Bug 656736 - Support upgrading to the latest version of MozMill. r=Standard8

This patch adds mozmill 1.5.4b4, mozrunner 2.5.5b4 and jsbridge 2.4.4b4 to the
tree. It also sets up a virtualenv to install mozmill and its dependencies
in. This patch means Thunderbird developers will no longer need to have MozMill
or its dependencies installed in order to run MozMill tests.
This commit is contained in:
Siddharth Agarwal 2011-08-16 00:35:27 +05:30
Родитель c8302b5c92
Коммит 4baf05cb9e
261 изменённых файлов: 39510 добавлений и 183 удалений

Просмотреть файл

@ -81,6 +81,7 @@ AC_SUBST(COMM_BUILD)
dnl export this, so the var is set for mozilla/configure
MOZCONFIG=`$_AUTOCONF_TOOLS_DIR/mozconfig-find $topsrcdir`
export MOZCONFIG
echo "MOZCONFIG = $MOZCONFIG"
MOZ_DEB_TIMESTAMP=`date +"%a, %d %b %Y %T %z" 2>&1`
AC_SUBST(MOZ_DEB_TIMESTAMP)

Просмотреть файл

@ -75,9 +75,22 @@ libs:: $(_HARNESS_FILES)
# Copy the mailnews and mail resources that we require.
libs::
$(INSTALL) $(topsrcdir)/mailnews/test/resources/* $(MOZDEPTH)/_tests/mozmill/resources
$(INSTALL) $(topsrcdir)/mailnews/test/fakeserver/* $(MOZDEPTH)/_tests/mozmill/resources
$(INSTALL) $(topsrcdir)/mail/base/test/unit/resources/* $(MOZDEPTH)/_tests/mozmill/resources
$(INSTALL) $(topsrcdir)/mailnews/test/resources/* $(_DEST_DIR)/resources
$(INSTALL) $(topsrcdir)/mailnews/test/fakeserver/* $(_DEST_DIR)/resources
$(INSTALL) $(topsrcdir)/mail/base/test/unit/resources/* $(_DEST_DIR)/resources
# Copy MozMill and its dependencies over, and set up a virtualenv. The
# virtualenv directory is outside because we don't want to bundle it up during
# stage-package.
VIRTUALENV_DIR = $(_DEST_DIR)/../mozmill-virtualenv
mozmill-virtualenv: NSDISTMODE=copy
mozmill-virtualenv:
$(DIR_INSTALL) $(topsrcdir)/mail/test/resources $(_DEST_DIR)
rm -rf $(VIRTUALENV_DIR) && \
mkdir $(VIRTUALENV_DIR) && \
$(PYTHON) $(_DEST_DIR)/resources/installmozmill.py $(VIRTUALENV_DIR)
libs:: mozmill-virtualenv
PKG_STAGE = $(DIST)/test-package-stage

Просмотреть файл

@ -482,3 +482,8 @@ function test_tag_keys_disabled_in_content_tab() {
mc.keypress(null, "1", {});
check_tag_in_message(curMessage, tagArray[0], false);
}
function teardownModule() {
// Make sure archiving is enabled at the end
enable_archiving(true);
}

Просмотреть файл

@ -49,6 +49,7 @@ var elib = {};
Cu.import('resource://mozmill/modules/elementslib.js', elib);
var folder;
var gInterestingMessage;
function setupModule(module) {
let fdh = collector.getModule('folder-display-helpers');
@ -62,20 +63,20 @@ function setupModule(module) {
// create a message that has the interesting headers that commonly
// show up in the message header pane for testing
let msg = create_message({cc: msgGen.makeNamesAndAddresses(20), // YYY
subject: "This is a really, really, really, really, really, really, really, really, long subject.",
clobberHeaders: {
"Newsgroups": "alt.test",
"Reply-To": "J. Doe <j.doe@momo.invalid>",
"Content-Base": "http://example.com/",
"Bcc": "Richard Roe <richard.roe@momo.invalid>"
}});
gInterestingMessage = create_message({cc: msgGen.makeNamesAndAddresses(20), // YYY
subject: "This is a really, really, really, really, really, really, really, really, long subject.",
clobberHeaders: {
"Newsgroups": "alt.test",
"Reply-To": "J. Doe <j.doe@momo.invalid>",
"Content-Base": "http://example.com/",
"Bcc": "Richard Roe <richard.roe@momo.invalid>"
}});
add_message_to_folder(folder, msg);
add_message_to_folder(folder, gInterestingMessage);
// create a message that has boring headers to be able to switch to and
// back from, to force the more button to collapse again.
msg = create_message();
let msg = create_message();
add_message_to_folder(folder, msg);
}
@ -132,151 +133,6 @@ function test_add_tag_with_really_long_label() {
mc.keypress(mc.eid("expandedHeadersNameColumn"), "1", {});
}
/**
* @param headerName used for pretty-printing in exceptions
* @param headerValueElement code to be eval()ed returning the DOM element
* with the data.
* @param expectedName code to be eval()ed returning the expected value of
* nsIAccessible.name for the DOM element in question
* @param expectedRole the expected value for nsIAccessible.role
*/
let headersToTest = [
{
headerName: "Subject",
headerValueElement: "mc.a('expandedsubjectBox', {class: 'headerValue'})",
expectedName: "mc.e('expandedsubjectLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.textContent",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "Content-Base",
headerValueElement: "mc.a('expandedcontent-baseBox', {class: 'headerValue text-link headerValueUrl'})",
expectedName: "mc.e('expandedcontent-baseLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.textContent",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "From",
headerValueElement: "mc.window.document.getAnonymousElementByAttribute(" +
"mc.a('expandedfromBox', {tagName: 'mail-emailaddress'})," +
"'class', 'emailDisplayButton')",
expectedName: "mc.e('expandedfromLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.parentNode.getAttribute('fullAddress')",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "To",
headerValueElement: "mc.window.document.getAnonymousElementByAttribute(" +
"mc.a('expandedtoBox', {tagName: 'mail-emailaddress'})," +
"'class', 'emailDisplayButton')",
expectedName: "mc.e('expandedtoLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.parentNode.getAttribute('fullAddress')",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "Cc",
headerValueElement: "mc.window.document.getAnonymousElementByAttribute(" +
"mc.a('expandedccBox', {tagName: 'mail-emailaddress'})," +
"'class', 'emailDisplayButton')",
expectedName: "mc.e('expandedccLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.parentNode.getAttribute('fullAddress')",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "Bcc",
headerValueElement: "mc.window.document.getAnonymousElementByAttribute(" +
"mc.a('expandedbccBox', {tagName: 'mail-emailaddress'})," +
"'class', 'emailDisplayButton')",
expectedName: "mc.e('expandedbccLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.parentNode.getAttribute('fullAddress')",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "Reply-To",
headerValueElement: "mc.window.document.getAnonymousElementByAttribute(" +
"mc.a('expandedreply-toBox', {tagName: 'mail-emailaddress'})," +
"'class', 'emailDisplayButton')",
expectedName: "mc.e('expandedreply-toLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.parentNode.getAttribute('fullAddress')",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "Newsgroups",
headerValueElement: "mc.window.document.getAnonymousElementByAttribute(" +
"mc.a('expandednewsgroupsBox', {tagName: 'mail-newsgroup'})," +
"'class', 'newsgrouplabel')",
expectedName: "mc.e('expandednewsgroupsLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.parentNode.parentNode.getAttribute('newsgroup')",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "Tags",
headerValueElement: "mc.a('expandedtagsBox', {class: 'tagvalue blc-FF0000'})",
expectedName: "mc.e('expandedtagsLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.getAttribute('value')",
expectedRole: Ci.nsIAccessibleRole.ROLE_LABEL
}
];
// used to get the accessible object for a DOM node
let gAccRetrieval = Cc["@mozilla.org/accessibleRetrieval;1"].
getService(Ci.nsIAccessibleRetrieval);
/**
* Use the information from aHeaderInfo to verify that screenreaders will
* do the right thing with the given message header.
*
* @param {Object} aHeaderInfo Information about how to do the verification;
* See the comments above the headersToTest array
* for details.
*/
function verify_header_a11y(aHeaderInfo) {
// XXX Don't use eval here.
let headerValueElement = eval(aHeaderInfo.headerValueElement);
let headerAccessible = gAccRetrieval.getAccessibleFor(headerValueElement);
if (headerAccessible.role != aHeaderInfo.expectedRole) {
throw new Error("role for " + aHeaderInfo.headerName + " was " +
headerAccessible.role + "; should have been " +
aHeaderInfo.expectedRole);
}
// XXX Don't use eval here.
let expectedName = eval(aHeaderInfo.expectedName);
if (headerAccessible.name != expectedName) {
throw new Error("headerAccessible.name for " + aHeaderInfo.headerName +
" was '" + headerAccessible.name + "'; expected '" +
expectedName + "'");
}
}
/**
* Test the accessibility attributes of the various message headers.
*
* XXX This test used to be after test_more_button_with_many_recipients,
* however, there were some accessibility changes that it didn't seem to play
* nicely with, and the toggling of the "more" button on the cc field was
* causing this test to fail on the cc element. Tests with accessibilty
* hardware/software showed that the code was working fine. Therefore the test
* may be suspect.
*/
function test_a11y_attrs() {
// skip this test on platforms that don't support accessibility
if (!("nsIAccessibleRole" in Components.interfaces))
return;
be_in_folder(folder);
// select and open the first message
let curMessage = select_click_row(0);
// make sure it loads
wait_for_message_display_completion(mc);
assert_selected_and_displayed(mc, curMessage);
headersToTest.forEach(verify_header_a11y);
}
function test_more_button_with_many_recipients()
{
// Start on the interesting message.
@ -882,3 +738,147 @@ function test_get_msg_button_customize_header_toolbar(){
}
}
// Some platforms (notably Mac) don't have a11y, so disable these tests there.
if ("nsIAccessibleRole" in Ci) {
/**
* @param headerName used for pretty-printing in exceptions
* @param headerValueElement code to be eval()ed returning the DOM element
* with the data.
* @param expectedName code to be eval()ed returning the expected value of
* nsIAccessible.name for the DOM element in question
* @param expectedRole the expected value for nsIAccessible.role
*/
let headersToTest = [
{
headerName: "Subject",
headerValueElement: "mc.a('expandedsubjectBox', {class: 'headerValue'})",
expectedName: "mc.e('expandedsubjectLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.textContent",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "Content-Base",
headerValueElement: "mc.a('expandedcontent-baseBox', {class: 'headerValue text-link headerValueUrl'})",
expectedName: "mc.e('expandedcontent-baseLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.textContent",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "From",
headerValueElement: "mc.window.document.getAnonymousElementByAttribute(" +
"mc.a('expandedfromBox', {tagName: 'mail-emailaddress'})," +
"'class', 'emailDisplayButton')",
expectedName: "mc.e('expandedfromLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.parentNode.getAttribute('fullAddress')",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "To",
headerValueElement: "mc.window.document.getAnonymousElementByAttribute(" +
"mc.a('expandedtoBox', {tagName: 'mail-emailaddress'})," +
"'class', 'emailDisplayButton')",
expectedName: "mc.e('expandedtoLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.parentNode.getAttribute('fullAddress')",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "Cc",
headerValueElement: "mc.window.document.getAnonymousElementByAttribute(" +
"mc.a('expandedccBox', {tagName: 'mail-emailaddress'})," +
"'class', 'emailDisplayButton')",
expectedName: "mc.e('expandedccLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.parentNode.getAttribute('fullAddress')",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "Bcc",
headerValueElement: "mc.window.document.getAnonymousElementByAttribute(" +
"mc.a('expandedbccBox', {tagName: 'mail-emailaddress'})," +
"'class', 'emailDisplayButton')",
expectedName: "mc.e('expandedbccLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.parentNode.getAttribute('fullAddress')",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "Reply-To",
headerValueElement: "mc.window.document.getAnonymousElementByAttribute(" +
"mc.a('expandedreply-toBox', {tagName: 'mail-emailaddress'})," +
"'class', 'emailDisplayButton')",
expectedName: "mc.e('expandedreply-toLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.parentNode.getAttribute('fullAddress')",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "Newsgroups",
headerValueElement: "mc.window.document.getAnonymousElementByAttribute(" +
"mc.a('expandednewsgroupsBox', {tagName: 'mail-newsgroup'})," +
"'class', 'newsgrouplabel')",
expectedName: "mc.e('expandednewsgroupsLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.parentNode.parentNode.getAttribute('newsgroup')",
expectedRole: Ci.nsIAccessibleRole.ROLE_ENTRY
},
{
headerName: "Tags",
headerValueElement: "mc.a('expandedtagsBox', {class: 'tagvalue blc-FF0000'})",
expectedName: "mc.e('expandedtagsLabel').value.slice(0,-1) + ': ' + " +
"headerValueElement.getAttribute('value')",
expectedRole: Ci.nsIAccessibleRole.ROLE_LABEL
}
];
// used to get the accessible object for a DOM node
let gAccRetrieval = Cc["@mozilla.org/accessibleRetrieval;1"].
getService(Ci.nsIAccessibleRetrieval);
/**
* Use the information from aHeaderInfo to verify that screenreaders will
* do the right thing with the given message header.
*
* @param {Object} aHeaderInfo Information about how to do the verification;
* See the comments above the headersToTest array
* for details.
*/
function verify_header_a11y(aHeaderInfo) {
// XXX Don't use eval here.
let headerValueElement = eval(aHeaderInfo.headerValueElement);
let headerAccessible = gAccRetrieval.getAccessibleFor(headerValueElement)
if (headerAccessible.role != aHeaderInfo.expectedRole) {
throw new Error("role for " + aHeaderInfo.headerName + " was " +
headerAccessible.role + "; should have been " +
aHeaderInfo.expectedRole);
}
// XXX Don't use eval here.
let expectedName = eval(aHeaderInfo.expectedName);
if (headerAccessible.name != expectedName) {
throw new Error("headerAccessible.name for " + aHeaderInfo.headerName +
" was '" + headerAccessible.name + "'; expected '" +
expectedName + "'");
}
}
/**
* Test the accessibility attributes of the various message headers.
*
* XXX This test used to be after test_more_button_with_many_recipients,
* however, there were some accessibility changes that it didn't seem to play
* nicely with, and the toggling of the "more" button on the cc field was
* causing this test to fail on the cc element. Tests with accessibilty
* hardware/software showed that the code was working fine. Therefore the test
* may be suspect.
*/
function test_a11y_attrs() {
be_in_folder(folder);
// select and open the interesting message
let curMessage = select_click_row(mc.dbView.findIndexOfMsgHdr(
gInterestingMessage, false));
// make sure it loads
assert_selected_and_displayed(mc, curMessage);
headersToTest.forEach(verify_header_a11y);
}
} // if ("nsIAccessibleRole" in Ci)

Просмотреть файл

@ -202,6 +202,9 @@ class ThunderTestProfile(mozrunner.ThunderbirdProfile):
if os.path.exists(PROFILE_DIR):
shutil.rmtree(PROFILE_DIR, onerror=rmtree_onerror)
os.makedirs(PROFILE_DIR)
print 'Using profile dir:', PROFILE_DIR
if not os.path.exists(PROFILE_DIR):
raise Exception('somehow failed to create profile dir!')
if wrapper is not None and hasattr(wrapper, "on_profile_created"):
# It's a little dangerous to allow on_profile_created access to the
@ -292,6 +295,30 @@ class ThunderTestRunner(mozrunner.ThunderbirdRunner):
print '!!! Exception during killing VNC server:', ex
def monkeypatched_15_run_tests(self, tests, sleeptime=0):
frame = mozmill.jsbridge.JSObject(self.bridge,
"Components.utils.import('resource://mozmill/modules/frame.js')")
sleep(sleeptime)
# transfer persisted data
frame.persisted = self.persisted
if len(tests) == 1 and not os.path.isdir(tests[0]):
# tests[0] isn't necessarily an abspath'd path, so do that now
test = os.path.abspath(tests[0])
frame.runTestFile(test)
else:
# run the test files
for test_dir in self.test_dirs:
frame.runTestDirectory(test_dir)
# Give a second for any callbacks to finish.
sleep(1)
if hasattr(mozmill.MozMill, 'find_tests'):
# Monkey-patch run_tests
mozmill.MozMill.old_run_tests = mozmill.MozMill.run_tests
mozmill.MozMill.run_tests = monkeypatched_15_run_tests
class ThunderTestCLI(mozmill.CLI):
profile_class = ThunderTestProfile
@ -302,31 +329,47 @@ class ThunderTestCLI(mozmill.CLI):
def __init__(self, *args, **kwargs):
global SYMBOLS_PATH, TEST_NAME
# invoke jsbridge.CLI's constructor directly since we are explicitly
# trying to replace mozmill's CLI constructor here (which hardcodes
# the firefox runner and profile in 1.3 for no clear reason).
jsbridge.CLI.__init__(self, *args, **kwargs)
# mozmill 1.5.4 still explicitly hardcodes references to Firefox; in
# order to avoid missing out on initializer logic or needing to copy
# it, we monkeypatch mozmill's view of mozrunner. (Keep in mind that
# the python module import process shallow copies dictionaries...)
mozmill.mozrunner.FirefoxRunner = self.runner_class
mozmill.mozrunner.FirefoxProfile = self.profile_class
# note: we previously hardcoded a JS bridge timeout of 300 seconds,
# but the default is now 60 seconds...
mozmill.CLI.__init__(self, *args, **kwargs)
SYMBOLS_PATH = self.options.symbols
TEST_NAME = os.path.basename(self.options.test)
if isinstance(self.options.test, basestring):
test_paths = [self.options.test]
else:
test_paths = self.options.test
TEST_NAME = ', '.join([os.path.basename(t) for t in test_paths])
test_dirs = self.test_dirs = []
for test_file in test_paths:
test_file = os.path.abspath(test_file)
if not os.path.isdir(test_file):
test_file = os.path.dirname(test_file)
if not test_file in test_dirs:
test_dirs.append(test_file)
# if we are monkeypatching, give it the test directories.
if hasattr(self.mozmill, 'find_tests'):
self.mozmill.test_dirs = test_dirs
self._load_wrapper()
self.mozmill = self.mozmill_class(runner_class=self.runner_class,
profile_class=self.profile_class,
jsbridge_port=int(self.options.port),
jsbridge_timeout=300)
self.mozmill.add_global_listener(mozmill.LoggerListener())
def _load_wrapper(self):
global wrapper
"""
Load the wrapper module if it is present in the test directory.
"""
if os.path.isdir(self.options.test):
testdir = self.options.test
else:
testdir = os.path.dirname(self.options.test)
if len(self.test_dirs) > 1:
raise Exception("Wrapper semantics require only a single test dir")
testdir = self.test_dirs[0]
try:
(fd, path, desc) = imp.find_module(WRAPPER_MODULE_NAME, [testdir])
@ -340,6 +383,7 @@ class ThunderTestCLI(mozmill.CLI):
if fd is not None:
fd.close()
TEST_RESULTS = []
# Versions of MozMill prior to 1.5 did not output test-pass /
# TEST-UNEXPECTED-FAIL. Since 1.5 happened this gets output, so we only want
@ -361,7 +405,15 @@ ORIGINAL_FAILURE_LOGGER = mozmill.LoggerListener.cases['mozmill.fail']
def logFailure(obj):
if isinstance(obj, basestring):
obj = json.loads(obj)
ORIGINAL_FAILURE_LOGGER(obj["exception"]["message"])
if 'exception' in obj:
objex = obj['exception']
if 'message' in objex:
report_as = objex['message']
else:
report_as = 'Empty object thrown as an exception somehow'
else:
report_as = 'No exception provided'
ORIGINAL_FAILURE_LOGGER(report_as)
mozmill.LoggerListener.cases['mozmill.fail'] = logFailure
@ -409,8 +461,12 @@ def prettyPrintResults():
if 'summary' in result:
testOrSummary = 'SUMMARY'
if len(result['fails']) == 0:
if result.get('skipped', False):
kind = 'SKIP'
else:
kind = 'PASS'
if result['name'] not in TEST_BLACKLIST:
print '%s-PASS | %s' % (testOrSummary, result['name'])
print '%s-%s | %s' % (testOrSummary, kind, result['name'])
else:
print '%s-UNEXPECTED-FAIL | %s | %s' % (testOrSummary, prettifyFilename(result['filename']), result['name'])
for failure in result['fails']:

Просмотреть файл

@ -103,7 +103,7 @@ for directory in f:
testDirectory = os.path.join(options.dir, directory.rstrip())
else:
testDirectory = directory.rstrip()
args = ["python", "runtest.py", "-t", testDirectory,
args = [sys.executable, "runtest.py", "-t", testDirectory,
"--binary", options.binary, "--symbols-path", options.symbols]
print args
outputPipe = subprocess.PIPE

Просмотреть файл

@ -197,11 +197,27 @@ function setupModule() {
// can mutate it. (The jsbridge is a global listener and so is guaranteed
// to be invoked after our specific named listener.)
frame.events.addListener("fail", function(obj) {
// normalize nsIExceptions so they look like JS exceptions...
rawex = obj.exception;
if (obj.exception != null &&
(obj.exception instanceof Ci.nsIException)) {
obj.exception = {
message: "nsIException: " + rawex.message + " (" + rawex.result + ")",
fileName: rawex.filename,
lineNumber: rawex.lineNumber,
name: rawex.name,
result: rawex.result,
stack: "",
};
}
// generate the failure notification now so it shows up in the event log
// bucket for presentation purposes.
testHelperModule._xpcshellLogger.info(
testHelperModule._testLoggerActiveContext,
new testHelperModule._Failure(obj.exception.message, obj.exception));
new testHelperModule._Failure(
obj.exception ? obj.exception.message : "No Exception!",
rawex));
try {
obj.failureContext = {

Просмотреть файл

@ -129,8 +129,8 @@ function get_subpage(fc) {
// broken:
// Lie to mozmill to convince it to not explode because these frames never
// get a documentLoaded attribute.
contentWindow.documentLoaded = true;
// get a mozmillDocumentLoaded attribute.
contentWindow.mozmillDocumentLoaded = true;
// And sleep so the page has a chance to load
controller.sleep(1000);
let aController = new controller.MozMillController(contentWindow);

Просмотреть файл

@ -0,0 +1,189 @@
Metadata-Version: 1.0
Name: ManifestDestiny
Version: 0.2.2
Summary: universal reader for manifests
Home-page: https://wiki.mozilla.org/Auto-tools/Projects/ManifestDestiny
Author: Jeff Hammel
Author-email: jhammel@mozilla.com
License: MPL
Description: ManifestDestiny
===============
Universal manifests for Mozilla test harnesses
What is ManifestDestiny?
------------------------
What ManifestDestiny gives you is:
* manifests are (ordered) lists of tests
* tests may have an arbitrary number of key, value pairs
* the parser returns an ordered list of test data structures, which
are just dicts with some keys. For example, a test with no
user-specified metadata looks like this::
[{'path':
'/home/jhammel/mozmill/src/ManifestDestiny/manifestdestiny/tests/testToolbar/testBackForwardButtons.js',
'name': 'testToolbar/testBackForwardButtons.js', 'here':
'/home/jhammel/mozmill/src/ManifestDestiny/manifestdestiny/tests',
'manifest': '/home/jhammel/mozmill/src/ManifestDestiny/manifestdestiny/tests',}]
The keys displayed here (path, name, here, and manifest) are reserved
words for ManifestDestiny and any consuming APIs.
Manifest Format
---------------
Manifests are .ini file with the section names denoting the path
relative to the manifest::
[foo.js]
[bar.js]
[fleem.js]
The sections are read in order. In addition, tests may include
arbitrary key, value metadata to be used by the harness. You can also
have a ``[DEFAULT]`` section that will give key, value pairs that will
be inherited by each test unless overridden::
[DEFAULT]
type = restart
[lilies.js]
color = white
[daffodils.js]
color = yellow
type = other
# override type from DEFAULT
[roses.js]
color = red
You can also include other manifests::
[include:subdir/anothermanifest.ini]
Data
----
Manifest Destiny gives tests as a list of dictionary (in python
terms).
* path: full path to the test
* name: short name of the test; this is the (usually) relative path
specified in the section name
* here: the parent directory of the manifest
* manifest: the path to the manifest containing the test
This data corresponds to a one-line manifest::
[testToolbar/testBackForwardButtons.js]
If additional key, values were specified, they would be in this dict
as well.
Outside of the reserved keys, the remaining key, values
are up to convention to use. There is a (currently very minimal)
generic integration layer in ManifestDestiny for use of all tests.
For instance, if the 'disabled' key is present, you can get the set of
tests without disabled (various other queries are doable as well).
Since the system is convention-based, the harnesses may do whatever
they want with the data. They may ignore it completely, they may use
the provided integration layer, or they may provide their own
integration layer. This should allow whatever sort of logic they
want. For instance, if in yourtestharness you wanted to run only on
mondays for a certain class of tests::
tests = []
for test in manifests.tests:
if 'runOnDay' in test:
if calendar.day_name[calendar.weekday(*datetime.datetime.now().timetuple()[:3])].lower() == test['runOnDay'].lower():
tests.append(test)
else:
tests.append(test)
To recap:
* the manifests allow you to specify test data
* the parser gives you this data
* you can use it however you want or process it further as you need
Tests are denoted by sections in an .ini file (see
http://hg.mozilla.org/automation/ManifestDestiny/file/tip/manifestdestiny/tests/mozmill-example.ini).
Additional manifest files may be included with a [include:] directive::
[include:path-to-additional-file.manifest]
The path to included files is relative to the current manifest.
The ``[DEFAULT]`` section contains variables that all tests inherit from.
Included files will inherit the top-level variables but may override
in their own ``[DEFAULT]`` section.
Creating Manifests
------------------
ManifestDestiny comes with a console script, ``manifestparser create``, that
may be used to create a seed manifest structure from a directory of
files. Run ``manifestparser help create`` for usage information.
Copying Manifests
-----------------
To copy tests and manifests from a source::
manifestparser [options] copy from_manifest to_directory -tag1 -tag2 --key1=value1 key2=value2 ...
Upating Tests
-------------
To update the tests associated with with a manifest from a source
directory::
manifestparser [options] update manifest from_directory -tag1 -tag2 --key1=value1 --key2=value2 ...
Tests
-----
ManifestDestiny includes a suite of tests:
http://hg.mozilla.org/automation/ManifestDestiny/file/tip/manifestdestiny/tests
``test_manifest.txt`` is a doctest that may be helpful in figuring out
how to use the API. Tests are run via ``python test.py``.
CLI
---
Run ``manifestparser help`` for usage information.
To create a manifest from a set of directories::
manifestparser [options] create directory <directory> <...> [create-options]
To output a manifest of tests::
manifestparser [options] write manifest <manifest> <...> -tag1 -tag2 --key1=value1 --key2=value2 ...
To copy tests and manifests from a source::
manifestparser [options] copy from_manifest to_manifest -tag1 -tag2 --key1=value1 key2=value2 ...
To update the tests associated with with a manifest from a source
directory::
manifestparser [options] update manifest from_directory -tag1 -tag2 --key1=value1 --key2=value2 ...
Keywords: mozilla manifests
Platform: UNKNOWN

Просмотреть файл

@ -0,0 +1,178 @@
ManifestDestiny
===============
Universal manifests for Mozilla test harnesses
What is ManifestDestiny?
------------------------
What ManifestDestiny gives you is:
* manifests are (ordered) lists of tests
* tests may have an arbitrary number of key, value pairs
* the parser returns an ordered list of test data structures, which
are just dicts with some keys. For example, a test with no
user-specified metadata looks like this::
[{'path':
'/home/jhammel/mozmill/src/ManifestDestiny/manifestdestiny/tests/testToolbar/testBackForwardButtons.js',
'name': 'testToolbar/testBackForwardButtons.js', 'here':
'/home/jhammel/mozmill/src/ManifestDestiny/manifestdestiny/tests',
'manifest': '/home/jhammel/mozmill/src/ManifestDestiny/manifestdestiny/tests',}]
The keys displayed here (path, name, here, and manifest) are reserved
words for ManifestDestiny and any consuming APIs.
Manifest Format
---------------
Manifests are .ini file with the section names denoting the path
relative to the manifest::
[foo.js]
[bar.js]
[fleem.js]
The sections are read in order. In addition, tests may include
arbitrary key, value metadata to be used by the harness. You can also
have a ``[DEFAULT]`` section that will give key, value pairs that will
be inherited by each test unless overridden::
[DEFAULT]
type = restart
[lilies.js]
color = white
[daffodils.js]
color = yellow
type = other
# override type from DEFAULT
[roses.js]
color = red
You can also include other manifests::
[include:subdir/anothermanifest.ini]
Data
----
Manifest Destiny gives tests as a list of dictionary (in python
terms).
* path: full path to the test
* name: short name of the test; this is the (usually) relative path
specified in the section name
* here: the parent directory of the manifest
* manifest: the path to the manifest containing the test
This data corresponds to a one-line manifest::
[testToolbar/testBackForwardButtons.js]
If additional key, values were specified, they would be in this dict
as well.
Outside of the reserved keys, the remaining key, values
are up to convention to use. There is a (currently very minimal)
generic integration layer in ManifestDestiny for use of all tests.
For instance, if the 'disabled' key is present, you can get the set of
tests without disabled (various other queries are doable as well).
Since the system is convention-based, the harnesses may do whatever
they want with the data. They may ignore it completely, they may use
the provided integration layer, or they may provide their own
integration layer. This should allow whatever sort of logic they
want. For instance, if in yourtestharness you wanted to run only on
mondays for a certain class of tests::
tests = []
for test in manifests.tests:
if 'runOnDay' in test:
if calendar.day_name[calendar.weekday(*datetime.datetime.now().timetuple()[:3])].lower() == test['runOnDay'].lower():
tests.append(test)
else:
tests.append(test)
To recap:
* the manifests allow you to specify test data
* the parser gives you this data
* you can use it however you want or process it further as you need
Tests are denoted by sections in an .ini file (see
http://hg.mozilla.org/automation/ManifestDestiny/file/tip/manifestdestiny/tests/mozmill-example.ini).
Additional manifest files may be included with a [include:] directive::
[include:path-to-additional-file.manifest]
The path to included files is relative to the current manifest.
The ``[DEFAULT]`` section contains variables that all tests inherit from.
Included files will inherit the top-level variables but may override
in their own ``[DEFAULT]`` section.
Creating Manifests
------------------
ManifestDestiny comes with a console script, ``manifestparser create``, that
may be used to create a seed manifest structure from a directory of
files. Run ``manifestparser help create`` for usage information.
Copying Manifests
-----------------
To copy tests and manifests from a source::
manifestparser [options] copy from_manifest to_directory -tag1 -tag2 --key1=value1 key2=value2 ...
Upating Tests
-------------
To update the tests associated with with a manifest from a source
directory::
manifestparser [options] update manifest from_directory -tag1 -tag2 --key1=value1 --key2=value2 ...
Tests
-----
ManifestDestiny includes a suite of tests:
http://hg.mozilla.org/automation/ManifestDestiny/file/tip/manifestdestiny/tests
``test_manifest.txt`` is a doctest that may be helpful in figuring out
how to use the API. Tests are run via ``python test.py``.
CLI
---
Run ``manifestparser help`` for usage information.
To create a manifest from a set of directories::
manifestparser [options] create directory <directory> <...> [create-options]
To output a manifest of tests::
manifestparser [options] write manifest <manifest> <...> -tag1 -tag2 --key1=value1 --key2=value2 ...
To copy tests and manifests from a source::
manifestparser [options] copy from_manifest to_manifest -tag1 -tag2 --key1=value1 key2=value2 ...
To update the tests associated with with a manifest from a source
directory::
manifestparser [options] update manifest from_directory -tag1 -tag2 --key1=value1 --key2=value2 ...

Просмотреть файл

@ -0,0 +1,776 @@
#!/usr/bin/env python
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Mozilla.org.
# Portions created by the Initial Developer are Copyright (C) 2010
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Jeff Hammel <jhammel@mozilla.com> (Original author)
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
"""
Mozilla universal manifest parser
"""
# this file lives at
# http://hg.mozilla.org/automation/ManifestDestiny/raw-file/tip/manifestparser.py
__all__ = ['ManifestParser', 'TestManifest', 'convert']
import os
import shutil
import sys
from fnmatch import fnmatch
from optparse import OptionParser
version = '0.2.2' # package version
try:
from setuptools import setup
except ImportError:
setup = None
def read_ini(fp, variables=None, default='DEFAULT',
comments=';#', separators=('=', ':'),
strict=True):
"""
read an .ini file and return a list of [(section, values)]
- fp : file pointer or path to read
- variables : default set of variables
- default : name of the section for the default section
- comments : characters that if they start a line denote a comment
- separators : strings that denote key, value separation in order
- strict : whether to be strict about parsing
"""
if variables is None:
variables = {}
if isinstance(fp, basestring):
fp = file(fp)
sections = []
key = value = None
section_names = set([])
# read the lines
for line in fp.readlines():
stripped = line.strip()
# ignore blank lines
if not stripped:
# reset key and value to avoid continuation lines
key = value = None
continue
# ignore comment lines
if stripped[0] in comments:
continue
# check for a new section
if len(stripped) > 2 and stripped[0] == '[' and stripped[-1] == ']':
section = stripped[1:-1].strip()
key = value = None
# deal with DEFAULT section
if section.lower() == default.lower():
if strict:
assert default not in section_names
section_names.add(default)
current_section = variables
continue
if strict:
# make sure this section doesn't already exist
assert section not in section_names
section_names.add(section)
current_section = {}
sections.append((section, current_section))
continue
# if there aren't any sections yet, something bad happen
if not section_names:
raise Exception('No sections yet :(')
# (key, value) pair
for separator in separators:
if separator in stripped:
key, value = stripped.split(separator, 1)
key = key.strip()
value = value.strip()
if strict:
# make sure this key isn't already in the section or empty
assert key
if current_section is not variables:
assert key not in current_section
current_section[key] = value
break
else:
# continuation line ?
if line[0].isspace() and key:
value = '%s%s%s' % (value, os.linesep, stripped)
current_section[key] = value
else:
# something bad happen!
raise Exception("Not sure what you're trying to do")
# interpret the variables
def interpret_variables(global_dict, local_dict):
variables = global_dict.copy()
variables.update(local_dict)
return variables
sections = [(i, interpret_variables(variables, j)) for i, j in sections]
return sections
### objects for parsing manifests
class ManifestParser(object):
"""read .ini manifests"""
### methods for reading manifests
def __init__(self, manifests=(), defaults=None, strict=True):
self._defaults = defaults or {}
self.tests = []
self.strict = strict
self.rootdir = None
if manifests:
self.read(*manifests)
def read(self, *filenames, **defaults):
# ensure all files exist
missing = [ filename for filename in filenames
if not os.path.exists(filename) ]
if missing:
raise IOError('Missing files: %s' % ', '.join(missing))
# process each file
for filename in filenames:
# set the per file defaults
defaults = defaults.copy() or self._defaults.copy()
here = os.path.dirname(os.path.abspath(filename))
defaults['here'] = here
if self.rootdir is None:
# set the root directory
# == the directory of the first manifest given
self.rootdir = here
# read the configuration
sections = read_ini(filename, variables=defaults)
# get the tests
for section, data in sections:
# a file to include
# TODO: keep track of structure:
# self.manifests = {'manifest.ini': 'relative/path.ini'}
if section.startswith('include:'):
include_file = section.split('include:', 1)[-1]
include_file = os.path.join(here, include_file)
if not os.path.exists(include_file):
if strict:
raise IOError("File '%s' does not exist" % include_file)
else:
continue
include_defaults = data.copy()
self.read(include_file, **include_defaults)
continue
# otherwise a test
test = data
test['name'] = section
test['path'] = os.path.join(here, section)
test['manifest'] = os.path.abspath(filename)
self.tests.append(test)
### methods for querying manifests
def query(self, *checks):
"""
general query function for tests
- checks : callable conditions to test if the test fulfills the query
"""
retval = []
for test in self.tests:
for check in checks:
if not check(test):
break
else:
retval.append(test)
return retval
def get(self, _key=None, inverse=False, tags=None, **kwargs):
# TODO: pass a dict instead of kwargs since you might hav
# e.g. 'inverse' as a key in the dict
# TODO: tags should just be part of kwargs with None values
# (None == any is kinda weird, but probably still better)
# fix up tags
if tags:
tags = set(tags)
else:
tags = set()
# make some check functions
if inverse:
has_tags = lambda test: tags.isdisjoint(test.keys())
def dict_query(test):
for key, value in kwargs.items():
if test.get(key) == value:
return False
return True
else:
has_tags = lambda test: tags.issubset(test.keys())
def dict_query(test):
for key, value in kwargs.items():
if test.get(key) != value:
return False
return True
# query the tests
tests = self.query(has_tags, dict_query)
# if a key is given, return only a list of that key
# useful for keys like 'name' or 'path'
if _key:
return [test[_key] for test in tests]
# return the tests
return tests
def missing(self, tests=None):
"""return list of tests that do not exist on the filesystem"""
if tests is None:
tests = self.tests
return [test for test in tests
if not os.path.exists(test['path'])]
def manifests(self, tests=None):
"""
return manifests in order in which they appear in the tests
"""
if tests is None:
tests = self.tests
manifests = []
for test in tests:
manifest = test.get('manifest')
if not manifest:
continue
if manifest not in manifests:
manifests.append(manifest)
return manifests
### methods for outputting from manifests
def write(self, fp=sys.stdout, rootdir=None,
global_tags=None, global_kwargs=None,
local_tags=None, local_kwargs=None):
"""
write a manifest given a query
global and local options will be munged to do the query
globals will be written to the top of the file
locals (if given) will be written per test
"""
# root directory
if rootdir is None:
rootdir = self.rootdir
# sanitize input
global_tags = global_tags or set()
local_tags = local_tags or set()
global_kwargs = global_kwargs or {}
local_kwargs = local_kwargs or {}
# create the query
tags = set([])
tags.update(global_tags)
tags.update(local_tags)
kwargs = {}
kwargs.update(global_kwargs)
kwargs.update(local_kwargs)
# get matching tests
tests = self.get(tags=tags, **kwargs)
# print the .ini manifest
if global_tags or global_kwargs:
print >> fp, '[DEFAULT]'
for tag in global_tags:
print >> fp, '%s =' % tag
for key, value in global_kwargs.items():
print >> fp, '%s = %s' % (key, value)
print >> fp
for test in tests:
test = test.copy() # don't overwrite
path = test['name']
if not os.path.isabs(path):
path = os.path.relpath(test['path'], self.rootdir)
print >> fp, '[%s]' % path
# reserved keywords:
reserved = ['path', 'name', 'here', 'manifest']
for key in sorted(test.keys()):
if key in reserved:
continue
if key in global_kwargs:
continue
if key in global_tags and not test[key]:
continue
print >> fp, '%s = %s' % (key, test[key])
print >> fp
def copy(self, directory, rootdir=None, *tags, **kwargs):
"""
copy the manifests and associated tests
- directory : directory to copy to
- rootdir : root directory to copy to (if not given from manifests)
- tags : keywords the tests must have
- kwargs : key, values the tests must match
"""
# XXX note that copy does *not* filter the tests out of the
# resulting manifest; it just stupidly copies them over.
# ideally, it would reread the manifests and filter out the
# tests that don't match *tags and **kwargs
# destination
if not os.path.exists(directory):
os.path.makedirs(directory)
else:
# sanity check
assert os.path.isdir(directory)
# tests to copy
tests = self.get(tags=tags, **kwargs)
if not tests:
return # nothing to do!
# root directory
if rootdir is None:
rootdir = self.rootdir
# copy the manifests + tests
manifests = [os.path.relpath(manifest, rootdir) for manifest in self.manifests()]
for manifest in manifests:
destination = os.path.join(directory, manifest)
dirname = os.path.dirname(destination)
if not os.path.exists(dirname):
os.makedirs(dirname)
else:
# sanity check
assert os.path.isdir(dirname)
shutil.copy(os.path.join(rootdir, manifest), destination)
for test in tests:
if os.path.isabs(test['name']):
continue
source = test['path']
if not os.path.exists(source):
print >> sys.stderr, "Missing test: '%s' does not exist!" % source
continue
# TODO: should err on strict
destination = os.path.join(directory, os.path.relpath(test['path'], rootdir))
shutil.copy(source, destination)
# TODO: ensure that all of the tests are below the from_dir
def update(self, from_dir, rootdir=None, *tags, **kwargs):
"""
update the tests as listed in a manifest from a directory
- from_dir : directory where the tests live
- rootdir : root directory to copy to (if not given from manifests)
- tags : keys the tests must have
- kwargs : key, values the tests must match
"""
# get the tests
tests = self.get(tags=tags, **kwargs)
# get the root directory
if not rootdir:
rootdir = self.rootdir
# copy them!
for test in tests:
if not os.path.isabs(test['name']):
relpath = os.path.relpath(test['path'], rootdir)
source = os.path.join(from_dir, relpath)
if not os.path.exists(source):
# TODO err on strict
print >> sys.stderr, "Missing test: '%s'; skipping" % test['name']
continue
destination = os.path.join(rootdir, relpath)
shutil.copy(source, destination)
class TestManifest(ManifestParser):
"""
apply logic to manifests; this is your integration layer :)
specific harnesses may subclass from this if they need more logic
"""
def active_tests(self):
# ignore disabled tests
tests = self.get(inverse=True, tags=['disabled'])
# TODO: could filter out by current platform, existence, etc
return tests
def test_paths(self):
return [test['path'] for test in self.active_tests()]
### utility function(s); probably belongs elsewhere
def convert(directories, pattern=None, ignore=(), write=None):
"""
convert directories to a simple manifest
"""
retval = []
include = []
for directory in directories:
for dirpath, dirnames, filenames in os.walk(directory):
# filter out directory names
dirnames = [ i for i in dirnames if i not in ignore ]
dirnames.sort()
# reference only the subdirectory
_dirpath = dirpath
dirpath = dirpath.split(directory, 1)[-1].strip('/')
if dirpath.split(os.path.sep)[0] in ignore:
continue
# filter by glob
if pattern:
filenames = [filename for filename in filenames
if fnmatch(filename, pattern)]
filenames.sort()
# write a manifest for each directory
if write and (dirnames or filenames):
manifest = file(os.path.join(_dirpath, write), 'w')
for dirname in dirnames:
print >> manifest, '[include:%s]' % os.path.join(dirname, write)
for filename in filenames:
print >> manifest, '[%s]' % filename
manifest.close()
# add to the list
retval.extend([os.path.join(dirpath, filename)
for filename in filenames])
if write:
return # the manifests have already been written!
retval.sort()
retval = ['[%s]' % filename for filename in retval]
return '\n'.join(retval)
### command line attributes
class ParserError(Exception):
"""error for exceptions while parsing the command line"""
def parse_args(_args):
"""
parse and return:
--keys=value (or --key value)
-tags
args
"""
# return values
_dict = {}
tags = []
args = []
# parse the arguments
key = None
for arg in _args:
if arg.startswith('---'):
raise ParserError("arguments should start with '-' or '--' only")
elif arg.startswith('--'):
if key:
raise ParserError("Key %s still open" % key)
key = arg[2:]
if '=' in key:
key, value = key.split('=', 1)
_dict[key] = value
key = None
continue
elif arg.startswith('-'):
if key:
raise ParserError("Key %s still open" % key)
tags.append(arg[1:])
continue
else:
if key:
_dict[key] = arg
continue
args.append(arg)
# return values
return (_dict, tags, args)
### classes for subcommands
class CLICommand(object):
usage = '%prog [options] command'
def __init__(self, parser):
self._parser = parser # master parser
def parser(self):
return OptionParser(usage=self.usage, description=self.__doc__,
add_help_option=False)
class Copy(CLICommand):
usage = '%prog [options] copy manifest directory -tag1 -tag2 --key1=value1 --key2=value2 ...'
def __call__(self, options, args):
# parse the arguments
try:
kwargs, tags, args = parse_args(args)
except ParserError, e:
self._parser.error(e.message)
# make sure we have some manifests, otherwise it will
# be quite boring
if not len(args) == 2:
HelpCLI(self._parser)(options, ['copy'])
return
# read the manifests
# TODO: should probably ensure these exist here
manifests = ManifestParser()
manifests.read(args[0])
# print the resultant query
manifests.copy(args[1], None, *tags, **kwargs)
class CreateCLI(CLICommand):
"""
create a manifest from a list of directories
"""
usage = '%prog [options] create directory <directory> <...>'
def parser(self):
parser = CLICommand.parser(self)
parser.add_option('-p', '--pattern', dest='pattern',
help="glob pattern for files")
parser.add_option('-i', '--ignore', dest='ignore',
default=[], action='append',
help='directories to ignore')
parser.add_option('-w', '--in-place', dest='in_place',
help='Write .ini files in place; filename to write to')
return parser
def __call__(self, _options, args):
parser = self.parser()
options, args = parser.parse_args(args)
# need some directories
if not len(args):
parser.print_usage()
return
# add the directories to the manifest
for arg in args:
assert os.path.exists(arg)
assert os.path.isdir(arg)
manifest = convert(args, pattern=options.pattern, ignore=options.ignore,
write=options.in_place)
if manifest:
print manifest
class WriteCLI(CLICommand):
"""
write a manifest based on a query
"""
usage = '%prog [options] write manifest <manifest> -tag1 -tag2 --key1=value1 --key2=value2 ...'
def __call__(self, options, args):
# parse the arguments
try:
kwargs, tags, args = parse_args(args)
except ParserError, e:
self._parser.error(e.message)
# make sure we have some manifests, otherwise it will
# be quite boring
if not args:
HelpCLI(self._parser)(options, ['write'])
return
# read the manifests
# TODO: should probably ensure these exist here
manifests = ManifestParser()
manifests.read(*args)
# print the resultant query
manifests.write(global_tags=tags, global_kwargs=kwargs)
class HelpCLI(CLICommand):
"""
get help on a command
"""
usage = '%prog [options] help [command]'
def __call__(self, options, args):
if len(args) == 1 and args[0] in commands:
commands[args[0]](self._parser).parser().print_help()
else:
self._parser.print_help()
print '\nCommands:'
for command in sorted(commands):
print ' %s : %s' % (command, commands[command].__doc__.strip())
class SetupCLI(CLICommand):
"""
setup using setuptools
"""
usage = '%prog [options] setup [setuptools options]'
def __call__(self, options, args):
sys.argv = [sys.argv[0]] + args
assert setup is not None, "You must have setuptools installed to use SetupCLI"
here = os.path.dirname(os.path.abspath(__file__))
try:
filename = os.path.join(here, 'README.txt')
description = file(filename).read()
except:
description = ''
os.chdir(here)
setup(name='ManifestDestiny',
version=version,
description="universal reader for manifests",
long_description=description,
classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
keywords='mozilla manifests',
author='Jeff Hammel',
author_email='jhammel@mozilla.com',
url='https://wiki.mozilla.org/Auto-tools/Projects/ManifestDestiny',
license='MPL',
zip_safe=False,
py_modules=['manifestparser'],
install_requires=[
# -*- Extra requirements: -*-
],
entry_points="""
[console_scripts]
manifestparser = manifestparser:main
""",
)
class UpdateCLI(CLICommand):
"""
update the tests as listed in a manifest from a directory
"""
usage = '%prog [options] update manifest directory -tag1 -tag2 --key1=value1 --key2=value2 ...'
def __call__(self, options, args):
# parse the arguments
try:
kwargs, tags, args = parse_args(args)
except ParserError, e:
self._parser.error(e.message)
# make sure we have some manifests, otherwise it will
# be quite boring
if not len(args) == 2:
HelpCLI(self._parser)(options, ['update'])
return
# read the manifests
# TODO: should probably ensure these exist here
manifests = ManifestParser()
manifests.read(args[0])
# print the resultant query
manifests.update(args[1], None, *tags, **kwargs)
# command -> class mapping
commands = { 'create': CreateCLI,
'help': HelpCLI,
'update': UpdateCLI,
'write': WriteCLI }
if setup is not None:
commands['setup'] = SetupCLI
def main(args=sys.argv[1:]):
"""console_script entry point"""
# set up an option parser
usage = '%prog [options] [command] ...'
description = __doc__
parser = OptionParser(usage=usage, description=description)
parser.add_option('-s', '--strict', dest='strict',
action='store_true', default=False,
help='adhere strictly to errors')
parser.disable_interspersed_args()
options, args = parser.parse_args(args)
if not args:
HelpCLI(parser)(options, args)
parser.exit()
# get the command
command = args[0]
if command not in commands:
parser.error("Command must be one of %s (you gave '%s')" % (', '.join(sorted(commands.keys())), command))
handler = commands[command](parser)
handler(options, args[1:])
if __name__ == '__main__':
main()

Просмотреть файл

@ -0,0 +1,5 @@
[egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0

Просмотреть файл

@ -0,0 +1,48 @@
#!/usr/bin/env python
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Mozilla.org.
# Portions created by the Initial Developer are Copyright (C) 2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Jeff Hammel <jhammel@mozilla.com> (Original author)
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
# The real details are in manifestparser.py; this is just a front-end
import sys
from manifestparser import SetupCLI
SetupCLI(None)(None, sys.argv[1:])

Просмотреть файл

@ -0,0 +1,126 @@
#!/usr/bin/env python
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Mozilla.org.
# Portions created by the Initial Developer are Copyright (C) 2010
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Jeff Hammel <jhammel@mozilla.com> (Original author)
# Siddharth Agarwal <sid.bugzilla@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
"""
install mozmill and its dependencies
"""
import os
import sys
from subprocess import call
### utility functions for cross-platform
def is_windows():
return sys.platform.startswith('win')
def esc(path):
"""quote and escape a path for cross-platform use"""
return '"%s"' % repr(path)[1:-1]
def scripts_path(virtual_env):
"""path to scripts directory"""
if is_windows():
return os.path.join(virtual_env, 'Scripts')
return os.path.join(virtual_env, 'bin')
def python_script_path(virtual_env, script_name):
"""path to a python script in a virtualenv"""
scripts_dir = scripts_path(virtual_env)
if is_windows():
script_name = script_name + '-script.py'
return os.path.join(scripts_dir, script_name)
def entry_point_path(virtual_env, entry_point):
path = os.path.join(scripts_path(virtual_env), entry_point)
if is_windows():
path += '.exe'
return path
### command-line entry point
def main(args=None):
"""command line front-end function"""
# parse command line arguments
args = args or sys.argv[1:]
usage = "Usage: %prog [destination]"
# Print the python version
print 'Python: %s' % sys.version
# The data is kept in the same directory as the script
source=os.path.abspath(os.path.dirname(__file__))
# directory to install to
if not len(args):
destination = source
elif len(args) == 1:
destination = os.path.abspath(args[0])
else:
print "Usage: %s [destination]" % sys.argv[0]
sys.exit(1)
os.chdir(source)
# check for existence of necessary files
if not os.path.exists('virtualenv'):
print "File not found: virtualenv"
sys.exit(1)
# packages to install in dependency order
packages = ["ManifestDestiny", "simplejson-2.1.6", "mozrunner", "jsbridge",
"mozmill"]
# create the virtualenv and install packages
env = os.environ.copy()
env.pop('PYTHONHOME', None)
returncode = call([sys.executable, os.path.join('virtualenv', 'virtualenv.py'), destination], env=env)
if returncode:
print 'Failure to install virtualenv'
sys.exit(returncode)
pip = entry_point_path(destination, 'pip')
returncode = call([pip, 'install'] + [os.path.abspath(package) for package in packages], env=env)
if returncode:
print 'Failure to install packages'
sys.exit(returncode)
if __name__ == '__main__':
main()

Просмотреть файл

@ -0,0 +1,2 @@
recursive-include jsbridge/extension *
recursive-include jsbridge/xpi *

Просмотреть файл

@ -0,0 +1,181 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Corporation Code.
#
# The Initial Developer of the Original Code is
# Mikeal Rogers.
# Portions created by the Initial Developer are Copyright (C) 2008 -2009
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Mikeal Rogers <mikeal.rogers@gmail.com>
# Henrik Skupin <hskupin@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
import socket
import os
import copy
import asyncore
from time import sleep
from network import Bridge, BackChannel, create_network
from jsobjects import JSObject
import mozrunner
settings_env = 'JSBRIDGE_SETTINGS_FILE'
parent = os.path.abspath(os.path.dirname(__file__))
extension_path = os.path.join(parent, 'extension')
window_string = "Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('')"
wait_to_create_timeout = 60
def wait_and_create_network(host, port, timeout=wait_to_create_timeout):
ttl = 0
while ttl < timeout:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.close()
break
except socket.error:
pass
sleep(.25)
ttl += .25
if ttl == timeout:
raise Exception("Sorry, cannot connect to jsbridge extension, port %s" % port)
back_channel, bridge = create_network(host, port)
sleep(.5)
while back_channel.registered is False:
back_channel.close()
bridge.close()
asyncore.socket_map = {}
sleep(1)
back_channel, bridge = create_network(host, port)
return back_channel, bridge
class CLI(mozrunner.CLI):
"""Command line interface."""
module = "jsbridge"
parser_options = copy.copy(mozrunner.CLI.parser_options)
parser_options[('-D', '--debug',)] = dict(dest="debug",
action="store_true",
help="Debug mode",
metavar="JSBRIDGE_DEBUG",
default=False )
parser_options[('-s', '--shell',)] = dict(dest="shell",
action="store_true",
help="Start a Python shell",
metavar="JSBRIDGE_SHELL",
default=False )
parser_options[('-u', '--usecode',)] = dict(dest="usecode", action="store_true",
help="Use code module instead of iPython",
default=False)
parser_options[('-P', '--port')] = dict(dest="port", default="24242",
help="TCP port to run jsbridge on.")
def get_profile(self, *args, **kwargs):
if self.options.debug:
kwargs.setdefault('preferences', {}).update({
'extensions.checkCompatibility':False,
'devtools.errorconsole.enabled':True,
'javascript.options.strict': True
})
profile = mozrunner.CLI.get_profile(self, *args, **kwargs)
profile.install_addon(extension_path)
return profile
def get_runner(self, *args, **kwargs):
runner = super(CLI, self).get_runner(*args, **kwargs)
if self.options.debug:
runner.cmdargs.append('-jsconsole')
if not '-jsbridge' in runner.cmdargs:
runner.cmdargs += ['-jsbridge', self.options.port]
return runner
def run(self):
runner = self.create_runner()
runner.start()
self.start_jsbridge_network()
if self.options.shell:
self.start_shell(runner)
else:
try:
runner.wait()
except KeyboardInterrupt:
runner.stop()
runner.profile.cleanup()
def start_shell(self, runner):
try:
import IPython
except:
IPython = None
if not hasattr(self, 'bridge'):
self.start_jsbridge_network()
jsobj = JSObject(self.bridge, window_string)
if IPython is None or self.options.usecode:
import code
code.interact(local={"jsobj":jsobj,
"getBrowserWindow":lambda : getBrowserWindow(self.bridge),
"back_channel":self.back_channel,
})
else:
from IPython.Shell import IPShellEmbed
ipshell = IPShellEmbed([])
ipshell(local_ns={"jsobj":jsobj,
"getBrowserWindow":lambda : getBrowserWindow(self.bridge),
"back_channel":self.back_channel,
})
runner.stop()
def start_jsbridge_network(self, timeout=10):
port = int(self.options.port)
host = '127.0.0.1'
self.back_channel, self.bridge = wait_and_create_network(host, port, timeout)
def cli():
CLI().run()
def getBrowserWindow(bridge):
return JSObject(bridge, "Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('')")

Просмотреть файл

@ -0,0 +1,14 @@
resource jsbridge resource/
content jsbridge chrome/content/
overlay chrome://browser/content/browser.xul chrome://jsbridge/content/overlay.xul
overlay chrome://messenger/content/mailWindowOverlay.xul chrome://jsbridge/content/overlay.xul
overlay chrome://calendar/content/calendar.xul chrome://jsbridge/content/overlay.xul
overlay windowtype:Songbird:Main chrome://jsbridge/content/overlay.xul
component {2872d428-14f6-11de-ac86-001f5bd9235c} components/cmdarg.js
contract @mozilla.org/commandlinehandler/general-startup;1?type=jsbridge {2872d428-14f6-11de-ac86-001f5bd9235c}
category command-line-handler jsbridge @mozilla.org/commandlinehandler/general-startup;1?type=jsbridge

Просмотреть файл

@ -0,0 +1,40 @@
// ***** BEGIN LICENSE BLOCK *****
// Version: MPL 1.1/GPL 2.0/LGPL 2.1
//
// The contents of this file are subject to the Mozilla Public License Version
// 1.1 (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// The Original Code is Mozilla Corporation Code.
//
// The Initial Developer of the Original Code is
// Mikeal Rogers.
// Portions created by the Initial Developer are Copyright (C) 2008
// the Initial Developer. All Rights Reserved.
//
// Contributor(s):
// Mikeal Rogers <mikeal.rogers@gmail.com>
//
// Alternatively, the contents of this file may be used under the terms of
// either the GNU General Public License Version 2 or later (the "GPL"), or
// the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
// in which case the provisions of the GPL or the LGPL are applicable instead
// of those above. If you wish to allow use of your version of this file only
// under the terms of either the GPL or the LGPL, and not to allow others to
// use your version of this file under the terms of the MPL, indicate your
// decision by deleting the provisions above and replace them with the notice
// and other provisions required by the GPL or the LGPL. If you do not delete
// the provisions above, a recipient may use your version of this file under
// the terms of any one of the MPL, the GPL or the LGPL.
//
// ***** END LICENSE BLOCK *****
var jsbridgeInit = {}; Components.utils.import('resource://jsbridge/modules/init.js',jsbridgeInit);

Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<overlay id="jsbridge-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="overlay.js"/>
</overlay>

Просмотреть файл

@ -0,0 +1,124 @@
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const nsIAppShellService = Components.interfaces.nsIAppShellService;
const nsISupports = Components.interfaces.nsISupports;
const nsICategoryManager = Components.interfaces.nsICategoryManager;
const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
const nsICommandLine = Components.interfaces.nsICommandLine;
const nsICommandLineHandler = Components.interfaces.nsICommandLineHandler;
const nsIFactory = Components.interfaces.nsIFactory;
const nsIModule = Components.interfaces.nsIModule;
const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
// CHANGEME: to the chrome URI of your extension or application
const CHROME_URI = "chrome://jsbridge/content/";
// CHANGEME: change the contract id, CID, and category to be unique
// to your application.
const clh_contractID = "@mozilla.org/commandlinehandler/general-startup;1?type=jsbridge";
// use uuidgen to generate a unique ID
const clh_CID = Components.ID("{2872d428-14f6-11de-ac86-001f5bd9235c}");
// category names are sorted alphabetically. Typical command-line handlers use a
// category that begins with the letter "m".
const clh_category = "jsbridge";
var aConsoleService = Components.classes["@mozilla.org/consoleservice;1"].
getService(Components.interfaces.nsIConsoleService);
/**
* Utility functions
*/
/**
* Opens a chrome window.
* @param aChromeURISpec a string specifying the URI of the window to open.
* @param aArgument an argument to pass to the window (may be null)
*/
function openWindow(aChromeURISpec, aArgument)
{
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].
getService(Components.interfaces.nsIWindowWatcher);
ww.openWindow(null, aChromeURISpec, "_blank",
"chrome,menubar,toolbar,status,resizable,dialog=no",
aArgument);
}
/**
* The XPCOM component that implements nsICommandLineHandler.
* It also implements nsIFactory to serve as its own singleton factory.
*/
function jsbridgeHandler() {
}
jsbridgeHandler.prototype = {
classID: clh_CID,
contractID: clh_contractID,
classDescription: "jsbridgeHandler",
_xpcom_categories: [{category: "command-line-handler", entry: clh_category}],
/* nsISupports */
QueryInterface : function clh_QI(iid)
{
if (iid.equals(nsICommandLineHandler) ||
iid.equals(nsIFactory) ||
iid.equals(nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
/* nsICommandLineHandler */
handle : function clh_handle(cmdLine)
{
try {
var port = cmdLine.handleFlagWithParam("jsbridge", false);
if (port) {
var server = {};
Components.utils.import('resource://jsbridge/modules/server.js', server);
server.startServer(parseInt(port));
} else {
var server = {};
Components.utils.import('resource://jsbridge/modules/server.js', server);
server.startServer(24242);
}
}
catch (e) {
Components.utils.reportError("incorrect parameter passed to -jsbridge on the command line.");
}
},
// CHANGEME: change the help info as appropriate, but
// follow the guidelines in nsICommandLineHandler.idl
// specifically, flag descriptions should start at
// character 24, and lines should be wrapped at
// 72 characters with embedded newlines,
// and finally, the string should end with a newline
helpInfo : " -jsbridge Port to run jsbridge on.\n",
/* nsIFactory */
createInstance : function clh_CI(outer, iid)
{
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return this.QueryInterface(iid);
},
lockFactory : function clh_lock(lock)
{
/* no-op */
}
};
/**
* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.1 (Firefox 3.5).
*/
if (XPCOMUtils.generateNSGetFactory)
const NSGetFactory = XPCOMUtils.generateNSGetFactory([jsbridgeHandler]);
else
const NSGetModule = XPCOMUtils.generateNSGetModule([jsbridgeHandler]);

Просмотреть файл

@ -0,0 +1,61 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>jsbridge@mozilla.com</em:id>
<em:name>jsbridge</em:name>
<em:version>2.4.4b4</em:version>
<em:creator>Mikeal Rogers</em:creator>
<em:description>Python to JavaScript bridge</em:description>
<em:unpack>true</em:unpack>
<em:targetApplication>
<!-- Firefox -->
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>3.5</em:minVersion>
<em:maxVersion>7.*</em:maxVersion>
</Description>
</em:targetApplication>
<em:targetApplication>
<!-- Thunderbird -->
<Description>
<em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
<em:minVersion>3.0a1pre</em:minVersion>
<em:maxVersion>6.*</em:maxVersion>
</Description>
</em:targetApplication>
<em:targetApplication>
<!-- Sunbird -->
<Description>
<em:id>{718e30fb-e89b-41dd-9da7-e25a45638b28}</em:id>
<em:minVersion>1.0b1pre</em:minVersion>
<em:maxVersion>1.0pre</em:maxVersion>
</Description>
</em:targetApplication>
<em:targetApplication>
<!-- SeaMonkey -->
<Description>
<em:id>{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}</em:id>
<em:minVersion>2.0a1</em:minVersion>
<em:maxVersion>3.*</em:maxVersion>
</Description>
</em:targetApplication>
<em:targetApplication>
<!-- Songbird -->
<Description>
<em:id>songbird@songbirdnest.com</em:id>
<em:minVersion>0.3pre</em:minVersion>
<em:maxVersion>2.*</em:maxVersion>
</Description>
</em:targetApplication>
<em:targetApplication>
<Description>
<em:id>toolkit@mozilla.org</em:id>
<em:minVersion>1.9.1</em:minVersion>
<em:maxVersion>2.0*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,13 @@
var EXPORTED_SYMBOLS = ["backchannels", "fireEvent", "addBackChannel"];
var backchannels = [];
var fireEvent = function (name, obj) {
for each(backchannel in backchannels) {
backchannel.session.encodeOut({'eventType':name, 'result':obj});
}
}
var addBackChannel = function (backchannel) {
backchannels.push(backchannel);
}

Просмотреть файл

@ -0,0 +1,40 @@
// ***** BEGIN LICENSE BLOCK *****
// Version: MPL 1.1/GPL 2.0/LGPL 2.1
//
// The contents of this file are subject to the Mozilla Public License Version
// 1.1 (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// The Original Code is Mozilla Corporation Code.
//
// The Initial Developer of the Original Code is
// Mikeal Rogers.
// Portions created by the Initial Developer are Copyright (C) 2008
// the Initial Developer. All Rights Reserved.
//
// Contributor(s):
// Mikeal Rogers <mikeal.rogers@gmail.com>
//
// Alternatively, the contents of this file may be used under the terms of
// either the GNU General Public License Version 2 or later (the "GPL"), or
// the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
// in which case the provisions of the GPL or the LGPL are applicable instead
// of those above. If you wish to allow use of your version of this file only
// under the terms of either the GPL or the LGPL, and not to allow others to
// use your version of this file under the terms of the MPL, indicate your
// decision by deleting the provisions above and replace them with the notice
// and other provisions required by the GPL or the LGPL. If you do not delete
// the provisions above, a recipient may use your version of this file under
// the terms of any one of the MPL, the GPL or the LGPL.
//
// ***** END LICENSE BLOCK *****
var EXPORTED_SYMBOLS = ["server"];
var server = {}; Components.utils.import('resource://jsbridge/modules/server.js', server);

Просмотреть файл

@ -0,0 +1,471 @@
/*
http://www.JSON.org/json2.js
2008-05-25
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
This file creates a global JSON object containing two methods: stringify
and parse.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
replacer an optional parameter that determines how object
values are stringified for objects without a toJSON
method. It can be a function or an array.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or '&nbsp;'),
it contains the characters used to indent at each level.
This method produces a JSON text from a JavaScript value.
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the object holding the key.
For example, this would serialize Dates as ISO strings.
Date.prototype.toJSON = function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the replacer parameter is an array, then it will be used to
select the members to be serialized. It filters the results such
that only members with keys listed in the replacer array are
stringified.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
text = JSON.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
// text is '["Date(---current time---)"]'
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
This is a reference implementation. You are free to copy, modify, or
redistribute.
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
*/
/*jslint evil: true */
/*global JSON */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", call,
charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, getUTCMinutes,
getUTCMonth, getUTCSeconds, hasOwnProperty, join, lastIndex, length,
parse, propertyIsEnumerable, prototype, push, replace, slice, stringify,
test, toJSON, toString
*/
var EXPORTED_SYMBOLS = ["JSON"];
if (!this.JSON) {
// Create a JSON object only if one does not already exist. We create the
// object in a closure to avoid creating global variables.
JSON = function () {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
Date.prototype.toJSON = function (key) {
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapeable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep;
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapeable.lastIndex = 0;
return escapeable.test(string) ?
'"' + string.replace(escapeable, function (a) {
var c = meta[a];
if (typeof c === 'string') {
return c;
}
return '\\u' + ('0000' +
(+(a.charCodeAt(0))).toString(16)).slice(-4);
}) + '"' :
'"' + string + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// If the object has a dontEnum length property, we'll treat it as an array.
if (typeof value.length === 'number' &&
!(value.propertyIsEnumerable('length'))) {
// The object is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0 ? '[]' :
gap ? '[\n' + gap +
partial.join(',\n' + gap) + '\n' +
mind + ']' :
'[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
k = rep[i];
if (typeof k === 'string') {
v = str(k, value, rep);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = str(k, value, rep);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0 ? '{}' :
gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
mind + '}' : '{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
// Return the JSON object containing the stringify and parse methods.
return {
stringify: function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {'': value});
},
parse: function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.
var j;
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' + ('0000' +
(+(a.charCodeAt(0))).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function' ?
walk({'': j}, '') : j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON.parse');
}
};
}();
}

Просмотреть файл

@ -0,0 +1,347 @@
// ***** BEGIN LICENSE BLOCK *****
// Version: MPL 1.1/GPL 2.0/LGPL 2.1
//
// The contents of this file are subject to the Mozilla Public License Version
// 1.1 (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// The Original Code is Mozilla Corporation Code.
//
// The Initial Developer of the Original Code is
// based on the MozRepl project.
// Portions created by the Initial Developer are Copyright (C) 2008
// the Initial Developer. All Rights Reserved.
//
// Contributor(s):
// Mikeal Rogers <mikeal.rogers@gmail.com>
// Massimiliano Mirra <bard@hyperstruct.net>
//
// Alternatively, the contents of this file may be used under the terms of
// either the GNU General Public License Version 2 or later (the "GPL"), or
// the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
// in which case the provisions of the GPL or the LGPL are applicable instead
// of those above. If you wish to allow use of your version of this file only
// under the terms of either the GPL or the LGPL, and not to allow others to
// use your version of this file under the terms of the MPL, indicate your
// decision by deleting the provisions above and replace them with the notice
// and other provisions required by the GPL or the LGPL. If you do not delete
// the provisions above, a recipient may use your version of this file under
// the terms of any one of the MPL, the GPL or the LGPL.
//
// ***** END LICENSE BLOCK *****
var EXPORTED_SYMBOLS = ["Server", "server", "AsyncRead", "Session", "sessions", "globalRegistry", "startServer"];
var events = {}; Components.utils.import("resource://jsbridge/modules/events.js", events);
const DEBUG_ON = false;
const BUFFER_SIZE = 1024;
const Cc = Components.classes;
const Ci = Components.interfaces;
const loader = Cc['@mozilla.org/moz/jssubscript-loader;1']
.getService(Ci.mozIJSSubScriptLoader);
var hwindow = Components.classes["@mozilla.org/appshell/appShellService;1"]
.getService(Components.interfaces.nsIAppShellService)
.hiddenDOMWindow;
var nativeJSON = Components.classes["@mozilla.org/dom/json;1"]
.createInstance(Components.interfaces.nsIJSON);
var json2 = Components.utils.import("resource://jsbridge/modules/json2.js");
var jsonEncode = json2.JSON.stringify;
var uuidgen = Components.classes["@mozilla.org/uuid-generator;1"]
.getService(Components.interfaces.nsIUUIDGenerator);
function AsyncRead (session) {
this.session = session;
}
AsyncRead.prototype.onStartRequest = function (request, context) {};
AsyncRead.prototype.onStopRequest = function (request, context, status) {
log("async onstoprequest: onstoprequest");
this.session.onQuit();
}
AsyncRead.prototype.onDataAvailable = function (request, context, inputStream, offset, count) {
var str = {};
str.value = '';
var bytesAvail = 0;
do {
var parts = {};
if (count > BUFFER_SIZE) {
bytesAvail = BUFFER_SIZE;
} else {
bytesAvail = count;
}
log("jsbridge: onDataAvailable, reading bytesAvail = " + bytesAvail + "\n");
var bytesRead = this.session.instream.readString(bytesAvail, parts);
count = count - bytesRead;
log("jsbridge: onDataAvailable, read bytes: " + bytesRead + " count is now: " + count + "\n");
str.value += parts.value;
} while (count > 0);
log("jsbridge: onDataAvailable, going into receive with: \n\n" + str.value + "\n\n");
this.session.receive(str.value);
}
globalRegistry = {};
function Bridge (session) {
this.session = session;
this.registry = globalRegistry;
}
Bridge.prototype._register = function (_type) {
this.bridgeType = _type;
if (_type == "backchannel") {
events.addBackChannel(this);
}
}
Bridge.prototype.register = function (uuid, _type) {
try {
this._register(_type);
var passed = true;
} catch(e) {
if (typeof(e) == "string") {
var exception = e;
} else {
var exception = {'name':e.name, 'message':e.message};
}
this.session.encodeOut({'result':false, 'exception':exception, 'uuid':uuid});
}
if (passed != undefined) {
this.session.encodeOut({"result":true, 'eventType':'register', 'uuid':uuid});
}
}
Bridge.prototype._describe = function (obj) {
var response = {};
if (obj == null) {
var type = "null";
} else {
var type = typeof(obj);
}
if (type == "object") {
if (obj.length != undefined) {
var type = "array";
}
response.attributes = [];
for (i in obj) {
response.attributes = response.attributes.concat(i);
}
}
else if (type != "function"){
response.data = obj;
}
response.type = type;
return response;
}
Bridge.prototype.describe = function (uuid, obj) {
var response = this._describe(obj);
response.uuid = uuid;
response.result = true;
this.session.encodeOut(response);
}
Bridge.prototype._set = function (obj) {
var uuid = uuidgen.generateUUID().toString();
this.registry[uuid] = obj;
return uuid;
}
Bridge.prototype.set = function (uuid, obj) {
var ruuid = this._set(obj);
this.session.encodeOut({'result':true, 'data':'bridge.registry["'+ruuid+'"]', 'uuid':uuid});
}
Bridge.prototype._setAttribute = function (obj, name, value) {
obj[name] = value;
return value;
}
Bridge.prototype.setAttribute = function (uuid, obj, name, value) {
try {
var result = this._setAttribute(obj, name, value);
} catch(e) {
if (typeof(e) == "string") {
var exception = e;
} else {
var exception = {'name':e.name, 'message':e.message};
}
this.session.encodeOut({'result':false, 'exception':exception, 'uuid':uuid});
}
if (result != undefined) {
this.set(uuid, obj[name]);
}
}
Bridge.prototype._execFunction = function (func, args) {
return func.apply(this.session.sandbox, args);
}
Bridge.prototype.execFunction = function (uuid, func, args) {
try {
var data = this._execFunction(func, args);
var result = true;
} catch(e) {
if (typeof(e) == "string") {
var exception = e;
} else {
var exception = {'name':e.name, 'message':e.message};
}
this.session.encodeOut({'result':false, 'exception':exception, 'uuid':uuid});
var result = true;
}
if (data != undefined) {
this.set(uuid, data);
} else if ( result == true) {
this.session.encodeOut({'result':true, 'data':null, 'uuid':uuid});
} else {
log("jsbridge threw unknown data in execFunc");
throw 'JSBridge unknown data in execFunc';
}
}
backstage = this;
function Session (transport) {
this.transpart = transport;
this.sandbox = Components.utils.Sandbox(backstage);
this.sandbox.bridge = new Bridge(this);
this.sandbox.openPreferences = hwindow.openPreferences;
try {
this.outputstream = transport.openOutputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0);
this.outstream = Cc['@mozilla.org/intl/converter-output-stream;1']
.createInstance(Ci.nsIConverterOutputStream);
this.outstream.init(this.outputstream, 'UTF-8', BUFFER_SIZE,
Ci.nsIConverterOutputStream.DEFAULT_REPLACEMENT_CHARACTER);
this.stream = transport.openInputStream(0, 0, 0);
this.instream = Cc['@mozilla.org/intl/converter-input-stream;1']
.createInstance(Ci.nsIConverterInputStream);
this.instream.init(this.stream, 'UTF-8', BUFFER_SIZE,
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
} catch(e) {
log('jsbridge: Error: ' + e);
}
log('jsbridge: Accepted connection.');
this.pump = Cc['@mozilla.org/network/input-stream-pump;1']
.createInstance(Ci.nsIInputStreamPump);
this.pump.init(this.stream, -1, -1, 0, 0, false);
this.pump.asyncRead(new AsyncRead(this), null);
}
Session.prototype.onOutput = function(string) {
log('jsbridge: write: '+string)
if (typeof(string) != "string") {
throw "This is not a string"
}
try {
var stroffset = 0;
do {
var parts = '';
// Handle the case where we are writing something larger than our buffer
if (string.length > BUFFER_SIZE) {
log("jsbridge: onOutput: writing data stroffset is: " + stroffset + " string.length is: " + string.length);
parts = string.slice(stroffset, stroffset + BUFFER_SIZE);
log("jsbridge: onOutput: here is our part: \n" + parts + "\n");
} else {
parts = string;
}
// Update our offset
stroffset = stroffset += parts.length;
// write it
this.outstream.writeString(parts);
} while (stroffset < string.length);
// Ensure the entire stream is flushed
this.outstream.flush();
} catch (e) {
log("jsbridge: threw on writing string: " + string + " exception: " + e);
throw "JSBridge cannot write: "+string
}
};
Session.prototype.onQuit = function() {
this.instream.close();
this.outstream.close();
sessions.remove(session);
};
Session.prototype.encodeOut = function (obj) {
try {
this.onOutput(jsonEncode(obj));
} catch(e) {
if (typeof(e) == "string") {
var exception = e;
} else {
var exception = {'name':e.name, 'message':e.message};
}
this.onOutput(jsonEncode({'result':false, 'exception':exception}));
}
}
Session.prototype.receive = function(data) {
Components.utils.evalInSandbox(data, this.sandbox);
}
var sessions = {
_list: [],
add: function(session) {
this._list.push(session);
},
remove: function(session) {
var index = this._list.indexOf(session);
if(index != -1)
this._list.splice(index, 1);
},
get: function(index) {
return this._list[index];
},
quit: function() {
this._list.forEach(
function(session) { session.quit; });
this._list.splice(0, this._list.length);
}
};
function Server (port) {
this.port = port;
}
Server.prototype.start = function () {
try {
this.serv = Cc['@mozilla.org/network/server-socket;1']
.createInstance(Ci.nsIServerSocket);
this.serv.init(this.port, true, -1);
this.serv.asyncListen(this);
} catch(e) {
log('jsbridge: Exception: ' + e);
}
}
Server.prototype.stop = function () {
log('jsbridge: Closing...');
this.serv.close();
this.sessions.quit();
this.serv = undefined;
}
Server.prototype.onStopListening = function (serv, status) {
// Stub function
}
Server.prototype.onSocketAccepted = function (serv, transport) {
session = new Session(transport)
sessions.add(session);
}
function log(msg) {
if (DEBUG_ON) {
dump(msg + '\n');
}
}
function startServer(port) {
var server = new Server(port)
server.start()
}

Просмотреть файл

@ -0,0 +1,167 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Corporation Code.
#
# The Initial Developer of the Original Code is
# Mikeal Rogers.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Mikeal Rogers <mikeal.rogers@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
def init_jsobject(cls, bridge, name, value, description=None):
"""Initialize a js object that is a subclassed base type; int, str, unicode, float."""
obj = cls(value)
obj._bridge_ = bridge
obj._name_ = name
obj._description_ = description
return obj
def create_jsobject(bridge, fullname, value=None, obj_type=None, override_set=False):
"""Create a single JSObject for named object on other side of the bridge.
Handles various initization cases for different JSObjects."""
description = bridge.describe(fullname)
obj_type = description['type']
value = description.get('data', None)
if value is True or value is False:
return value
if js_type_cases.has_key(obj_type):
cls, needs_init = js_type_cases[obj_type]
# Objects that requires initialization are base types that have "values".
if needs_init:
obj = init_jsobject(cls, bridge, fullname, value, description=description)
else:
obj = cls(bridge, fullname, description=description, override_set=override_set)
return obj
else:
# Something very bad happened, we don't have a representation for the given type.
raise TypeError("Don't have a JSObject for javascript type "+obj_type)
class JSObject(object):
"""Base javascript object representation."""
_loaded_ = False
def __init__(self, bridge, name, override_set=False, description=None, *args, **kwargs):
self._bridge_ = bridge
if not override_set:
name = bridge.set(name)['data']
self._name_ = name
self._description_ = description
def __jsget__(self, name):
"""Abstraction for final step in get events; __getitem__ and __getattr__.
"""
result = create_jsobject(self._bridge_, name, override_set=True)
return result
def __getattr__(self, name):
"""Get the object from jsbridge.
Handles lazy loading of all attributes of self."""
# A little hack so that ipython returns all the names.
if name == '_getAttributeNames':
return lambda : self._bridge_.describe(self._name_)['attributes']
attributes = self._bridge_.describe(self._name_)['attributes']
if name in attributes:
return self.__jsget__(self._name_+'["'+name+'"]')
else:
raise AttributeError(name+" is undefined.")
__getitem__ = __getattr__
def __setattr__(self, name, value):
"""Set the given JSObject as an attribute of this JSObject and make proper javascript
assignment on the other side of the bridge."""
if name.startswith('_') and name.endswith('_'):
return object.__setattr__(self, name, value)
response = self._bridge_.setAttribute(self._name_, name, value)
object.__setattr__(self, name, create_jsobject(self._bridge_, response['data'], override_set=True))
__setitem__ = __setattr__
class JSFunction(JSObject):
"""Javascript function represenation.
Returns a JSObject instance for the serialized js type with
name set to the full javascript call for this function.
"""
def __init__(self, bridge, name, override_set=False, description=None, *args, **kwargs):
self._bridge_ = bridge
self._name_ = name
self._description_ = description
def __call__(self, *args):
response = self._bridge_.execFunction(self._name_, args)
if response['data'] is not None:
return create_jsobject(self._bridge_, response['data'], override_set=True)
class JSString(JSObject, unicode):
"Javascript string representation."
__init__ = unicode.__init__
class JSInt(JSObject, int):
"""Javascript number representation for Python int."""
__init__ = int.__init__
class JSFloat(JSObject, float):
"""Javascript number representation for Python float."""
__init__ = float.__init__
class JSUndefined(JSObject):
"""Javascript undefined representation."""
__str__ = lambda self : "undefined"
def __cmp__(self, other):
if isinstance(other, JSUndefined):
return True
else:
return False
__nonzero__ = lambda self: False
js_type_cases = {'function' :(JSFunction, False,),
'object' :(JSObject, False,),
'array' :(JSObject, False,),
'string' :(JSString, True,),
'number' :(JSFloat, True,),
'undefined':(JSUndefined, False,),
'null' :(JSObject, False,),
}
py_type_cases = {unicode :JSString,
str :JSString,
int :JSInt,
float :JSFloat,
}

Просмотреть файл

@ -0,0 +1,308 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Corporation Code.
#
# The Initial Developer of the Original Code is
# Mikeal Rogers.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Mikeal Rogers <mikeal.rogers@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
import asyncore
import socket
import select
import logging
import uuid
from time import sleep
from threading import Thread
try:
import json as simplejson
from json.encoder import encode_basestring_ascii, encode_basestring
except ImportError:
import simplejson
from simplejson.encoder import encode_basestring_ascii, encode_basestring
logger = logging.getLogger(__name__)
class JavaScriptException(Exception): pass
class Telnet(asyncore.dispatcher):
def __init__(self, host, port):
self.host, self.port = host, port
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((host, port))
self.buffer = ''
self.logger = logger
def __del__(self):
self.close()
def handle_close(self):
"""override method of asyncore.dispatcher"""
self.close()
def handle_expt(self):
self.close() # connection failed, shutdown
def writable(self):
return (len(self.buffer) > 0)
def handle_write(self):
sent = self.send(self.buffer)
self.buffer = self.buffer[sent:]
def read_all(self):
import socket
data = ''
while 1:
try:
data += self.recv(4096)
except socket.error:
return data
def handle_read(self):
self.data = self.read_all()
self.process_read(self.data)
read_callback = lambda self, data: None
decoder = simplejson.JSONDecoder()
class JSObjectEncoder(simplejson.JSONEncoder):
"""Encoder that supports jsobject references by name."""
def encode(self, o):
import jsobjects
if isinstance(o, jsobjects.JSObject):
return o._name_
else:
return simplejson.JSONEncoder.encode(self, o)
def _iterencode(self, o, markers=None):
import jsobjects
if isinstance(o, jsobjects.JSObject):
yield o._name_
elif isinstance(o, basestring):
if self.ensure_ascii:
encoder = encode_basestring_ascii
else:
encoder = encode_basestring
_encoding = self.encoding
if (_encoding is not None and isinstance(o, str)
and not (_encoding == 'utf-8')):
o = o.decode(_encoding)
yield encoder(o)
elif o is None:
yield 'null'
elif o is True:
yield 'true'
elif o is False:
yield 'false'
elif isinstance(o, (int, long)):
yield str(o)
elif isinstance(o, float):
yield getattr(simplejson.encoder, 'floatstr', simplejson.encoder._floatstr)(o, self.allow_nan)
elif isinstance(o, (list, tuple)):
for chunk in self._iterencode_list(o, markers):
yield chunk
elif isinstance(o, dict):
for chunk in self._iterencode_dict(o, markers):
yield chunk
else:
if markers is not None:
markerid = id(o)
if markerid in markers:
raise ValueError("Circular reference detected")
markers[markerid] = o
for chunk in self._iterencode_default(o, markers):
yield chunk
if markers is not None:
del markers[markerid]
encoder = JSObjectEncoder()
class JSBridgeDisconnectError(Exception):
"""exception raised when an unexpected disconect happens"""
class Bridge(Telnet):
trashes = []
reading = False
sbuffer = ''
events_list = []
callbacks = {}
bridge_type = "bridge"
registered = False
timeout_ctr = 0. # global timeout counter
def __init__(self, host, port, timeout=60.):
"""
- timeout : failsafe timeout for each call to run in seconds
"""
self.timeout = timeout
Telnet.__init__(self, host, port)
sleep(.1)
# XXX we've actually already connected in Telnet
self.connect((host, port))
def handle_connect(self):
self.register()
def run(self, _uuid, exec_string, interval=.2, raise_exeption=True):
exec_string += '\r\n'
self.send(exec_string)
while _uuid not in self.callbacks.keys():
Bridge.timeout_ctr += interval
if Bridge.timeout_ctr > self.timeout:
print 'Timeout: %s' % exec_string
raise JSBridgeDisconnectError("Connection timed out")
sleep(interval)
try:
self.send('')
except socket.error, e:
raise JSBridgeDisconnectError("JSBridge Socket Disconnected: %s" % e)
Bridge.timeout_ctr = 0. # reset the counter
callback = self.callbacks.pop(_uuid)
if callback['result'] is False and raise_exeption is True:
raise JavaScriptException(callback['exception'])
return callback
def register(self):
_uuid = str(uuid.uuid1())
self.send('bridge.register("'+_uuid+'", "'+self.bridge_type+'")\r\n')
self.registered = True
def execFunction(self, func_name, args, interval=.25):
_uuid = str(uuid.uuid1())
exec_args = [encoder.encode(_uuid), func_name, encoder.encode(args)]
return self.run(_uuid, 'bridge.execFunction('+ ', '.join(exec_args)+')', interval)
def setAttribute(self, obj_name, name, value):
_uuid = str(uuid.uuid1())
exec_args = [encoder.encode(_uuid), obj_name, encoder.encode(name), encoder.encode(value)]
return self.run(_uuid, 'bridge.setAttribute('+', '.join(exec_args)+')')
def set(self, obj_name):
_uuid = str(uuid.uuid1())
return self.run(_uuid, 'bridge.set('+', '.join([encoder.encode(_uuid), obj_name])+')')
def describe(self, obj_name):
_uuid = str(uuid.uuid1())
return self.run(_uuid, 'bridge.describe('+', '.join([encoder.encode(_uuid), obj_name])+')')
def fire_callbacks(self, obj):
self.callbacks[obj['uuid']] = obj
def process_read(self, data):
"""Parse out json objects and fire callbacks."""
self.sbuffer += data
self.reading = True
self.parsing = True
while self.parsing:
# Remove erroneus data in front of callback object
index = self.sbuffer.find('{')
if index is not -1 and index is not 0:
self.sbuffer = self.sbuffer[index:]
# Try to get a json object from the data stream
try:
obj, index = decoder.raw_decode(self.sbuffer)
except Exception, e:
self.parsing = False
# If we got an object fire the callback infra
if self.parsing:
self.fire_callbacks(obj)
self.sbuffer = self.sbuffer[index:]
class BackChannel(Bridge):
bridge_type = "backchannel"
def __init__(self, host, port):
Bridge.__init__(self, host, port)
self.uuid_listener_index = {}
self.event_listener_index = {}
self.global_listeners = []
def fire_callbacks(self, obj):
"""Handle all callback fireing on json objects pulled from the data stream."""
self.fire_event(**dict([(str(key), value,) for key, value in obj.items()]))
def add_listener(self, callback, uuid=None, eventType=None):
if uuid is not None:
self.uuid_listener_index.setdefault(uuid, []).append(callback)
if eventType is not None:
self.event_listener_index.setdefault(eventType, []).append(callback)
def add_global_listener(self, callback):
self.global_listeners.append(callback)
def fire_event(self, eventType=None, uuid=None, result=None, exception=None):
Bridge.timeout_ctr = 0. # reset the counter
event = eventType
if uuid is not None and self.uuid_listener_index.has_key(uuid):
for callback in self.uuid_listener_index[uuid]:
callback(result)
if event is not None and self.event_listener_index.has_key(event):
for callback in self.event_listener_index[event]:
callback(result)
for listener in self.global_listeners:
listener(eventType, result)
thread = None
def create_network(hostname, port):
back_channel = BackChannel(hostname, port)
bridge = Bridge(hostname, port)
global thread
if not thread or not thread.isAlive():
def do():
try: asyncore.loop(use_poll=True)
except select.error:pass
thread = Thread(target=do)
getattr(thread, 'setDaemon', lambda x : None)(True)
thread.start()
return back_channel, bridge

Просмотреть файл

@ -0,0 +1,77 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Corporation Code.
#
# The Initial Developer of the Original Code is
# Mikeal Rogers.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Mikeal Rogers <mikeal.rogers@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
import sys
from setuptools import setup, find_packages
desc = """Python to JavaScript bridge interface."""
summ = """A powerful and extensible Python to JavaScript bridge interface."""
PACKAGE_NAME = "jsbridge"
PACKAGE_VERSION = "2.4.4b4"
requires = ['mozrunner == 2.5.5b4']
if not sys.version.startswith('2.6'):
requires.append('simplejson')
setup(name=PACKAGE_NAME,
version=PACKAGE_VERSION,
description=desc,
long_description=summ,
author='Mikeal Rogers, Mozilla',
author_email='mikeal.rogers@gmail.com',
url='http://github.com/mozautomation/mozmill',
license='http://www.apache.org/licenses/LICENSE-2.0',
packages=find_packages(exclude=['test']),
include_package_data=True,
package_data = {'': ['*.js', '*.css', '*.html', '*.txt', '*.xpi', '*.rdf', '*.xul', '*.jsm', '*.xml' 'extension'],},
zip_safe=False,
entry_points="""
[console_scripts]
jsbridge = jsbridge:cli
""",
platforms =['Any'],
install_requires = requires,
classifiers=['Development Status :: 4 - Beta',
'Environment :: Console',
'Intended Audience :: Developers',
'License :: OSI Approved :: Apache Software License',
'Operating System :: OS Independent',
'Topic :: Software Development :: Libraries :: Python Modules',
]
)

Просмотреть файл

@ -0,0 +1,2 @@
recursive-include docs *
recursive-include mozmill/extension *

Просмотреть файл

@ -0,0 +1,75 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " changes to make an overview over all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
clean:
-rm -rf _build/*
html:
mkdir -p _build/html _build/doctrees
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
@echo
@echo "Build finished. The HTML pages are in _build/html."
pickle:
mkdir -p _build/pickle _build/doctrees
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
@echo
@echo "Build finished; now you can process the pickle files."
web: pickle
json:
mkdir -p _build/json _build/doctrees
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
mkdir -p _build/htmlhelp _build/doctrees
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in _build/htmlhelp."
latex:
mkdir -p _build/latex _build/doctrees
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
@echo
@echo "Build finished; the LaTeX files are in _build/latex."
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
"run these through (pdf)latex."
changes:
mkdir -p _build/changes _build/doctrees
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
@echo
@echo "The overview file is in _build/changes."
linkcheck:
mkdir -p _build/linkcheck _build/doctrees
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in _build/linkcheck/output.txt."

Двоичные данные
mail/test/resources/mozmill/docs/_build/doctrees/environment.pickle поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
mail/test/resources/mozmill/docs/_build/doctrees/index.doctree поставляемый Normal file

Двоичный файл не отображается.

188
mail/test/resources/mozmill/docs/_build/html/_sources/index.txt поставляемый Normal file
Просмотреть файл

@ -0,0 +1,188 @@
:mod:`mozmill` --- Full automation of XULRunner applications.
=============================================================
.. module:: mozmill
:synopsis: Full automation of XULRunner applications.
.. moduleauthor:: Mikeal Rogers <mikeal.rogers@gmail.com>
.. sectionauthor:: Mikeal Rogers <mikeal.rogers@gmail.com>
Command Line Usage
------------------
The mozmill command line is versatile and includes a fair amount of debugging options. Even though all these options are available mozmill should run by default without any arguments and find your locally installed Firefox and run with mozmill.
In most modes, ctrl-c will shut down Firefox and exit out of the mozmill Python side as well.
.. code-block:: none
$ mozmill
.. cmdoption:: -h, --help
Show help message.
.. cmdoption:: -b <binary>, --binary <binary>
Specify application binary location.
Default :class:`mozrunner.Profile` and :class:`mozrunner.Runner` are still
:class:`mozrunner.FirefoxProfile` and :class:`mozrunner.FirefoxRunner`. You can
change this by creating your own command line utility by subclassing :class:`CLI`
.. cmdoption:: -d <defaultprofile>
Specify the path to the default **clean** profile used to create new profiles.
.. cmdoption:: -n, --no-new-profile
Do not create a new fresh profile.
.. cmdoption:: -p <profile>, --profile <profile>
Specifies a profile to use. Must be used with --no-new-profile.
.. cmdoption:: -w <plugins>, --plugins <plugins>
Comma seperated list of additional paths to plugins to install.
Plugins can be either .xpi zip compressed extensions or deflated extension directories.
.. cmdoption:: -l <logfile>, --logfile <logfile>
Log all events to *logfile*.
.. cmdoption:: --report <uri>
*Currently in development.*
POST results to given brasstacks results server at *uri*.
.. cmdoption:: -t <test>, --test <test>
Run *test*. Can be either single test file or directory of tests.
.. cmdoption:: --showall
Show all test output.
.. cmdoption:: -D, --debug
Install debugging extensions and run with -jsconole
.. cmdoption:: --show-errors
Print all logger errors to the console. When running tests only test failures and skipped
tests are printed, this option print all other errors.
.. cmdoption:: -s, --shell
Starts a Python shell for debugging.
.. cmdoption:: -u, --usecode
By default --shell mode will use iPython if install and fall back to using the code module.
This option forces the use of the code module instead of iPython even when installed.
.. cmdoption:: -P <port>, --port <port>
Specify port for jsbridge.
Command Line Class
------------------
.. class:: CLI
Inherits from :class:`jsbridge.CLI` which inherits from :class:`mozrunner.CLI`.
All the heavy lifting is handled by jsbridge and mozrunner. If you are subclassing
this in order to creat a new command line interface be sure to call :func:`super` on all
related methods.
.. attribute:: runner_class
Default runner class. Should be subclass of :class:`mozrunner.Runner`.
Defaults to :class:`mozrunner.FirefoxRunner`.
.. attribute:: profile_class
Default profile class. Should be subclass of :class:`mozruner.Profile`.
Defaults to :class:`mozrunner.FirefoxProfile`.
Running MozMill from Python
---------------------------
.. class:: MozMill([runner_class[, profile_class[, jsbridge_port]]])
Manages an instance of Firefox w/ jsbridge and provides facilities for running tests and
keeping track of results with callback methods.
Default *runner_class* is :class:`mozrunner.FirefoxRunner`. Value should be a subclass of
:class:`mozrunner.Runner`.
Default *profile_class* is :class:`mozrunner.FirefoxProfile`. Value should be a subclass of
:class:`mozrunner.Profile`.
Default *jsbridge_port* is `24242`.
.. attribute:: runner_class
Set during initialization to subclass of :class:`mozrunner.Runner`.
.. attribute:: profile_class
Set during initialization to subclass of :class:`mozrunner.Profile`.
.. attribute:: jsbridge_port
Set during initialization to :class:`numbers.Integral`.
.. method:: start([profile[, runner]])
Start mozrunner and jsbridge pre-requisites.
*profile* should be an instance of a `mozrunner.Profile` subclass. If one is not passed
an instance of `self.profile_class` is created. `self.profile` will be set to this
value.
*runner* should be an instance of a `mozrunner.Runner` subclass. If one is not passed an
instance of :attr:`runner_class` will be created. :attr:`runner` will be set to this value.
This method will also run `runner.start()` and :func:`mozrunner.wait_and_create_network`
and sets :attr:`back_channel` and :attr:`bridge` to instances of
:class:`jsbridge.BackChannel` and :class:`jsbridge.Bridge` respectively.
.. attribute:: profile
Set during :meth:`start` to subclass of :class:`mozrunner.Profile`.
.. attribute:: runner
Set during :meth:`start` to subclass of :class:`mozrunner.Runner`.
.. attribute:: back_channel
Set during :meth:`start` to subclass of :class:`jsbridge.BackChannel`.
.. attribute:: bridge
Set during :meth:`start` to subclass of :class:`jsbridge.Bridge`
.. method:: run_tests(test[, report])
Run *test* in live Firefox using :attr:`bridge`.
Adds local listeners :meth:`endTest_listener` and :meth:`endRunner_listener` to
`"endTest"` and `"endRunner"` events using :meth:`jsbridge.BackChannel.add_listener` of
:attr:`back_channel`.
When tests are done the results are posted to a results server at *report* if passed.
.. method:: endTest_listener(test)
When a test is finished the test object will be passed to this callback.
.. method:: endRunner_listener(obj)
When all the tests are done running this callback will be fired.

Двоичные данные
mail/test/resources/mozmill/docs/_build/html/_static/contents.png поставляемый Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 202 B

657
mail/test/resources/mozmill/docs/_build/html/_static/default.css поставляемый Normal file
Просмотреть файл

@ -0,0 +1,657 @@
/**
* Sphinx Doc Design
*/
body {
font-family: sans-serif;
font-size: 100%;
background-color: #11303d;
color: #000;
margin: 0;
padding: 0;
}
/* :::: LAYOUT :::: */
div.document {
background-color: #1c4e63;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 230px;
}
div.body {
background-color: white;
padding: 0 20px 30px 20px;
}
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
}
div.clearer {
clear: both;
}
div.footer {
color: #fff;
width: 100%;
padding: 9px 0 9px 0;
text-align: center;
font-size: 75%;
}
div.footer a {
color: #fff;
text-decoration: underline;
}
div.related {
background-color: #133f52;
color: #fff;
width: 100%;
line-height: 30px;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
div.related a {
color: white;
}
/* ::: TOC :::: */
div.sphinxsidebar h3 {
font-family: 'Trebuchet MS', sans-serif;
color: white;
font-size: 1.4em;
font-weight: normal;
margin: 0;
padding: 0;
}
div.sphinxsidebar h3 a {
color: white;
}
div.sphinxsidebar h4 {
font-family: 'Trebuchet MS', sans-serif;
color: white;
font-size: 1.3em;
font-weight: normal;
margin: 5px 0 0 0;
padding: 0;
}
div.sphinxsidebar p {
color: white;
}
div.sphinxsidebar p.topless {
margin: 5px 10px 10px 10px;
}
div.sphinxsidebar ul {
margin: 10px;
padding: 0;
list-style: none;
color: white;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar a {
color: #98dbcc;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
/* :::: MODULE CLOUD :::: */
div.modulecloud {
margin: -5px 10px 5px 10px;
padding: 10px;
line-height: 160%;
border: 1px solid #cbe7e5;
background-color: #f2fbfd;
}
div.modulecloud a {
padding: 0 5px 0 5px;
}
/* :::: SEARCH :::: */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* :::: COMMON FORM STYLES :::: */
div.actions {
padding: 5px 10px 5px 10px;
border-top: 1px solid #cbe7e5;
border-bottom: 1px solid #cbe7e5;
background-color: #e0f6f4;
}
form dl {
color: #333;
}
form dt {
clear: both;
float: left;
min-width: 110px;
margin-right: 10px;
padding-top: 2px;
}
input#homepage {
display: none;
}
div.error {
margin: 5px 20px 0 0;
padding: 5px;
border: 1px solid #d00;
font-weight: bold;
}
/* :::: INDEX PAGE :::: */
table.contentstable {
width: 90%;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* :::: INDEX STYLES :::: */
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable dl, table.indextable dd {
margin-top: 0;
margin-bottom: 0;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
form.pfform {
margin: 10px 0 20px 0;
}
/* :::: GLOBAL STYLES :::: */
.docwarning {
background-color: #ffe4e4;
padding: 10px;
margin: 0 -20px 0 -20px;
border-bottom: 1px solid #f66;
}
p.subhead {
font-weight: bold;
margin-top: 20px;
}
a {
color: #355f7c;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: 'Trebuchet MS', sans-serif;
background-color: #f2f2f2;
font-weight: normal;
color: #20435c;
border-bottom: 1px solid #ccc;
margin: 20px -20px 10px -20px;
padding: 3px 0 3px 10px;
}
div.body h1 { margin-top: 0; font-size: 200%; }
div.body h2 { font-size: 160%; }
div.body h3 { font-size: 140%; }
div.body h4 { font-size: 120%; }
div.body h5 { font-size: 110%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
visibility: hidden;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink {
visibility: visible;
}
a.headerlink:hover {
background-color: #c60f0f;
color: white;
}
div.body p, div.body dd, div.body li {
text-align: justify;
line-height: 130%;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
ul.fakelist {
list-style: none;
margin: 10px 0 10px 20px;
padding: 0;
}
.field-list ul {
padding-left: 1em;
}
.first {
margin-top: 0 !important;
}
/* "Footnotes" heading */
p.rubric {
margin-top: 30px;
font-weight: bold;
}
/* Sidebars */
div.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px 7px 0 7px;
background-color: #ffe;
width: 40%;
float: right;
}
p.sidebar-title {
font-weight: bold;
}
/* "Topics" */
div.topic {
background-color: #eee;
border: 1px solid #ccc;
padding: 7px 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* Admonitions */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
div.admonition dl {
margin-bottom: 0;
}
div.admonition p.admonition-title + p {
display: inline;
}
div.seealso {
background-color: #ffc;
border: 1px solid #ff6;
}
div.warning {
background-color: #ffe4e4;
border: 1px solid #f66;
}
div.note {
background-color: #eee;
border: 1px solid #ccc;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
display: inline;
}
p.admonition-title:after {
content: ":";
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
table.docutils {
border: 0;
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 0;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.field-list td, table.field-list th {
border: 0 !important;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
dl {
margin-bottom: 15px;
clear: both;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
.refcount {
color: #060;
}
dt:target,
.highlight {
background-color: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
th {
text-align: left;
padding-right: 5px;
}
pre {
padding: 5px;
background-color: #efc;
color: #333;
border: 1px solid #ac9;
border-left: none;
border-right: none;
overflow: auto;
}
td.linenos pre {
padding: 5px 0px;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
tt {
background-color: #ecf0f3;
padding: 0 1px 0 1px;
font-size: 0.95em;
}
tt.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
tt.descclassname {
background-color: transparent;
}
tt.xref, a tt {
background-color: transparent;
font-weight: bold;
}
.footnote:target { background-color: #ffa }
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
background-color: transparent;
}
.optional {
font-size: 1.3em;
}
.versionmodified {
font-style: italic;
}
form.comment {
margin: 0;
padding: 10px 30px 10px 30px;
background-color: #eee;
}
form.comment h3 {
background-color: #326591;
color: white;
margin: -10px -30px 10px -30px;
padding: 5px;
font-size: 1.4em;
}
form.comment input,
form.comment textarea {
border: 1px solid #ccc;
padding: 2px;
font-family: sans-serif;
font-size: 100%;
}
form.comment input[type="text"] {
width: 240px;
}
form.comment textarea {
width: 100%;
height: 200px;
margin-bottom: 10px;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
img.math {
vertical-align: middle;
}
div.math p {
text-align: center;
}
span.eqno {
float: right;
}
img.logo {
border: 0;
}
/* :::: PRINT :::: */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0;
width : 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
div#comments div.new-comment-box,
#top-link {
display: none;
}
}

232
mail/test/resources/mozmill/docs/_build/html/_static/doctools.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,232 @@
/// XXX: make it cross browser
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
*/
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
"group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {}
}
/**
* small helper function to urldecode strings
*/
jQuery.urldecode = function(x) {
return decodeURIComponent(x).replace(/\+/g, ' ');
}
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s == 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
}
/**
* small function to check if an array contains
* a given item.
*/
jQuery.contains = function(arr, item) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] == item)
return true;
}
return false;
}
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node) {
if (node.nodeType == 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 && !jQuery.className.has(node.parentNode, className)) {
var span = document.createElement("span");
span.className = className;
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this)
});
}
}
return this.each(function() {
highlight(this);
});
}
/**
* Small JavaScript module for the documentation.
*/
var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initModIndex();
},
/**
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
LOCALE : 'unknown',
// gettext and ngettext don't access this so that the functions
// can savely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated == 'undefined')
return string;
return (typeof translated == 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated == 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
addTranslations : function(catalog) {
for (var key in catalog.messages)
this.TRANSLATIONS[key] = catalog.messages[key];
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
this.LOCALE = catalog.locale;
},
/**
* add context elements like header anchor links
*/
addContextElements : function() {
$('div[@id] > :header:first').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this headline')).
appendTo(this);
});
$('dt[@id]').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this definition')).
appendTo(this);
});
},
/**
* workaround a firefox stupidity
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
},
/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords : function() {
var params = $.getQueryParameters();
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div.body');
window.setTimeout(function() {
$.each(terms, function() {
body.highlightText(this.toLowerCase(), 'highlight');
});
}, 10);
$('<li class="highlight-link"><a href="javascript:Documentation.' +
'hideSearchWords()">' + _('Hide Search Matches') + '</a></li>')
.appendTo($('.sidebar .this-page-menu'));
}
},
/**
* init the modindex toggle buttons
*/
initModIndex : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
console.log($('tr.cg-' + idnum).toggle());
if (src.substr(-9) == 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_MODINDEX) {
togglers.click();
}
},
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('.sidebar .this-page-menu li.highlight-link').fadeOut(300);
$('span.highlight').removeClass('highlight');
},
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this == '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
}
};
// quick alias for translations
_ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});

Двоичные данные
mail/test/resources/mozmill/docs/_build/html/_static/file.png поставляемый Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 392 B

32
mail/test/resources/mozmill/docs/_build/html/_static/jquery.js поставляемый Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Двоичные данные
mail/test/resources/mozmill/docs/_build/html/_static/minus.png поставляемый Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 199 B

Двоичные данные
mail/test/resources/mozmill/docs/_build/html/_static/navigation.png поставляемый Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 218 B

Двоичные данные
mail/test/resources/mozmill/docs/_build/html/_static/plus.png поставляемый Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 199 B

Просмотреть файл

@ -0,0 +1,61 @@
.hll { background-color: #ffffcc }
.c { color: #408090; font-style: italic } /* Comment */
.err { border: 1px solid #FF0000 } /* Error */
.k { color: #007020; font-weight: bold } /* Keyword */
.o { color: #666666 } /* Operator */
.cm { color: #408090; font-style: italic } /* Comment.Multiline */
.cp { color: #007020 } /* Comment.Preproc */
.c1 { color: #408090; font-style: italic } /* Comment.Single */
.cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
.gd { color: #A00000 } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #FF0000 } /* Generic.Error */
.gh { color: #000080; font-weight: bold } /* Generic.Heading */
.gi { color: #00A000 } /* Generic.Inserted */
.go { color: #303030 } /* Generic.Output */
.gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.gt { color: #0040D0 } /* Generic.Traceback */
.kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
.kp { color: #007020 } /* Keyword.Pseudo */
.kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
.kt { color: #902000 } /* Keyword.Type */
.m { color: #208050 } /* Literal.Number */
.s { color: #4070a0 } /* Literal.String */
.na { color: #4070a0 } /* Name.Attribute */
.nb { color: #007020 } /* Name.Builtin */
.nc { color: #0e84b5; font-weight: bold } /* Name.Class */
.no { color: #60add5 } /* Name.Constant */
.nd { color: #555555; font-weight: bold } /* Name.Decorator */
.ni { color: #d55537; font-weight: bold } /* Name.Entity */
.ne { color: #007020 } /* Name.Exception */
.nf { color: #06287e } /* Name.Function */
.nl { color: #002070; font-weight: bold } /* Name.Label */
.nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.nt { color: #062873; font-weight: bold } /* Name.Tag */
.nv { color: #bb60d5 } /* Name.Variable */
.ow { color: #007020; font-weight: bold } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #208050 } /* Literal.Number.Float */
.mh { color: #208050 } /* Literal.Number.Hex */
.mi { color: #208050 } /* Literal.Number.Integer */
.mo { color: #208050 } /* Literal.Number.Oct */
.sb { color: #4070a0 } /* Literal.String.Backtick */
.sc { color: #4070a0 } /* Literal.String.Char */
.sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
.s2 { color: #4070a0 } /* Literal.String.Double */
.se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
.sh { color: #4070a0 } /* Literal.String.Heredoc */
.si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
.sx { color: #c65d09 } /* Literal.String.Other */
.sr { color: #235388 } /* Literal.String.Regex */
.s1 { color: #4070a0 } /* Literal.String.Single */
.ss { color: #517918 } /* Literal.String.Symbol */
.bp { color: #007020 } /* Name.Builtin.Pseudo */
.vc { color: #bb60d5 } /* Name.Variable.Class */
.vg { color: #bb60d5 } /* Name.Variable.Global */
.vi { color: #bb60d5 } /* Name.Variable.Instance */
.il { color: #208050 } /* Literal.Number.Integer.Long */

Просмотреть файл

@ -0,0 +1,16 @@
/**
* Sphinx Doc Design -- Right Side Bar Overrides
*/
div.sphinxsidebar {
float: right;
}
div.bodywrapper {
margin: 0 230px 0 0;
}
div.inlinecomments {
right: 250px;
}

Просмотреть файл

@ -0,0 +1,467 @@
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, hlwords is the list of normal, unstemmed
* words. the first one is used to find the occurance, the
* latter for highlighting it.
*/
jQuery.makeSearchSummary = function(text, keywords, hlwords) {
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
var i = textLower.indexOf(this.toLowerCase());
if (i > -1)
start = i;
});
start = Math.max(start - 120, 0);
var excerpt = ((start > 0) ? '...' : '') +
$.trim(text.substr(start, 240)) +
((start + 240 - text.length) ? '...' : '');
var rv = $('<div class="context"></div>').text(excerpt);
$.each(hlwords, function() {
rv = rv.highlightText(this, 'highlight');
});
return rv;
}
/**
* Porter Stemmer
*/
var PorterStemmer = function() {
var step2list = {
ational: 'ate',
tional: 'tion',
enci: 'ence',
anci: 'ance',
izer: 'ize',
bli: 'ble',
alli: 'al',
entli: 'ent',
eli: 'e',
ousli: 'ous',
ization: 'ize',
ation: 'ate',
ator: 'ate',
alism: 'al',
iveness: 'ive',
fulness: 'ful',
ousness: 'ous',
aliti: 'al',
iviti: 'ive',
biliti: 'ble',
logi: 'log'
};
var step3list = {
icate: 'ic',
ative: '',
alize: 'al',
iciti: 'ic',
ical: 'ic',
ful: '',
ness: ''
};
var c = "[^aeiou]"; // consonant
var v = "[aeiouy]"; // vowel
var C = c + "[^aeiouy]*"; // consonant sequence
var V = v + "[aeiou]*"; // vowel sequence
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
var s_v = "^(" + C + ")?" + v; // vowel in stem
this.stemWord = function (w) {
var stem;
var suffix;
var firstch;
var origword = w;
if (w.length < 3)
return w;
var re;
var re2;
var re3;
var re4;
firstch = w.substr(0,1);
if (firstch == "y")
w = firstch.toUpperCase() + w.substr(1);
// Step 1a
re = /^(.+?)(ss|i)es$/;
re2 = /^(.+?)([^s])s$/;
if (re.test(w))
w = w.replace(re,"$1$2");
else if (re2.test(w))
w = w.replace(re2,"$1$2");
// Step 1b
re = /^(.+?)eed$/;
re2 = /^(.+?)(ed|ing)$/;
if (re.test(w)) {
var fp = re.exec(w);
re = new RegExp(mgr0);
if (re.test(fp[1])) {
re = /.$/;
w = w.replace(re,"");
}
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1];
re2 = new RegExp(s_v);
if (re2.test(stem)) {
w = stem;
re2 = /(at|bl|iz)$/;
re3 = new RegExp("([^aeiouylsz])\\1$");
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re2.test(w))
w = w + "e";
else if (re3.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
else if (re4.test(w))
w = w + "e";
}
}
// Step 1c
re = /^(.+?)y$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(s_v);
if (re.test(stem))
w = stem + "i";
}
// Step 2
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step2list[suffix];
}
// Step 3
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step3list[suffix];
}
// Step 4
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
re2 = /^(.+?)(s|t)(ion)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
if (re.test(stem))
w = stem;
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1] + fp[2];
re2 = new RegExp(mgr1);
if (re2.test(stem))
w = stem;
}
// Step 5
re = /^(.+?)e$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
re2 = new RegExp(meq1);
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
w = stem;
}
re = /ll$/;
re2 = new RegExp(mgr1);
if (re.test(w) && re2.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
// and turn initial Y back to y
if (firstch == "y")
w = firstch.toLowerCase() + w.substr(1);
return w;
}
}
/**
* Search Module
*/
var Search = {
_index : null,
_queued_query : null,
_pulse_status : -1,
init : function() {
var params = $.getQueryParameters();
if (params.q) {
var query = params.q[0];
$('input[@name="q"]')[0].value = query;
this.performSearch(query);
}
},
/**
* Sets the index
*/
setIndex : function(index) {
var q;
this._index = index;
if ((q = this._queued_query) !== null) {
this._queued_query = null;
Search.query(q);
}
},
hasIndex : function() {
return this._index !== null;
},
deferQuery : function(query) {
this._queued_query = query;
},
stopPulse : function() {
this._pulse_status = 0;
},
startPulse : function() {
if (this._pulse_status >= 0)
return;
function pulse() {
Search._pulse_status = (Search._pulse_status + 1) % 4;
var dotString = '';
for (var i = 0; i < Search._pulse_status; i++)
dotString += '.';
Search.dots.text(dotString);
if (Search._pulse_status > -1)
window.setTimeout(pulse, 500);
};
pulse();
},
/**
* perform a search for something
*/
performSearch : function(query) {
// create the required interface elements
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p style="display: none"></p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));
this.startPulse();
// index already loaded, the browser was quick!
if (this.hasIndex())
this.query(query);
else
this.setQuery(query);
},
query : function(query) {
// stem the searchterms and add them to the
// correct list
var stemmer = new PorterStemmer();
var searchterms = [];
var excluded = [];
var hlterms = [];
var tmp = query.split(/\s+/);
var object = (tmp.length == 1) ? tmp[0].toLowerCase() : null;
for (var i = 0; i < tmp.length; i++) {
// stem the word
var word = stemmer.stemWord(tmp[i]).toLowerCase();
// select the correct list
if (word[0] == '-') {
var toAppend = excluded;
word = word.substr(1);
}
else {
var toAppend = searchterms;
hlterms.push(tmp[i].toLowerCase());
}
// only add if not already in the list
if (!$.contains(toAppend, word))
toAppend.push(word);
};
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
console.debug('SEARCH: searching for:');
console.info('required: ', searchterms);
console.info('excluded: ', excluded);
// prepare search
var filenames = this._index.filenames;
var titles = this._index.titles;
var terms = this._index.terms;
var descrefs = this._index.descrefs;
var modules = this._index.modules;
var desctypes = this._index.desctypes;
var fileMap = {};
var files = null;
var objectResults = [];
var regularResults = [];
$('#search-progress').empty();
// lookup as object
if (object != null) {
for (var module in modules) {
if (module.indexOf(object) > -1) {
fn = modules[module];
descr = _('module, in ') + titles[fn];
objectResults.push([filenames[fn], module, '#module-'+module, descr]);
}
}
for (var prefix in descrefs) {
for (var name in descrefs[prefix]) {
if (name.toLowerCase().indexOf(object) > -1) {
match = descrefs[prefix][name];
fullname = (prefix ? prefix + '.' : '') + name;
descr = desctypes[match[1]] + _(', in ') + titles[match[0]];
objectResults.push([filenames[match[0]], fullname, '#'+fullname, descr]);
}
}
}
}
// sort results descending
objectResults.sort(function(a, b) {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
// perform the search on the required terms
for (var i = 0; i < searchterms.length; i++) {
var word = searchterms[i];
// no match but word was a required one
if ((files = terms[word]) == null)
break;
if (files.length == undefined) {
files = [files];
}
// create the mapping
for (var j = 0; j < files.length; j++) {
var file = files[j];
if (file in fileMap)
fileMap[file].push(word);
else
fileMap[file] = [word];
}
}
// now check if the files don't contain excluded terms
for (var file in fileMap) {
var valid = true;
// check if all requirements are matched
if (fileMap[file].length != searchterms.length)
continue;
// ensure that none of the excluded terms is in the
// search result.
for (var i = 0; i < excluded.length; i++) {
if (terms[excluded[i]] == file ||
$.contains(terms[excluded[i]] || [], file)) {
valid = false;
break;
}
}
// if we have still a valid result we can add it
// to the result list
if (valid)
regularResults.push([filenames[file], titles[file], '', null]);
}
// delete unused variables in order to not waste
// memory until list is retrieved completely
delete filenames, titles, terms;
// now sort the regular results descending by title
regularResults.sort(function(a, b) {
var left = a[1].toLowerCase();
var right = b[1].toLowerCase();
return (left > right) ? -1 : ((left < right) ? 1 : 0);
});
// combine both
var results = regularResults.concat(objectResults);
// print the results
var resultCount = results.length;
function displayNextItem() {
// results left, load the summary and display it
if (results.length) {
var item = results.pop();
var listItem = $('<li style="display:none"></li>');
listItem.append($('<a/>').attr(
'href',
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
highlightstring + item[2]).html(item[1]));
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
$.get('_sources/' + item[0] + '.txt', function(data) {
listItem.append($.makeSearchSummary(data, searchterms, hlterms));
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
});
} else {
// no source available, just display title
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
}
}
// search finished, update title and status message
else {
Search.stopPulse();
Search.title.text(_('Search Results'));
if (!resultCount)
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
else
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
Search.status.fadeIn(500);
}
}
displayNextItem();
}
}
$(document).ready(function() {
Search.init();
});

Просмотреть файл

@ -0,0 +1,557 @@
/**
* Alternate Sphinx design
* Originally created by Armin Ronacher for Werkzeug, adapted by Georg Brandl.
*/
body {
font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', 'Verdana', sans-serif;
font-size: 14px;
letter-spacing: -0.01em;
line-height: 150%;
text-align: center;
/*background-color: #AFC1C4; */
background-color: #BFD1D4;
color: black;
padding: 0;
border: 1px solid #aaa;
margin: 0px 80px 0px 80px;
min-width: 740px;
}
a {
color: #CA7900;
text-decoration: none;
}
a:hover {
color: #2491CF;
}
pre {
font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
font-size: 0.95em;
letter-spacing: 0.015em;
padding: 0.5em;
border: 1px solid #ccc;
background-color: #f8f8f8;
}
td.linenos pre {
padding: 0.5em 0;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
cite, code, tt {
font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
font-size: 0.95em;
letter-spacing: 0.01em;
}
hr {
border: 1px solid #abc;
margin: 2em;
}
tt {
background-color: #f2f2f2;
border-bottom: 1px solid #ddd;
color: #333;
}
tt.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
border: 0;
}
tt.descclassname {
background-color: transparent;
border: 0;
}
tt.xref {
background-color: transparent;
font-weight: bold;
border: 0;
}
a tt {
background-color: transparent;
font-weight: bold;
border: 0;
color: #CA7900;
}
a tt:hover {
color: #2491CF;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
dl {
margin-bottom: 15px;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
.refcount {
color: #060;
}
dt:target,
.highlight {
background-color: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
pre {
line-height: 120%;
}
pre a {
color: inherit;
text-decoration: underline;
}
.first {
margin-top: 0 !important;
}
div.document {
background-color: white;
text-align: left;
background-image: url(contents.png);
background-repeat: repeat-x;
}
/*
div.documentwrapper {
width: 100%;
}
*/
div.clearer {
clear: both;
}
div.related h3 {
display: none;
}
div.related ul {
background-image: url(navigation.png);
height: 2em;
list-style: none;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 0;
padding-left: 10px;
}
div.related ul li {
margin: 0;
padding: 0;
height: 2em;
float: left;
}
div.related ul li.right {
float: right;
margin-right: 5px;
}
div.related ul li a {
margin: 0;
padding: 0 5px 0 5px;
line-height: 1.75em;
color: #EE9816;
}
div.related ul li a:hover {
color: #3CA8E7;
}
div.body {
margin: 0;
padding: 0.5em 20px 20px 20px;
}
div.bodywrapper {
margin: 0 240px 0 0;
border-right: 1px solid #ccc;
}
div.body a {
text-decoration: underline;
}
div.sphinxsidebar {
margin: 0;
padding: 0.5em 15px 15px 0;
width: 210px;
float: right;
text-align: left;
/* margin-left: -100%; */
}
div.sphinxsidebar h4, div.sphinxsidebar h3 {
margin: 1em 0 0.5em 0;
font-size: 0.9em;
padding: 0.1em 0 0.1em 0.5em;
color: white;
border: 1px solid #86989B;
background-color: #AFC1C4;
}
div.sphinxsidebar h3 a {
color: white;
}
div.sphinxsidebar ul {
padding-left: 1.5em;
margin-top: 7px;
list-style: none;
padding: 0;
line-height: 130%;
}
div.sphinxsidebar ul ul {
list-style: square;
margin-left: 20px;
}
p {
margin: 0.8em 0 0.5em 0;
}
p.rubric {
font-weight: bold;
}
div.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px 7px 0 7px;
background-color: #ffe;
width: 40%;
float: right;
}
div.quotebar {
background-color: #f8f8f8;
max-width: 250px;
float: right;
padding: 2px 7px;
border: 1px solid #ccc;
}
p.sidebar-title {
font-weight: bold;
}
div.topic {
background-color: #f8f8f8;
border: 1px solid #ccc;
padding: 7px 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
}
h1 {
margin: 0;
padding: 0.7em 0 0.3em 0;
font-size: 1.5em;
color: #11557C;
}
h2 {
margin: 1.3em 0 0.2em 0;
font-size: 1.35em;
padding: 0;
}
h3 {
margin: 1em 0 -0.3em 0;
font-size: 1.2em;
}
div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a {
color: black!important;
}
h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {
display: none;
margin: 0 0 0 0.3em;
padding: 0 0.2em 0 0.2em;
color: #aaa!important;
}
h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
h5:hover a.anchor, h6:hover a.anchor {
display: inline;
}
h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
h5 a.anchor:hover, h6 a.anchor:hover {
color: #777;
background-color: #eee;
}
table {
border-collapse: collapse;
margin: 0 -0.5em 0 -0.5em;
}
table td, table th {
padding: 0.2em 0.5em 0.2em 0.5em;
}
div.footer {
background-color: #E3EFF1;
color: #86989B;
padding: 3px 8px 3px 0;
clear: both;
font-size: 0.8em;
text-align: right;
}
div.footer a {
color: #86989B;
text-decoration: underline;
}
div.pagination {
margin-top: 2em;
padding-top: 0.5em;
border-top: 1px solid black;
text-align: center;
}
div.sphinxsidebar ul.toc {
margin: 1em 0 1em 0;
padding: 0 0 0 0.5em;
list-style: none;
}
div.sphinxsidebar ul.toc li {
margin: 0.5em 0 0.5em 0;
font-size: 0.9em;
line-height: 130%;
}
div.sphinxsidebar ul.toc li p {
margin: 0;
padding: 0;
}
div.sphinxsidebar ul.toc ul {
margin: 0.2em 0 0.2em 0;
padding: 0 0 0 1.8em;
}
div.sphinxsidebar ul.toc ul li {
padding: 0;
}
div.admonition, div.warning {
font-size: 0.9em;
margin: 1em 0 0 0;
border: 1px solid #86989B;
background-color: #f7f7f7;
}
div.admonition p, div.warning p {
margin: 0.5em 1em 0.5em 1em;
padding: 0;
}
div.admonition pre, div.warning pre {
margin: 0.4em 1em 0.4em 1em;
}
div.admonition p.admonition-title,
div.warning p.admonition-title {
margin: 0;
padding: 0.1em 0 0.1em 0.5em;
color: white;
border-bottom: 1px solid #86989B;
font-weight: bold;
background-color: #AFC1C4;
}
div.warning {
border: 1px solid #940000;
}
div.warning p.admonition-title {
background-color: #CF0000;
border-bottom-color: #940000;
}
div.admonition ul, div.admonition ol,
div.warning ul, div.warning ol {
margin: 0.1em 0.5em 0.5em 3em;
padding: 0;
}
div.versioninfo {
margin: 1em 0 0 0;
border: 1px solid #ccc;
background-color: #DDEAF0;
padding: 8px;
line-height: 1.3em;
font-size: 0.9em;
}
a.headerlink {
color: #c60f0f!important;
font-size: 1em;
margin-left: 6px;
padding: 0 4px 0 4px;
text-decoration: none!important;
visibility: hidden;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink {
visibility: visible;
}
a.headerlink:hover {
background-color: #ccc;
color: white!important;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable dl, table.indextable dd {
margin-top: 0;
margin-bottom: 0;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
form.pfform {
margin: 10px 0 20px 0;
}
table.contentstable {
width: 90%;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
img.math {
vertical-align: center;
}
div.math {
text-align: center;
}
span.eqno {
float: right;
}
img.logo {
border: 0;
}

Просмотреть файл

@ -0,0 +1,19 @@
/**
* Sphinx Doc Design -- Sticky sidebar Overrides
*/
div.sphinxsidebar {
top: 30px;
left: 0px;
position: fixed;
margin: 0;
float: none;
}
div.related {
position: fixed;
}
div.documentwrapper {
margin-top: 30px;
}

Просмотреть файл

@ -0,0 +1,700 @@
/**
* Sphinx Doc Design -- traditional python.org style
*/
body {
color: #000;
margin: 0;
padding: 0;
}
/* :::: LAYOUT :::: */
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 230px 0 0;
}
div.body {
background-color: white;
padding: 0 20px 30px 20px;
}
div.sphinxsidebarwrapper {
border: 1px solid #99ccff;
padding: 10px;
margin: 10px 15px 10px 0;
}
div.sphinxsidebar {
float: right;
margin-left: -100%;
width: 230px;
}
div.clearer {
clear: both;
}
div.footer {
clear: both;
width: 100%;
background-color: #99ccff;
padding: 9px 0 9px 0;
text-align: center;
}
div.related {
background-color: #99ccff;
color: #333;
width: 100%;
height: 30px;
line-height: 30px;
border-bottom: 5px solid white;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
font-weight: bold;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* ::: SIDEBAR :::: */
div.sphinxsidebar h3 {
margin: 0;
}
div.sphinxsidebar h4 {
margin: 5px 0 0 0;
}
div.sphinxsidebar p.topless {
margin: 5px 10px 10px 10px;
}
div.sphinxsidebar ul {
margin: 10px;
margin-left: 15px;
padding: 0;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
/* :::: SEARCH :::: */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* :::: COMMON FORM STYLES :::: */
div.actions {
border-top: 1px solid #aaa;
background-color: #ddd;
margin: 10px 0 0 -20px;
padding: 5px 0 5px 20px;
}
form dl {
color: #333;
}
form dt {
clear: both;
float: left;
min-width: 110px;
margin-right: 10px;
padding-top: 2px;
}
input#homepage {
display: none;
}
div.error {
margin: 5px 20px 0 0;
padding: 5px;
border: 1px solid #d00;
/*border: 2px solid #05171e;
background-color: #092835;
color: white;*/
font-weight: bold;
}
/* :::: INLINE COMMENTS :::: */
div.inlinecommentswrapper {
float: right;
max-width: 40%;
}
div.commentmarker {
float: right;
background-image: url(style/comment.png);
background-repeat: no-repeat;
width: 25px;
height: 25px;
text-align: center;
padding-top: 3px;
}
div.nocommentmarker {
float: right;
background-image: url(style/nocomment.png);
background-repeat: no-repeat;
width: 25px;
height: 25px;
}
div.inlinecomments {
margin-left: 10px;
margin-bottom: 5px;
background-color: #eee;
border: 1px solid #ccc;
padding: 5px;
}
div.inlinecomment {
border-top: 1px solid #ccc;
padding-top: 5px;
margin-top: 5px;
}
.inlinecomments p {
margin: 5px 0 5px 0;
}
.inlinecomments .head {
font-weight: bold;
}
.inlinecomments .meta {
font-style: italic;
}
/* :::: COMMENTS :::: */
div#comments h3 {
border-top: 1px solid #aaa;
padding: 5px 20px 5px 20px;
margin: 20px -20px 20px -20px;
background-color: #ddd;
}
/*
div#comments {
background-color: #ccc;
margin: 40px -20px -30px -20px;
padding: 0 0 1px 0;
}
div#comments h4 {
margin: 30px 0 20px 0;
background-color: #aaa;
border-bottom: 1px solid #09232e;
color: #333;
}
div#comments form {
display: block;
margin: 0 0 0 20px;
}
div#comments textarea {
width: 98%;
height: 160px;
}
div#comments div.help {
margin: 20px 20px 10px 0;
background-color: #ccc;
color: #333;
}
div#comments div.help p {
margin: 0;
padding: 0 0 10px 0;
}
div#comments input, div#comments textarea {
font-family: 'Bitstream Vera Sans', 'Arial', sans-serif;
font-size: 13px;
color: black;
background-color: #aaa;
border: 1px solid #092835;
}
div#comments input[type="reset"],
div#comments input[type="submit"] {
cursor: pointer;
font-weight: bold;
padding: 2px;
margin: 5px 5px 5px 0;
background-color: #666;
color: white;
}
div#comments div.comment {
margin: 10px 10px 10px 20px;
padding: 10px;
border: 1px solid #0f3646;
background-color: #aaa;
color: #333;
}
div#comments div.comment p {
margin: 5px 0 5px 0;
}
div#comments div.comment p.meta {
font-style: italic;
color: #444;
text-align: right;
margin: -5px 0 -5px 0;
}
div#comments div.comment h4 {
margin: -10px -10px 5px -10px;
padding: 3px;
font-size: 15px;
background-color: #888;
color: white;
border: 0;
}
div#comments div.comment pre,
div#comments div.comment tt {
background-color: #ddd;
color: #111;
border: none;
}
div#comments div.comment a {
color: #fff;
text-decoration: underline;
}
div#comments div.comment blockquote {
margin: 10px;
padding: 10px;
border-left: 1px solid #0f3646;
/*border: 1px solid #0f3646;
background-color: #071c25;*/
}
div#comments em.important {
color: #d00;
font-weight: bold;
font-style: normal;
}*/
/* :::: SUGGEST CHANGES :::: */
div#suggest-changes-box input, div#suggest-changes-box textarea {
border: 1px solid #ccc;
background-color: white;
color: black;
}
div#suggest-changes-box textarea {
width: 99%;
height: 400px;
}
/* :::: PREVIEW :::: */
div.preview {
background-image: url(style/preview.png);
padding: 0 20px 20px 20px;
margin-bottom: 30px;
}
/* :::: INDEX PAGE :::: */
table.contentstable {
width: 90%;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.5em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
}
/* :::: GENINDEX STYLES :::: */
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable dl, table.indextable dd {
margin-top: 0;
margin-bottom: 0;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
/* :::: GLOBAL STYLES :::: */
p.subhead {
font-weight: bold;
margin-top: 20px;
}
a:link:active { color: #ff0000; }
a:link:hover { background-color: #bbeeff; }
a:visited:hover { background-color: #bbeeff; }
a:visited { color: #551a8b; }
a:link { color: #0000bb; }
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: avantgarde, sans-serif;
font-weight: bold;
}
div.body h1 { font-size: 180%; }
div.body h2 { font-size: 150%; }
div.body h3 { font-size: 120%; }
div.body h4 { font-size: 120%; }
a.headerlink,
a.headerlink,
a.headerlink,
a.headerlink,
a.headerlink,
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
visibility: hidden;
}
*:hover > a.headerlink,
*:hover > a.headerlink,
*:hover > a.headerlink,
*:hover > a.headerlink,
*:hover > a.headerlink,
*:hover > a.headerlink {
visibility: visible;
}
a.headerlink:hover,
a.headerlink:hover,
a.headerlink:hover,
a.headerlink:hover,
a.headerlink:hover,
a.headerlink:hover {
background-color: #c60f0f;
color: white;
}
div.body p, div.body dd, div.body li {
text-align: justify;
}
div.body td {
text-align: left;
}
ul.fakelist {
list-style: none;
margin: 10px 0 10px 20px;
padding: 0;
}
/* "Footnotes" heading */
p.rubric {
margin-top: 30px;
font-weight: bold;
}
/* "Topics" */
div.topic {
background-color: #eee;
border: 1px solid #ccc;
padding: 0 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* Admonitions */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
div.admonition dd {
margin-bottom: 10px;
}
div.admonition dl {
margin-bottom: 0;
}
div.admonition p {
display: inline;
}
div.seealso {
background-color: #ffc;
border: 1px solid #ff6;
}
div.warning {
background-color: #ffe4e4;
border: 1px solid #f66;
}
div.note {
background-color: #eee;
border: 1px solid #ccc;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
display: inline;
}
p.admonition-title:after {
content: ":";
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
table.docutils {
border: 0;
}
table.docutils td, table.docutils th {
padding: 0 8px 2px 0;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.field-list td, table.field-list th {
border: 0 !important;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
dl {
margin-bottom: 15px;
clear: both;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.refcount {
color: #060;
}
th {
text-align: left;
padding-right: 5px;
}
pre {
font-family: monospace;
padding: 5px;
color: #00008b;
border-left: none;
border-right: none;
}
tt {
font-family: monospace;
background-color: #ecf0f3;
padding: 0 1px 0 1px;
}
tt.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
tt.descclassname {
background-color: transparent;
}
tt.xref, a tt {
background-color: transparent;
font-weight: bold;
}
.footnote:target { background-color: #ffa }
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
background-color: transparent;
}
.optional {
font-size: 1.3em;
}
.versionmodified {
font-style: italic;
}
form.comment {
margin: 0;
padding: 10px 30px 10px 30px;
background-color: #eee;
}
form.comment h3 {
background-color: #326591;
color: white;
margin: -10px -30px 10px -30px;
padding: 5px;
font-size: 1.4em;
}
form.comment input,
form.comment textarea {
border: 1px solid #ccc;
padding: 2px;
font-family: sans-serif;
font-size: 13px;
}
form.comment input[type="text"] {
width: 240px;
}
form.comment textarea {
width: 100%;
height: 200px;
margin-bottom: 10px;
}
/* :::: PRINT :::: */
@media print {
div.documentwrapper {
width: 100%;
}
div.body {
margin: 0;
}
div.sphinxsidebar,
div.related,
div.footer,
div#comments div.new-comment-box,
#top-link {
display: none;
}
}

239
mail/test/resources/mozmill/docs/_build/html/genindex.html поставляемый Normal file
Просмотреть файл

@ -0,0 +1,239 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Index &mdash; mozmill v1.2.1a1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.2.1a1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="index" title="Index" href="" />
<link rel="search" title="Search" href="search.html" />
<link rel="top" title="mozmill v1.2.1a1 documentation" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="modindex.html" title="Global Module Index"
accesskey="M">modules</a> |</li>
<li><a href="index.html">mozmill v1.2.1a1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1 id="index">Index</h1>
<a href="#Symbols"><strong>Symbols</strong></a> | <a href="#B"><strong>B</strong></a> | <a href="#C"><strong>C</strong></a> | <a href="#E"><strong>E</strong></a> | <a href="#J"><strong>J</strong></a> | <a href="#M"><strong>M</strong></a> | <a href="#P"><strong>P</strong></a> | <a href="#R"><strong>R</strong></a> | <a href="#S"><strong>S</strong></a>
<hr />
<h2 id="Symbols">Symbols</h2>
<table width="100%" class="indextable"><tr><td width="33%" valign="top">
<dl>
<dt>--report &lt;uri&gt;</dt>
<dd><dl>
<dt><a href="index.html#cmdoption--report">command line option</a></dt>
</dl></dd>
<dt>--show-errors</dt>
<dd><dl>
<dt><a href="index.html#cmdoption--show-errors">command line option</a></dt>
</dl></dd>
<dt>--showall</dt>
<dd><dl>
<dt><a href="index.html#cmdoption--showall">command line option</a></dt>
</dl></dd>
<dt>-b &lt;binary&gt;, --binary &lt;binary&gt;</dt>
<dd><dl>
<dt><a href="index.html#cmdoption-b">command line option</a></dt>
</dl></dd>
<dt>-d &lt;defaultprofile&gt;</dt>
<dd><dl>
<dt><a href="index.html#cmdoption-d">command line option</a></dt>
</dl></dd>
<dt>-D, --debug</dt>
<dd><dl>
<dt><a href="index.html#cmdoption-D">command line option</a></dt>
</dl></dd>
<dt>-h, --help</dt>
<dd><dl>
<dt><a href="index.html#cmdoption-h">command line option</a></dt>
</dl></dd>
<dt>-l &lt;logfile&gt;, --logfile &lt;logfile&gt;</dt>
<dd><dl>
<dt><a href="index.html#cmdoption-l">command line option</a></dt>
</dl></dd></dl></td><td width="33%" valign="top"><dl>
<dt>-n, --no-new-profile</dt>
<dd><dl>
<dt><a href="index.html#cmdoption-n">command line option</a></dt>
</dl></dd>
<dt>-P &lt;port&gt;, --port &lt;port&gt;</dt>
<dd><dl>
<dt><a href="index.html#cmdoption-P">command line option</a></dt>
</dl></dd>
<dt>-p &lt;profile&gt;, --profile &lt;profile&gt;</dt>
<dd><dl>
<dt><a href="index.html#cmdoption-p">command line option</a></dt>
</dl></dd>
<dt>-s, --shell</dt>
<dd><dl>
<dt><a href="index.html#cmdoption-s">command line option</a></dt>
</dl></dd>
<dt>-t &lt;test&gt;, --test &lt;test&gt;</dt>
<dd><dl>
<dt><a href="index.html#cmdoption-t">command line option</a></dt>
</dl></dd>
<dt>-u, --usecode</dt>
<dd><dl>
<dt><a href="index.html#cmdoption-u">command line option</a></dt>
</dl></dd>
<dt>-w &lt;plugins&gt;, --plugins &lt;plugins&gt;</dt>
<dd><dl>
<dt><a href="index.html#cmdoption-w">command line option</a></dt>
</dl></dd>
</dl></td></tr></table>
<h2 id="B">B</h2>
<table width="100%" class="indextable"><tr><td width="33%" valign="top">
<dl>
<dt><a href="index.html#mozmill.MozMill.back_channel">back_channel (mozmill.MozMill attribute)</a></dt>
<dt><a href="index.html#mozmill.MozMill.bridge">bridge (mozmill.MozMill attribute)</a></dt></dl></td><td width="33%" valign="top"><dl>
</dl></td></tr></table>
<h2 id="C">C</h2>
<table width="100%" class="indextable"><tr><td width="33%" valign="top">
<dl>
<dt><a href="index.html#mozmill.CLI">CLI (class in mozmill)</a></dt>
<dt>command line option</dt>
<dd><dl>
<dt><a href="index.html#cmdoption--report">--report &lt;uri&gt;</a></dt>
<dt><a href="index.html#cmdoption--show-errors">--show-errors</a></dt>
<dt><a href="index.html#cmdoption--showall">--showall</a></dt>
<dt><a href="index.html#cmdoption-D">-D, --debug</a></dt>
<dt><a href="index.html#cmdoption-P">-P &lt;port&gt;, --port &lt;port&gt;</a></dt>
<dt><a href="index.html#cmdoption-b">-b &lt;binary&gt;, --binary &lt;binary&gt;</a></dt>
<dt><a href="index.html#cmdoption-d">-d &lt;defaultprofile&gt;</a></dt>
<dt><a href="index.html#cmdoption-h">-h, --help</a></dt>
<dt><a href="index.html#cmdoption-l">-l &lt;logfile&gt;, --logfile &lt;logfile&gt;</a></dt>
<dt><a href="index.html#cmdoption-n">-n, --no-new-profile</a></dt>
<dt><a href="index.html#cmdoption-p">-p &lt;profile&gt;, --profile &lt;profile&gt;</a></dt>
<dt><a href="index.html#cmdoption-s">-s, --shell</a></dt>
<dt><a href="index.html#cmdoption-t">-t &lt;test&gt;, --test &lt;test&gt;</a></dt>
<dt><a href="index.html#cmdoption-u">-u, --usecode</a></dt>
<dt><a href="index.html#cmdoption-w">-w &lt;plugins&gt;, --plugins &lt;plugins&gt;</a></dt>
</dl></dd></dl></td><td width="33%" valign="top"><dl>
</dl></td></tr></table>
<h2 id="E">E</h2>
<table width="100%" class="indextable"><tr><td width="33%" valign="top">
<dl>
<dt><a href="index.html#mozmill.MozMill.endRunner_listener">endRunner_listener() (mozmill.MozMill method)</a></dt>
<dt><a href="index.html#mozmill.MozMill.endTest_listener">endTest_listener() (mozmill.MozMill method)</a></dt></dl></td><td width="33%" valign="top"><dl>
</dl></td></tr></table>
<h2 id="J">J</h2>
<table width="100%" class="indextable"><tr><td width="33%" valign="top">
<dl>
<dt><a href="index.html#mozmill.MozMill.jsbridge_port">jsbridge_port (mozmill.MozMill attribute)</a></dt></dl></td><td width="33%" valign="top"><dl>
</dl></td></tr></table>
<h2 id="M">M</h2>
<table width="100%" class="indextable"><tr><td width="33%" valign="top">
<dl>
<dt><a href="index.html#mozmill.MozMill">MozMill (class in mozmill)</a></dt>
<dt><a href="index.html#module-mozmill">mozmill (module)</a></dt></dl></td><td width="33%" valign="top"><dl>
</dl></td></tr></table>
<h2 id="P">P</h2>
<table width="100%" class="indextable"><tr><td width="33%" valign="top">
<dl>
<dt><a href="index.html#mozmill.MozMill.profile">profile (mozmill.MozMill attribute)</a></dt>
<dt><a href="index.html#mozmill.CLI.profile_class">profile_class (mozmill.CLI attribute)</a></dt>
<dd><dl>
<dt><a href="index.html#mozmill.MozMill.profile_class">(mozmill.MozMill attribute)</a></dt>
</dl></dd></dl></td><td width="33%" valign="top"><dl>
</dl></td></tr></table>
<h2 id="R">R</h2>
<table width="100%" class="indextable"><tr><td width="33%" valign="top">
<dl>
<dt><a href="index.html#mozmill.MozMill.run_tests">run_tests() (mozmill.MozMill method)</a></dt>
<dt><a href="index.html#mozmill.MozMill.runner">runner (mozmill.MozMill attribute)</a></dt>
<dt><a href="index.html#mozmill.CLI.runner_class">runner_class (mozmill.CLI attribute)</a></dt>
<dd><dl>
<dt><a href="index.html#mozmill.MozMill.runner_class">(mozmill.MozMill attribute)</a></dt>
</dl></dd></dl></td><td width="33%" valign="top"><dl>
</dl></td></tr></table>
<h2 id="S">S</h2>
<table width="100%" class="indextable"><tr><td width="33%" valign="top">
<dl>
<dt><a href="index.html#mozmill.MozMill.start">start() (mozmill.MozMill method)</a></dt></dl></td><td width="33%" valign="top"><dl>
</dl></td></tr></table>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" /> <input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="modindex.html" title="Global Module Index"
accesskey="M">modules</a> |</li>
<li><a href="index.html">mozmill v1.2.1a1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Mikeal Rogers &lt;mikeal.rogers@gmail.com&gt;.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.5.1.
</div>
</body>
</html>

295
mail/test/resources/mozmill/docs/_build/html/index.html поставляемый Normal file
Просмотреть файл

@ -0,0 +1,295 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>mozmill &#8212; Full automation of XULRunner applications. &mdash; mozmill v1.2.1a1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.2.1a1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="top" title="mozmill v1.2.1a1 documentation" href="" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="modindex.html" title="Global Module Index"
accesskey="M">modules</a> |</li>
<li><a href="">mozmill v1.2.1a1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="module-mozmill">
<h1><tt class="xref docutils literal"><span class="pre">mozmill</span></tt> &#8212; Full automation of XULRunner applications.<a class="headerlink" href="#module-mozmill" title="Permalink to this headline"></a></h1>
<div class="section" id="command-line-usage">
<h2>Command Line Usage<a class="headerlink" href="#command-line-usage" title="Permalink to this headline"></a></h2>
<p>The mozmill command line is versatile and includes a fair amount of debugging options. Even though all these options are available mozmill should run by default without any arguments and find your locally installed Firefox and run with mozmill.</p>
<p>In most modes, ctrl-c will shut down Firefox and exit out of the mozmill Python side as well.</p>
<div class="highlight-none"><div class="highlight"><pre>$ mozmill
</pre></div>
</div>
<dl class="cmdoption">
<dt id="cmdoption-h">
<tt class="descname">-h</tt><tt class="descclassname"></tt><tt class="descclassname">, </tt><tt class="descname">--help</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-h" title="Permalink to this definition"></a></dt>
<dd>Show help message.</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption-b">
<tt class="descname">-b</tt><tt class="descclassname"> &lt;binary&gt;</tt><tt class="descclassname">, </tt><tt class="descname">--binary</tt><tt class="descclassname"> &lt;binary&gt;</tt><a class="headerlink" href="#cmdoption-b" title="Permalink to this definition"></a></dt>
<dd><p>Specify application binary location.</p>
<p>Default <a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.Profile"><tt class="xref docutils literal"><span class="pre">mozrunner.Profile</span></tt></a> and <a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.Runner"><tt class="xref docutils literal"><span class="pre">mozrunner.Runner</span></tt></a> are still
<a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.FirefoxProfile"><tt class="xref docutils literal"><span class="pre">mozrunner.FirefoxProfile</span></tt></a> and <a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.FirefoxRunner"><tt class="xref docutils literal"><span class="pre">mozrunner.FirefoxRunner</span></tt></a>. You can
change this by creating your own command line utility by subclassing <a title="mozmill.CLI" class="reference internal" href="#mozmill.CLI"><tt class="xref docutils literal"><span class="pre">CLI</span></tt></a></p>
</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption-d">
<tt class="descname">-d</tt><tt class="descclassname"> &lt;defaultprofile&gt;</tt><a class="headerlink" href="#cmdoption-d" title="Permalink to this definition"></a></dt>
<dd>Specify the path to the default <strong>clean</strong> profile used to create new profiles.</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption-n">
<tt class="descname">-n</tt><tt class="descclassname"></tt><tt class="descclassname">, </tt><tt class="descname">--no-new-profile</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-n" title="Permalink to this definition"></a></dt>
<dd>Do not create a new fresh profile.</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption-p">
<tt class="descname">-p</tt><tt class="descclassname"> &lt;profile&gt;</tt><tt class="descclassname">, </tt><tt class="descname">--profile</tt><tt class="descclassname"> &lt;profile&gt;</tt><a class="headerlink" href="#cmdoption-p" title="Permalink to this definition"></a></dt>
<dd>Specifies a profile to use. Must be used with &#8211;no-new-profile.</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption-w">
<tt class="descname">-w</tt><tt class="descclassname"> &lt;plugins&gt;</tt><tt class="descclassname">, </tt><tt class="descname">--plugins</tt><tt class="descclassname"> &lt;plugins&gt;</tt><a class="headerlink" href="#cmdoption-w" title="Permalink to this definition"></a></dt>
<dd><p>Comma seperated list of additional paths to plugins to install.</p>
<p>Plugins can be either .xpi zip compressed extensions or deflated extension directories.</p>
</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption-l">
<tt class="descname">-l</tt><tt class="descclassname"> &lt;logfile&gt;</tt><tt class="descclassname">, </tt><tt class="descname">--logfile</tt><tt class="descclassname"> &lt;logfile&gt;</tt><a class="headerlink" href="#cmdoption-l" title="Permalink to this definition"></a></dt>
<dd>Log all events to <em>logfile</em>.</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption--report">
<tt class="descname">--report</tt><tt class="descclassname"> &lt;uri&gt;</tt><a class="headerlink" href="#cmdoption--report" title="Permalink to this definition"></a></dt>
<dd><p><em>Currently in development.</em></p>
<p>POST results to given brasstacks results server at <em>uri</em>.</p>
</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption-t">
<tt class="descname">-t</tt><tt class="descclassname"> &lt;test&gt;</tt><tt class="descclassname">, </tt><tt class="descname">--test</tt><tt class="descclassname"> &lt;test&gt;</tt><a class="headerlink" href="#cmdoption-t" title="Permalink to this definition"></a></dt>
<dd>Run <em>test</em>. Can be either single test file or directory of tests.</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption--showall">
<tt class="descname">--showall</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption--showall" title="Permalink to this definition"></a></dt>
<dd>Show all test output.</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption-D">
<tt class="descname">-D</tt><tt class="descclassname"></tt><tt class="descclassname">, </tt><tt class="descname">--debug</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-D" title="Permalink to this definition"></a></dt>
<dd>Install debugging extensions and run with -jsconole</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption--show-errors">
<tt class="descname">--show-errors</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption--show-errors" title="Permalink to this definition"></a></dt>
<dd>Print all logger errors to the console. When running tests only test failures and skipped
tests are printed, this option print all other errors.</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption-s">
<tt class="descname">-s</tt><tt class="descclassname"></tt><tt class="descclassname">, </tt><tt class="descname">--shell</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-s" title="Permalink to this definition"></a></dt>
<dd>Starts a Python shell for debugging.</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption-u">
<tt class="descname">-u</tt><tt class="descclassname"></tt><tt class="descclassname">, </tt><tt class="descname">--usecode</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-u" title="Permalink to this definition"></a></dt>
<dd>By default &#8211;shell mode will use iPython if install and fall back to using the code module.
This option forces the use of the code module instead of iPython even when installed.</dd></dl>
<dl class="cmdoption">
<dt id="cmdoption-P">
<tt class="descname">-P</tt><tt class="descclassname"> &lt;port&gt;</tt><tt class="descclassname">, </tt><tt class="descname">--port</tt><tt class="descclassname"> &lt;port&gt;</tt><a class="headerlink" href="#cmdoption-P" title="Permalink to this definition"></a></dt>
<dd>Specify port for jsbridge.</dd></dl>
</div>
<div class="section" id="command-line-class">
<h2>Command Line Class<a class="headerlink" href="#command-line-class" title="Permalink to this headline"></a></h2>
<dl class="class">
<dt id="mozmill.CLI">
<!--[mozmill.CLI]-->class <tt class="descclassname">mozmill.</tt><tt class="descname">CLI</tt><a class="headerlink" href="#mozmill.CLI" title="Permalink to this definition"></a></dt>
<dd><p>Inherits from <a title="(in jsbridge v2.0a1)" class="reference external" href="http://jsbridge.googlecode.com/svn/trunk/docs/_build/html/index.html#jsbridge.CLI"><tt class="xref docutils literal"><span class="pre">jsbridge.CLI</span></tt></a> which inherits from <a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.CLI"><tt class="xref docutils literal"><span class="pre">mozrunner.CLI</span></tt></a>.</p>
<p>All the heavy lifting is handled by jsbridge and mozrunner. If you are subclassing
this in order to creat a new command line interface be sure to call <a title="(in Python v2.7)" class="reference external" href="http://docs.python.org/dev/library/functions.html#super"><tt class="xref docutils literal"><span class="pre">super()</span></tt></a> on all
related methods.</p>
<dl class="attribute">
<dt id="mozmill.CLI.runner_class">
<!--[mozmill.CLI.runner_class]--><tt class="descname">runner_class</tt><a class="headerlink" href="#mozmill.CLI.runner_class" title="Permalink to this definition"></a></dt>
<dd>Default runner class. Should be subclass of <a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.Runner"><tt class="xref docutils literal"><span class="pre">mozrunner.Runner</span></tt></a>.
Defaults to <a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.FirefoxRunner"><tt class="xref docutils literal"><span class="pre">mozrunner.FirefoxRunner</span></tt></a>.</dd></dl>
<dl class="attribute">
<dt id="mozmill.CLI.profile_class">
<!--[mozmill.CLI.profile_class]--><tt class="descname">profile_class</tt><a class="headerlink" href="#mozmill.CLI.profile_class" title="Permalink to this definition"></a></dt>
<dd>Default profile class. Should be subclass of <tt class="xref docutils literal"><span class="pre">mozruner.Profile</span></tt>.
Defaults to <a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.FirefoxProfile"><tt class="xref docutils literal"><span class="pre">mozrunner.FirefoxProfile</span></tt></a>.</dd></dl>
</dd></dl>
</div>
<div class="section" id="running-mozmill-from-python">
<h2>Running MozMill from Python<a class="headerlink" href="#running-mozmill-from-python" title="Permalink to this headline"></a></h2>
<dl class="class">
<dt id="mozmill.MozMill">
<!--[mozmill.MozMill]-->class <tt class="descclassname">mozmill.</tt><tt class="descname">MozMill</tt><big>(</big><span class="optional">[</span><em>runner_class</em><span class="optional">[</span>, <em>profile_class</em><span class="optional">[</span>, <em>jsbridge_port</em><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#mozmill.MozMill" title="Permalink to this definition"></a></dt>
<dd><p>Manages an instance of Firefox w/ jsbridge and provides facilities for running tests and
keeping track of results with callback methods.</p>
<p>Default <em>runner_class</em> is <a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.FirefoxRunner"><tt class="xref docutils literal"><span class="pre">mozrunner.FirefoxRunner</span></tt></a>. Value should be a subclass of
<a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.Runner"><tt class="xref docutils literal"><span class="pre">mozrunner.Runner</span></tt></a>.</p>
<p>Default <em>profile_class</em> is <a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.FirefoxProfile"><tt class="xref docutils literal"><span class="pre">mozrunner.FirefoxProfile</span></tt></a>. Value should be a subclass of
<a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.Profile"><tt class="xref docutils literal"><span class="pre">mozrunner.Profile</span></tt></a>.</p>
<p>Default <em>jsbridge_port</em> is <cite>24242</cite>.</p>
<dl class="attribute">
<dt id="mozmill.MozMill.runner_class">
<!--[mozmill.MozMill.runner_class]--><tt class="descname">runner_class</tt><a class="headerlink" href="#mozmill.MozMill.runner_class" title="Permalink to this definition"></a></dt>
<dd>Set during initialization to subclass of <a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.Runner"><tt class="xref docutils literal"><span class="pre">mozrunner.Runner</span></tt></a>.</dd></dl>
<dl class="attribute">
<dt id="mozmill.MozMill.profile_class">
<!--[mozmill.MozMill.profile_class]--><tt class="descname">profile_class</tt><a class="headerlink" href="#mozmill.MozMill.profile_class" title="Permalink to this definition"></a></dt>
<dd>Set during initialization to subclass of <a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.Profile"><tt class="xref docutils literal"><span class="pre">mozrunner.Profile</span></tt></a>.</dd></dl>
<dl class="attribute">
<dt id="mozmill.MozMill.jsbridge_port">
<!--[mozmill.MozMill.jsbridge_port]--><tt class="descname">jsbridge_port</tt><a class="headerlink" href="#mozmill.MozMill.jsbridge_port" title="Permalink to this definition"></a></dt>
<dd>Set during initialization to <a title="(in Python v2.7)" class="reference external" href="http://docs.python.org/dev/library/numbers.html#numbers.Integral"><tt class="xref docutils literal"><span class="pre">numbers.Integral</span></tt></a>.</dd></dl>
<dl class="method">
<dt id="mozmill.MozMill.start">
<!--[mozmill.MozMill.start]--><tt class="descname">start</tt><big>(</big><span class="optional">[</span><em>profile</em><span class="optional">[</span>, <em>runner</em><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#mozmill.MozMill.start" title="Permalink to this definition"></a></dt>
<dd><p>Start mozrunner and jsbridge pre-requisites.</p>
<p><em>profile</em> should be an instance of a <cite>mozrunner.Profile</cite> subclass. If one is not passed
an instance of <cite>self.profile_class</cite> is created. <cite>self.profile</cite> will be set to this
value.</p>
<p><em>runner</em> should be an instance of a <cite>mozrunner.Runner</cite> subclass. If one is not passed an
instance of <a title="mozmill.MozMill.runner_class" class="reference internal" href="#mozmill.MozMill.runner_class"><tt class="xref docutils literal"><span class="pre">runner_class</span></tt></a> will be created. <a title="mozmill.MozMill.runner" class="reference internal" href="#mozmill.MozMill.runner"><tt class="xref docutils literal"><span class="pre">runner</span></tt></a> will be set to this value.</p>
<p>This method will also run <cite>runner.start()</cite> and <tt class="xref docutils literal"><span class="pre">mozrunner.wait_and_create_network()</span></tt>
and sets <a title="mozmill.MozMill.back_channel" class="reference internal" href="#mozmill.MozMill.back_channel"><tt class="xref docutils literal"><span class="pre">back_channel</span></tt></a> and <a title="mozmill.MozMill.bridge" class="reference internal" href="#mozmill.MozMill.bridge"><tt class="xref docutils literal"><span class="pre">bridge</span></tt></a> to instances of
<a title="(in jsbridge v2.0a1)" class="reference external" href="http://jsbridge.googlecode.com/svn/trunk/docs/_build/html/index.html#jsbridge.BackChannel"><tt class="xref docutils literal"><span class="pre">jsbridge.BackChannel</span></tt></a> and <a title="(in jsbridge v2.0a1)" class="reference external" href="http://jsbridge.googlecode.com/svn/trunk/docs/_build/html/index.html#jsbridge.Bridge"><tt class="xref docutils literal"><span class="pre">jsbridge.Bridge</span></tt></a> respectively.</p>
</dd></dl>
<dl class="attribute">
<dt id="mozmill.MozMill.profile">
<!--[mozmill.MozMill.profile]--><tt class="descname">profile</tt><a class="headerlink" href="#mozmill.MozMill.profile" title="Permalink to this definition"></a></dt>
<dd>Set during <a title="mozmill.MozMill.start" class="reference internal" href="#mozmill.MozMill.start"><tt class="xref docutils literal"><span class="pre">start()</span></tt></a> to subclass of <a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.Profile"><tt class="xref docutils literal"><span class="pre">mozrunner.Profile</span></tt></a>.</dd></dl>
<dl class="attribute">
<dt id="mozmill.MozMill.runner">
<!--[mozmill.MozMill.runner]--><tt class="descname">runner</tt><a class="headerlink" href="#mozmill.MozMill.runner" title="Permalink to this definition"></a></dt>
<dd>Set during <a title="mozmill.MozMill.start" class="reference internal" href="#mozmill.MozMill.start"><tt class="xref docutils literal"><span class="pre">start()</span></tt></a> to subclass of <a title="(in mozrunner v2.0a1)" class="reference external" href="http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/index.html#mozrunner.Runner"><tt class="xref docutils literal"><span class="pre">mozrunner.Runner</span></tt></a>.</dd></dl>
<dl class="attribute">
<dt id="mozmill.MozMill.back_channel">
<!--[mozmill.MozMill.back_channel]--><tt class="descname">back_channel</tt><a class="headerlink" href="#mozmill.MozMill.back_channel" title="Permalink to this definition"></a></dt>
<dd>Set during <a title="mozmill.MozMill.start" class="reference internal" href="#mozmill.MozMill.start"><tt class="xref docutils literal"><span class="pre">start()</span></tt></a> to subclass of <a title="(in jsbridge v2.0a1)" class="reference external" href="http://jsbridge.googlecode.com/svn/trunk/docs/_build/html/index.html#jsbridge.BackChannel"><tt class="xref docutils literal"><span class="pre">jsbridge.BackChannel</span></tt></a>.</dd></dl>
<dl class="attribute">
<dt id="mozmill.MozMill.bridge">
<!--[mozmill.MozMill.bridge]--><tt class="descname">bridge</tt><a class="headerlink" href="#mozmill.MozMill.bridge" title="Permalink to this definition"></a></dt>
<dd>Set during <a title="mozmill.MozMill.start" class="reference internal" href="#mozmill.MozMill.start"><tt class="xref docutils literal"><span class="pre">start()</span></tt></a> to subclass of <a title="(in jsbridge v2.0a1)" class="reference external" href="http://jsbridge.googlecode.com/svn/trunk/docs/_build/html/index.html#jsbridge.Bridge"><tt class="xref docutils literal"><span class="pre">jsbridge.Bridge</span></tt></a></dd></dl>
<dl class="method">
<dt id="mozmill.MozMill.run_tests">
<!--[mozmill.MozMill.run_tests]--><tt class="descname">run_tests</tt><big>(</big><em>test</em><span class="optional">[</span>, <em>report</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#mozmill.MozMill.run_tests" title="Permalink to this definition"></a></dt>
<dd><p>Run <em>test</em> in live Firefox using <a title="mozmill.MozMill.bridge" class="reference internal" href="#mozmill.MozMill.bridge"><tt class="xref docutils literal"><span class="pre">bridge</span></tt></a>.</p>
<p>Adds local listeners <a title="mozmill.MozMill.endTest_listener" class="reference internal" href="#mozmill.MozMill.endTest_listener"><tt class="xref docutils literal"><span class="pre">endTest_listener()</span></tt></a> and <a title="mozmill.MozMill.endRunner_listener" class="reference internal" href="#mozmill.MozMill.endRunner_listener"><tt class="xref docutils literal"><span class="pre">endRunner_listener()</span></tt></a> to
<cite>&#8220;endTest&#8221;</cite> and <cite>&#8220;endRunner&#8221;</cite> events using <a title="(in jsbridge v2.0a1)" class="reference external" href="http://jsbridge.googlecode.com/svn/trunk/docs/_build/html/index.html#jsbridge.BackChannel.add_listener"><tt class="xref docutils literal"><span class="pre">jsbridge.BackChannel.add_listener()</span></tt></a> of
<a title="mozmill.MozMill.back_channel" class="reference internal" href="#mozmill.MozMill.back_channel"><tt class="xref docutils literal"><span class="pre">back_channel</span></tt></a>.</p>
<p>When tests are done the results are posted to a results server at <em>report</em> if passed.</p>
</dd></dl>
<dl class="method">
<dt id="mozmill.MozMill.endTest_listener">
<!--[mozmill.MozMill.endTest_listener]--><tt class="descname">endTest_listener</tt><big>(</big><em>test</em><big>)</big><a class="headerlink" href="#mozmill.MozMill.endTest_listener" title="Permalink to this definition"></a></dt>
<dd>When a test is finished the test object will be passed to this callback.</dd></dl>
<dl class="method">
<dt id="mozmill.MozMill.endRunner_listener">
<!--[mozmill.MozMill.endRunner_listener]--><tt class="descname">endRunner_listener</tt><big>(</big><em>obj</em><big>)</big><a class="headerlink" href="#mozmill.MozMill.endRunner_listener" title="Permalink to this definition"></a></dt>
<dd>When all the tests are done running this callback will be fired.</dd></dl>
</dd></dl>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href=""><tt class="docutils literal"><span class="pre">mozmill</span></tt> &#8212; Full automation of XULRunner applications.</a><ul>
<li><a class="reference external" href="#command-line-usage">Command Line Usage</a></li>
<li><a class="reference external" href="#command-line-class">Command Line Class</a></li>
<li><a class="reference external" href="#running-mozmill-from-python">Running MozMill from Python</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/index.txt">Show Source</a></li>
</ul>
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" /> <input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="modindex.html" title="Global Module Index"
accesskey="M">modules</a> |</li>
<li><a href="">mozmill v1.2.1a1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Mikeal Rogers &lt;mikeal.rogers@gmail.com&gt;.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.5.1.
</div>
</body>
</html>

97
mail/test/resources/mozmill/docs/_build/html/modindex.html поставляемый Normal file
Просмотреть файл

@ -0,0 +1,97 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Global Module Index &mdash; mozmill v1.2.1a1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.2.1a1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="top" title="mozmill v1.2.1a1 documentation" href="index.html" />
<script type="text/javascript">
DOCUMENTATION_OPTIONS.COLLAPSE_MODINDEX = true;
</script>
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="" title="Global Module Index"
accesskey="M">modules</a> |</li>
<li><a href="index.html">mozmill v1.2.1a1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1 id="global-module-index">Global Module Index</h1>
<a href="#cap-M"><strong>M</strong></a>
<hr/>
<table width="100%" class="indextable" cellspacing="0" cellpadding="2"><tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
<tr class="cap"><td></td><td><a name="cap-M"><strong>M</strong></a></td><td></td></tr><tr>
<td></td>
<td>
<a href="index.html#module-mozmill"><tt class="xref">mozmill</tt></a></td><td>
<em>Full automation of XULRunner applications.</em></td></tr>
</table>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" /> <input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="" title="Global Module Index"
accesskey="M">modules</a> |</li>
<li><a href="index.html">mozmill v1.2.1a1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Mikeal Rogers &lt;mikeal.rogers@gmail.com&gt;.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.5.1.
</div>
</body>
</html>

19
mail/test/resources/mozmill/docs/_build/html/objects.inv поставляемый Normal file
Просмотреть файл

@ -0,0 +1,19 @@
# Sphinx inventory version 1
# Project: mozmill
# Version: 1.2.1a1
mozmill mod index.html
mozmill.MozMill.start method index.html
mozmill.CLI class index.html
mozmill.MozMill class index.html
mozmill.MozMill.endTest_listener method index.html
mozmill.MozMill.runner_class attribute index.html
mozmill.MozMill.back_channel attribute index.html
mozmill.CLI.profile_class attribute index.html
mozmill.MozMill.jsbridge_port attribute index.html
mozmill.MozMill.profile_class attribute index.html
mozmill.CLI.runner_class attribute index.html
mozmill.MozMill.profile attribute index.html
mozmill.MozMill.bridge attribute index.html
mozmill.MozMill.endRunner_listener method index.html
mozmill.MozMill.runner attribute index.html
mozmill.MozMill.run_tests method index.html

89
mail/test/resources/mozmill/docs/_build/html/search.html поставляемый Normal file
Просмотреть файл

@ -0,0 +1,89 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Search &mdash; mozmill v1.2.1a1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.2.1a1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/searchtools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="" />
<link rel="top" title="mozmill v1.2.1a1 documentation" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="modindex.html" title="Global Module Index"
accesskey="M">modules</a> |</li>
<li><a href="index.html">mozmill v1.2.1a1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1 id="search-documentation">Search</h1>
<p>
From here you can search these documents. Enter your search
words into the box below and click "search". Note that the search
function will automatically search for all of the words. Pages
containing fewer words won't appear in the result list.
</p>
<form action="" method="get">
<input type="text" name="q" value="" />
<input type="submit" value="search" />
<span id="search-progress" style="padding-left: 10px"></span>
</form>
<div id="search-results">
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="modindex.html" title="Global Module Index"
accesskey="M">modules</a> |</li>
<li><a href="index.html">mozmill v1.2.1a1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Mikeal Rogers &lt;mikeal.rogers@gmail.com&gt;.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.5.1.
</div>
<script type="text/javascript" src="searchindex.js"></script>
</body>
</html>

1
mail/test/resources/mozmill/docs/_build/html/searchindex.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
Search.setIndex({desctypes:{"0":"method","1":"class","2":"attribute"},terms:{all:0,code:0,help:0,show:0,skip:0,fall:0,tcp:[],jsbridge_port:0,mozmil:0,endrunn:0,comma:0,jsbridg:0,still:0,find:0,jsconol:0,current:0,onli:0,locat:0,cli:0,binari:0,should:0,add:0,logger:0,local:0,sure:0,applic:0,firefoxrunn:0,python:0,initi:0,autom:0,util:0,failur:0,report:0,run_test:0,requir:[],docutil:0,list:0,server:0,provid:0,either:0,debug:0,output:0,side:0,"int":[],set:0,fair:0,seper:0,back:0,defaultprofil:0,mozrun:0,result:0,mozrunn:0,pass:0,event:0,out:0,even:0,xulrunn:0,back_channel:0,subclass:0,profil:0,exit:0,print:0,"new":0,method:0,attribut:[],shut:0,full:0,run:0,usag:0,given:0,extens:0,ipython:0,path:0,post:0,"super":0,valu:0,addit:0,deflat:0,obj:0,brasstack:0,plugin:0,forc:0,manag:0,amount:0,instanc:0,chang:0,own:0,firefox:0,modul:0,number:0,down:0,done:0,instal:0,facil:0,your:0,xpi:0,span:0,log:0,zip:0,messag:0,usecod:0,avail:0,start:0,live:0,interfac:0,includ:0,handl:0,call:0,default_profil:[],type:[],listen:0,wait_and_create_network:0,from:0,shell:0,consol:0,option:0,fire:0,relat:0,specifi:0,ani:0,lift:0,line:0,must:0,heavi:0,"default":0,endtest:0,directori:0,bridg:0,can:0,error:0,pre:0,firefoxprofil:0,add_listen:0,creat:0,ctrl:0,runner:0,dure:0,argument:0,mode:0,showal:0,liter:0,versatil:0,file:0,requisit:0,keep:0,integr:0,develop:0,self:0,when:0,backchannel:0,port:0,also:0,other:0,"__init__":[],which:0,test:0,instead:0,you:0,endrunner_listen:0,singl:0,finish:0,clean:0,though:0,track:0,object:0,compress:0,endtest_listen:0,most:0,logfil:0,profile_class:0,"class":0,url:[],runner_class:0,well:0,uri:0,inherit:0,callback:0,without:0,command:0,thi:0,fresh:0,order:0,respect:0},titles:["<tt class=\"docutils literal\"><span class=\"pre\">mozmill</span></tt> &#8212; Full automation of XULRunner applications."],modules:{mozmill:0},descrefs:{"mozmill.CLI":{runner_class:[0,2],profile_class:[0,2]},"mozmill.MozMill":{profile:[0,2],bridge:[0,2],endRunner_listener:[0,0],endTest_listener:[0,0],jsbridge_port:[0,2],runner:[0,2],back_channel:[0,2],runner_class:[0,2],run_tests:[0,0],start:[0,0],profile_class:[0,2]},mozmill:{CLI:[0,1],MozMill:[0,1]}},filenames:["index"]})

Просмотреть файл

@ -0,0 +1,194 @@
# -*- coding: utf-8 -*-
#
# mozmill documentation build configuration file, created by
# sphinx-quickstart on Mon Mar 16 14:30:49 2009.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# The contents of this file are pickled, so don't put values in the namespace
# that aren't pickleable (module imports are okay, they're removed automatically).
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If your extensions are in another directory, add it here. If the directory
# is relative to the documentation root, use os.path.abspath to make it
# absolute, like shown here.
#sys.path.append(os.path.abspath('.'))
# General configuration
# ---------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ["sphinx.ext.intersphinx"]
intersphinx_mapping = {'http://docs.python.org/dev': None,
'http://mozrunner.googlecode.com/svn/trunk/docs/_build/html/': None,
'http://jsbridge.googlecode.com/svn/trunk/docs/_build/html/': None}
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'mozmill'
copyright = u'2009, Mikeal Rogers <mikeal.rogers@gmail.com>'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '1.2.1a1'
# The full version, including alpha/beta/rc tags.
release = '1.2.1a1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
#unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# Options for HTML output
# -----------------------
# The style sheet to use for HTML and HTML Help pages. A file of that name
# must exist either in Sphinx' static/ path, or in one of the custom paths
# given in html_static_path.
html_style = 'default.css'
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_use_modindex = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, the reST sources are included in the HTML build as _sources/<name>.
#html_copy_source = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'mozmilldoc'
# Options for LaTeX output
# ------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, document class [howto/manual]).
latex_documents = [
('index', 'mozmill.tex', ur'mozmill Documentation',
ur'Mikeal Rogers <mikeal.rogers@gmail.com>', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True

Просмотреть файл

@ -0,0 +1,188 @@
:mod:`mozmill` --- Full automation of XULRunner applications.
=============================================================
.. module:: mozmill
:synopsis: Full automation of XULRunner applications.
.. moduleauthor:: Mikeal Rogers <mikeal.rogers@gmail.com>
.. sectionauthor:: Mikeal Rogers <mikeal.rogers@gmail.com>
Command Line Usage
------------------
The mozmill command line is versatile and includes a fair amount of debugging options. Even though all these options are available mozmill should run by default without any arguments and find your locally installed Firefox and run with mozmill.
In most modes, ctrl-c will shut down Firefox and exit out of the mozmill Python side as well.
.. code-block:: none
$ mozmill
.. cmdoption:: -h, --help
Show help message.
.. cmdoption:: -b <binary>, --binary <binary>
Specify application binary location.
Default :class:`mozrunner.Profile` and :class:`mozrunner.Runner` are still
:class:`mozrunner.FirefoxProfile` and :class:`mozrunner.FirefoxRunner`. You can
change this by creating your own command line utility by subclassing :class:`CLI`
.. cmdoption:: -d <defaultprofile>
Specify the path to the default **clean** profile used to create new profiles.
.. cmdoption:: -n, --no-new-profile
Do not create a new fresh profile.
.. cmdoption:: -p <profile>, --profile <profile>
Specifies a profile to use. Must be used with --no-new-profile.
.. cmdoption:: -w <plugins>, --plugins <plugins>
Comma seperated list of additional paths to plugins to install.
Plugins can be either .xpi zip compressed extensions or deflated extension directories.
.. cmdoption:: -l <logfile>, --logfile <logfile>
Log all events to *logfile*.
.. cmdoption:: --report <uri>
*Currently in development.*
POST results to given brasstacks results server at *uri*.
.. cmdoption:: -t <test>, --test <test>
Run *test*. Can be either single test file or directory of tests.
.. cmdoption:: --showall
Show all test output.
.. cmdoption:: -D, --debug
Install debugging extensions and run with -jsconole
.. cmdoption:: --show-errors
Print all logger errors to the console. When running tests only test failures and skipped
tests are printed, this option print all other errors.
.. cmdoption:: -s, --shell
Starts a Python shell for debugging.
.. cmdoption:: -u, --usecode
By default --shell mode will use iPython if install and fall back to using the code module.
This option forces the use of the code module instead of iPython even when installed.
.. cmdoption:: -P <port>, --port <port>
Specify port for jsbridge.
Command Line Class
------------------
.. class:: CLI
Inherits from :class:`jsbridge.CLI` which inherits from :class:`mozrunner.CLI`.
All the heavy lifting is handled by jsbridge and mozrunner. If you are subclassing
this in order to creat a new command line interface be sure to call :func:`super` on all
related methods.
.. attribute:: runner_class
Default runner class. Should be subclass of :class:`mozrunner.Runner`.
Defaults to :class:`mozrunner.FirefoxRunner`.
.. attribute:: profile_class
Default profile class. Should be subclass of :class:`mozruner.Profile`.
Defaults to :class:`mozrunner.FirefoxProfile`.
Running MozMill from Python
---------------------------
.. class:: MozMill([runner_class[, profile_class[, jsbridge_port]]])
Manages an instance of Firefox w/ jsbridge and provides facilities for running tests and
keeping track of results with callback methods.
Default *runner_class* is :class:`mozrunner.FirefoxRunner`. Value should be a subclass of
:class:`mozrunner.Runner`.
Default *profile_class* is :class:`mozrunner.FirefoxProfile`. Value should be a subclass of
:class:`mozrunner.Profile`.
Default *jsbridge_port* is `24242`.
.. attribute:: runner_class
Set during initialization to subclass of :class:`mozrunner.Runner`.
.. attribute:: profile_class
Set during initialization to subclass of :class:`mozrunner.Profile`.
.. attribute:: jsbridge_port
Set during initialization to :class:`numbers.Integral`.
.. method:: start([profile[, runner]])
Start mozrunner and jsbridge pre-requisites.
*profile* should be an instance of a `mozrunner.Profile` subclass. If one is not passed
an instance of `self.profile_class` is created. `self.profile` will be set to this
value.
*runner* should be an instance of a `mozrunner.Runner` subclass. If one is not passed an
instance of :attr:`runner_class` will be created. :attr:`runner` will be set to this value.
This method will also run `runner.start()` and :func:`mozrunner.wait_and_create_network`
and sets :attr:`back_channel` and :attr:`bridge` to instances of
:class:`jsbridge.BackChannel` and :class:`jsbridge.Bridge` respectively.
.. attribute:: profile
Set during :meth:`start` to subclass of :class:`mozrunner.Profile`.
.. attribute:: runner
Set during :meth:`start` to subclass of :class:`mozrunner.Runner`.
.. attribute:: back_channel
Set during :meth:`start` to subclass of :class:`jsbridge.BackChannel`.
.. attribute:: bridge
Set during :meth:`start` to subclass of :class:`jsbridge.Bridge`
.. method:: run_tests(test[, report])
Run *test* in live Firefox using :attr:`bridge`.
Adds local listeners :meth:`endTest_listener` and :meth:`endRunner_listener` to
`"endTest"` and `"endRunner"` events using :meth:`jsbridge.BackChannel.add_listener` of
:attr:`back_channel`.
When tests are done the results are posted to a results server at *report* if passed.
.. method:: endTest_listener(test)
When a test is finished the test object will be passed to this callback.
.. method:: endRunner_listener(obj)
When all the tests are done running this callback will be fired.

Просмотреть файл

@ -0,0 +1,845 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Corporation Code.
#
# The Initial Developer of the Original Code is
# Mikeal Rogers.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Mikeal Rogers <mikeal.rogers@gmail.com>
# Henrik Skupin <hskupin@mozilla.com>
# Clint Talbert <ctalbert@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
import copy
import httplib
import imp
import os
import socket
import sys
import traceback
import urllib
import urlparse
from datetime import datetime, timedelta
import manifestparser
try:
import json
except:
import simplejson as json
# setup logger
import logging
logger = logging.getLogger('mozmill')
import jsbridge
from jsbridge.network import JSBridgeDisconnectError
import mozrunner
from time import sleep
basedir = os.path.abspath(os.path.dirname(__file__))
extension_path = os.path.join(basedir, 'extension')
mozmillModuleJs = "Components.utils.import('resource://mozmill/modules/mozmill.js')"
class LoggerListener(object):
cases = {
'mozmill.pass': lambda string: logger.info('Step Pass: ' + string),
'mozmill.fail': lambda string: logger.error('Test Failure: ' + string),
'mozmill.skip': lambda string: logger.info('Test Skipped: ' + string)
}
class default(object):
def __init__(self, eName): self.eName = eName
def __call__(self, string):
if string:
logger.debug(self.eName + ' | ' + string)
else:
logger.debug(self.eName)
def __call__(self, eName, obj):
if obj == {}:
string = ''
else:
string = json.dumps(obj)
if eName not in self.cases:
self.cases[eName] = self.default(eName)
self.cases[eName](string)
class TestsFailedException(Exception):
"""exception to be raised when the tests fail"""
# XXX unused
class MozMill(object):
"""
MozMill is a one-shot test runner You should use MozMill as follows:
m = MozMill(...)
m.start(...)
m.run_tests()
m.stop()
You should *NOT* vary from this order of execution. If you have need to
run different sets of tests, create a new instantiation of MozMill
"""
report_type = 'mozmill-test'
def __init__(self,
runner_class=mozrunner.FirefoxRunner,
profile_class=mozrunner.FirefoxProfile,
jsbridge_port=24242,
jsbridge_timeout=60):
"""
- runner_class : which mozrunner class to use
- profile_class : which class to use to generate application profiles
- jsbridge_port : port jsbridge uses to connect to to the application
- jsbridge_timeout : how long to go without jsbridge communication
"""
self.runner_class = runner_class
self.profile_class = profile_class
self.jsbridge_port = jsbridge_port
self.jsbridge_timeout = jsbridge_timeout
self.passes = [] ; self.fails = [] ; self.skipped = []
self.alltests = []
self.persisted = {}
self.endRunnerCalled = False
self.shutdownModes = enum('default', 'user_shutdown', 'user_restart')
self.currentShutdownMode = self.shutdownModes.default
self.userShutdownEnabled = False
self.tests = []
# test time
self.starttime = self.endtime = None
# setup event listeners
self.global_listeners = []
self.listeners = []
self.add_listener(self.persist_listener, eventType="mozmill.persist")
self.add_listener(self.endTest_listener, eventType='mozmill.endTest')
self.add_listener(self.endRunner_listener, eventType='mozmill.endRunner')
self.add_listener(self.startTest_listener, eventType='mozmill.setTest')
self.add_listener(self.userShutdown_listener, eventType='mozmill.userShutdown')
# disable the crashreporter
os.environ['MOZ_CRASHREPORTER_NO_REPORT'] = '1'
def add_listener(self, callback, **kwargs):
self.listeners.append((callback, kwargs,))
def add_global_listener(self, callback):
self.global_listeners.append(callback)
def persist_listener(self, obj):
self.persisted = obj
def fire_python_callback(self, method, arg, python_callbacks_module):
meth = getattr(python_callbacks_module, method)
try:
meth(arg)
except Exception, e:
self.endTest_listener({"name":method, "failed":1,
"python_exception_type":e.__class__.__name__,
"python_exception_string":str(e),
"python_traceback":traceback.format_exc(),
"filename":python_callbacks_module.__file__})
return False
self.endTest_listener({"name":method, "failed":0,
"filename":python_callbacks_module.__file__})
return True
def firePythonCallback_listener(self, obj):
callback_file = "%s_callbacks.py" % os.path.splitext(obj['filename'])[0]
if os.path.isfile(callback_file):
python_callbacks_module = imp.load_source('callbacks', callback_file)
else:
raise Exception("No valid callback file")
self.fire_python_callback(obj['method'], obj['arg'], python_callbacks_module)
def create_network(self):
# get the bridge and the back-channel
self.back_channel, self.bridge = jsbridge.wait_and_create_network("127.0.0.1",
self.jsbridge_port)
# set a timeout on jsbridge actions in order to ensure termination
self.back_channel.timeout = self.bridge.timeout = self.jsbridge_timeout
# Assign listeners to the back channel
for listener in self.listeners:
self.back_channel.add_listener(listener[0], **listener[1])
for global_listener in self.global_listeners:
self.back_channel.add_global_listener(global_listener)
def start(self, profile=None, runner=None):
if not profile:
profile = self.profile_class(addons=[jsbridge.extension_path, extension_path])
self.profile = profile
if not runner:
runner = self.runner_class(profile=self.profile,
cmdargs=["-jsbridge", str(self.jsbridge_port)])
self.add_listener(self.firePythonCallback_listener, eventType='mozmill.firePythonCallback')
self.runner = runner
self.endRunnerCalled = False
self.runner.start()
self.create_network()
self.appinfo = self.get_appinfo(self.bridge)
# set the starttime for the tests
# XXX assumes run_tests will be called soon after (currently true)
self.starttime = datetime.utcnow()
def find_tests(self, tests, files=None):
if files is None:
files = []
for test in tests:
# tests have to be absolute paths to be loaded from JS
test = os.path.abspath(test)
if os.path.isdir(test):
directory = test
for f in os.listdir(directory):
if not f.startswith('test'):
continue
path = os.path.join(directory, f)
if os.path.isdir(path):
self.find_tests([path], files)
else:
if f.endswith('.js') and path not in files:
files.append(path)
else:
files.append(test)
return files
def run_tests(self, tests, sleeptime=0):
"""
run test files or directories
- test : test files or directories to run
- sleeptime : initial time to sleep [s] (not sure why the default is 4)
"""
tests = self.find_tests(tests)
self.tests.extend(tests)
frame = jsbridge.JSObject(self.bridge,
"Components.utils.import('resource://mozmill/modules/frame.js')")
sleep(sleeptime)
# transfer persisted data
frame.persisted = self.persisted
# run the test files
for test in tests:
frame.runTestFile(test)
# Give a second for any callbacks to finish.
sleep(1)
def startTest_listener(self, test):
self.current_test = test
print "TEST-START | %s | %s" % (test['filename'], test['name'])
def endTest_listener(self, test):
self.alltests.append(test)
if test.get('skipped', False):
print "WARNING | %s | (SKIP) %s" % (test['name'], test.get('skipped_reason', ''))
self.skipped.append(test)
elif test['failed'] > 0:
print "TEST-UNEXPECTED-FAIL | %s | %s" % (test['filename'], test['name'])
self.fails.append(test)
else:
print "TEST-PASS | %s | %s" % (test['filename'], test['name'])
self.passes.append(test)
def endRunner_listener(self, obj):
self.endRunnerCalled = True
def userShutdown_listener(self, obj):
if obj in [self.shutdownModes.default, self.shutdownModes.user_restart, self.shutdownModes.user_shutdown]:
self.currentShutdownMode = obj
self.userShutdownEnabled = not self.userShutdownEnabled
### methods for reporting
def printStats(self):
"""print pass/failed/skipped statistics"""
print "INFO Passed: %d" % len(self.passes)
print "INFO Failed: %d" % len(self.fails)
print "INFO Skipped: %d" % len(self.skipped)
def report_disconnect(self):
test = self.current_test
test['passes'] = []
test['fails'] = [{
'exception' : {
'message': 'Disconnect Error: Application unexpectedly closed'
}
}]
test['passed'] = 0
test['failed'] = 1
self.alltests.append(test)
self.fails.append(test)
def get_appinfo(self, bridge):
""" Collect application specific information """
mozmill = jsbridge.JSObject(bridge, mozmillModuleJs)
appInfo = mozmill.appInfo
results = {'application_id': str(appInfo.ID),
'application_name': str(appInfo.name),
'application_version': str(appInfo.version),
'application_locale': str(mozmill.locale),
'platform_buildid': str(appInfo.platformBuildID),
'platform_version': str(appInfo.platformVersion),
}
return results
def get_platform_information(self):
""" Retrieves platform information for test reports. Parts of that code
come from the dirtyharry application:
http://github.com/harthur/dirtyharry/blob/master/dirtyutils.py """
import platform
import re
(system, node, release, version, machine, processor) = platform.uname()
(bits, linkage) = platform.architecture()
service_pack = ''
if system in ["Microsoft", "Windows"]:
# There is a Python bug on Windows to determine platform values
# http://bugs.python.org/issue7860
if "PROCESSOR_ARCHITEW6432" in os.environ:
processor = os.environ.get("PROCESSOR_ARCHITEW6432", processor)
else:
processor = os.environ.get('PROCESSOR_ARCHITECTURE', processor)
system = os.environ.get("OS", system).replace('_', ' ')
service_pack = os.sys.getwindowsversion()[4]
elif system == "Linux":
(distro, version, codename) = platform.dist()
version = distro + " " + version
if not processor:
processor = machine
elif system == "Darwin":
system = "Mac"
(release, versioninfo, machine) = platform.mac_ver()
version = "OS X " + release
if processor in ["i386", "i686"]:
if bits == "32bit":
processor = "x86"
elif bits == "64bit":
processor = "x86_64"
elif processor == "AMD64":
bits = "64bit"
processor = "x86_64"
elif processor == "Power Macintosh":
processor = "ppc"
bits = re.search('(\d+)bit', bits).group(1)
platform = {'hostname': node,
'system': system,
'version': version,
'service_pack': service_pack,
'processor': processor,
'bits': bits
}
return platform
def get_report(self):
"""get the report results"""
format = "%Y-%m-%dT%H:%M:%SZ"
assert self.tests, 'no tests have been run!'
assert self.starttime, 'starttime not set; have you started the tests?'
if not self.endtime:
self.endtime = datetime.utcnow()
report = {'report_type': self.report_type,
'time_start': self.starttime.strftime(format),
'time_end': self.endtime.strftime(format),
'time_upload': 'n/a',
'tests_passed': len(self.passes),
'tests_failed': len(self.fails),
'tests_skipped': len(self.skipped),
'results': self.alltests
}
report.update(self.appinfo)
report.update(self.runner.get_repositoryInfo())
report['system_info'] = self.get_platform_information()
return report
def send_report(self, results, report_url):
""" Send a report of the results to a CouchdB instance or a file. """
# report to file or stdout
f = None
if report_url == 'stdout': # stdout
f = sys.stdout
if report_url.startswith('file://'):
filename = report_url.split('file://', 1)[1]
try:
f = file(filename, 'w')
except Exception, e:
print "Printing results to '%s' failed (%s)." % (filename, e)
return
if f:
print >> f, json.dumps(results)
return
# report to CouchDB
try:
# Set the upload time of the report
now = datetime.utcnow()
results['time_upload'] = now.strftime("%Y-%m-%dT%H:%M:%SZ")
# Parse URL fragments and send data
url_fragments = urlparse.urlparse(report_url)
connection = httplib.HTTPConnection(url_fragments.netloc)
connection.request("POST", url_fragments.path, json.dumps(results),
{"Content-type": "application/json"})
# Get response which contains the id of the new document
response = connection.getresponse()
data = json.loads(response.read())
connection.close()
# Check if the report has been created
if not data['ok']:
print "Creating report document failed (%s)" % data
return data
# Print document location to the console and return
print "Report document created at '%s%s'" % (report_url, data['id'])
return data
except Exception, e:
print "Sending results to '%s' failed (%s)." % (report_url, e)
def report(self, report_url):
"""print statistics and send the JSON report"""
self.printStats()
if report_url:
results = self.get_report()
return self.send_report(results, report_url)
### methods for shutting down and cleanup
def stop_runner(self, timeout=30, close_bridge=False, hard=False):
sleep(1)
try:
mozmill = jsbridge.JSObject(self.bridge, mozmillModuleJs)
mozmill.cleanQuit()
except (socket.error, JSBridgeDisconnectError):
pass
except:
self.runner.cleanup()
raise
if not close_bridge:
starttime = datetime.utcnow()
self.runner.wait(timeout=timeout)
endtime = datetime.utcnow()
if ( endtime - starttime ) > timedelta(seconds=timeout):
try:
self.runner.stop()
except:
pass
self.runner.wait()
else: # TODO: unify this logic with the above better
if hard:
self.runner.cleanup()
return
# XXX this call won't actually finish in the specified timeout time
self.runner.wait(timeout=timeout)
self.back_channel.close()
self.bridge.close()
x = 0
while x < timeout:
if self.endRunnerCalled:
break
sleep(1)
x += 1
else:
print "WARNING | endRunner was never called. There must have been a failure in the framework."
self.runner.cleanup()
sys.exit(1)
def stop(self, fatal=False):
"""cleanup"""
# stop the runner
self.stop_runner(timeout=10, close_bridge=True, hard=fatal)
# cleanup the profile if you need to
if self.runner is not None:
self.runner.cleanup()
class MozMillRestart(MozMill):
report_type = 'mozmill-restart-test'
def __init__(self, *args, **kwargs):
MozMill.__init__(self, *args, **kwargs)
self.python_callbacks = []
def add_listener(self, callback, **kwargs):
self.listeners.append((callback, kwargs,))
def add_global_listener(self, callback):
self.global_listeners.append(callback)
def start(self, runner=None, profile=None):
if not profile:
profile = self.profile_class(addons=[jsbridge.extension_path, extension_path])
self.profile = profile
if not runner:
runner = self.runner_class(profile=self.profile,
cmdargs=["-jsbridge", str(self.jsbridge_port)])
self.runner = runner
self.endRunnerCalled = False
self.add_listener(self.firePythonCallback_listener, eventType='mozmill.firePythonCallback')
# set the starttime for the tests
# XXX assumes run_tests will be called soon after (currently true)
self.starttime = datetime.utcnow()
def firePythonCallback_listener(self, obj):
if obj['fire_now']:
self.fire_python_callback(obj['method'], obj['arg'], self.python_callbacks_module)
else:
self.python_callbacks.append(obj)
def start_runner(self):
# if user_restart we don't need to start the browser back up
if self.currentShutdownMode != self.shutdownModes.user_restart:
self.runner.start()
self.create_network()
self.appinfo = self.get_appinfo(self.bridge)
frame = jsbridge.JSObject(self.bridge,
"Components.utils.import('resource://mozmill/modules/frame.js')")
return frame
def run_dir(self, test_dir, sleeptime=0):
"""run a directory of restart tests resetting the profile per directory"""
# TODO: document this behaviour!
if os.path.isfile(os.path.join(test_dir, 'testPre.js')):
pre_test = os.path.join(test_dir, 'testPre.js')
post_test = os.path.join(test_dir, 'testPost.js')
if not os.path.exists(pre_test) or not os.path.exists(post_test):
print "Skipping "+test_dir+" does not contain both pre and post test."
return
tests = [pre_test, post_test]
else:
if not os.path.isfile(os.path.join(test_dir, 'test1.js')):
print "Skipping "+test_dir+" does not contain any known test file names"
return
tests = []
counter = 1
while os.path.isfile(os.path.join(test_dir, "test"+str(counter)+".js")):
tests.append(os.path.join(test_dir, "test"+str(counter)+".js"))
counter += 1
self.add_listener(self.endRunner_listener, eventType='mozmill.endRunner')
if os.path.isfile(os.path.join(test_dir, 'callbacks.py')):
self.python_callbacks_module = imp.load_source('callbacks', os.path.join(test_dir, 'callbacks.py'))
for test in tests:
frame = self.start_runner()
self.currentShutdownMode = self.shutdownModes.default
self.endRunnerCalled = False
sleep(sleeptime)
frame.persisted = self.persisted
try:
frame.runTestFile(test)
while not self.endRunnerCalled:
sleep(.25)
self.currentShutdownMode = self.shutdownModes.default
self.stop_runner()
sleep(2) # Give mozrunner some time to shutdown the browser
except JSBridgeDisconnectError:
if not self.userShutdownEnabled:
raise JSBridgeDisconnectError()
self.userShutdownEnabled = False
for callback in self.python_callbacks:
self.fire_python_callback(callback['method'], callback['arg'], self.python_callbacks_module)
self.python_callbacks = []
self.python_callbacks_module = None
# Reset the profile.
profile = self.runner.profile
profile.cleanup()
if profile.create_new:
profile.profile = profile.create_new_profile(self.runner.binary)
for addon in profile.addons:
profile.install_addon(addon)
if jsbridge.extension_path not in profile.addons:
profile.install_addon(jsbridge.extension_path)
if extension_path not in profile.addons:
profile.install_addon(extension_path)
profile.set_preferences(profile.preferences)
def find_tests(self, tests):
files = []
# make sure these are all directories
not_dir = [ i for i in tests
if not os.path.isdir(i) ]
if not_dir:
raise IOError('Restart tests must be directories (%s)' % ', '.join(not_dir))
for test_dir in tests:
# tests have to be absolute paths, for some reason
test_dir = os.path.abspath(test_dir)
# XXX this allows for only one sub-level of test directories
# is this a spec or a side-effect?
# If the former, it should be documented
test_dirs = [os.path.join(test_dir, d)
for d in os.listdir(test_dir)
if d.startswith('test') and os.path.isdir(os.path.join(test_dir, d))]
if len(test_dirs):
files.extend(test_dirs)
else:
files.append(test_dir)
return files
def run_tests(self, tests, sleeptime=0):
test_dirs = self.find_tests(tests)
self.tests.extend(test_dirs)
for test_dir in test_dirs:
self.run_dir(test_dir, sleeptime)
# cleanup the profile
self.runner.cleanup()
# Give a second for any pending callbacks to finish
sleep(1)
def stop(self, fatal=False):
"""MozmillRestart doesn't need to do cleanup as this is already done per directory"""
# XXX this is a one-off to fix bug 581733
# really, the entire shutdown sequence should be reconsidered and
# made more robust.
# See https://bugzilla.mozilla.org/show_bug.cgi?id=581733#c20
# This will *NOT* work with all edge cases and it shouldn't be
# expected that adding on more kills() for each edge case will ever
# be able to fix a systematic issue by patching holes
if fatal:
self.runner.cleanup()
class CLI(jsbridge.CLI):
mozmill_class = MozMill
module = "mozmill"
parser_options = copy.copy(jsbridge.CLI.parser_options)
parser_options[("-t", "--test",)] = dict(dest="test", action='append', default=[],
help="Run test")
parser_options[("-l", "--logfile",)] = dict(dest="logfile", default=None,
help="Log all events to file.")
parser_options[("--show-errors",)] = dict(dest="showerrors", default=False,
action="store_true",
help="Print logger errors to the console.")
parser_options[("--report",)] = dict(dest="report", default=False,
help="Report the results. Requires url to results server. Use 'stdout' for stdout.")
parser_options[("--show-all",)] = dict(dest="showall", default=False, action="store_true",
help="Show all test output.")
parser_options[("--timeout",)] = dict(dest="timeout", type="float",
default=60.,
help="seconds before harness timeout if no communication is taking place")
parser_options[("-m", "--manifest")] = dict(dest='manifests', action='append',
help='test manifest .ini file')
parser_options[("--app-arg",)] = dict(dest='appArgs', action='append', default=[],
help='provides an argument to the test application')
def __init__(self, *args, **kwargs):
jsbridge.CLI.__init__(self, *args, **kwargs)
self.mozmill = self.mozmill_class(runner_class=mozrunner.FirefoxRunner,
profile_class=mozrunner.FirefoxProfile,
jsbridge_port=int(self.options.port),
jsbridge_timeout=self.options.timeout,
)
self.tests = []
# read tests from manifests
if self.options.manifests:
manifest_parser = manifestparser.TestManifest(manifests=self.options.manifests)
self.tests.extend(manifest_parser.test_paths())
# expand user directory for individual tests
for test in self.options.test:
test = os.path.expanduser(test)
self.tests.append(test)
# check existence for the tests
missing = [ test for test in self.tests
if not os.path.exists(test) ]
if missing:
raise IOError("Not a valid test file/directory: %s" % ', '.join(["'%s'" % test for test in missing]))
# setup log formatting
self.mozmill.add_global_listener(LoggerListener())
log_options = { 'format': "%(levelname)s | %(message)s",
'level': logging.CRITICAL }
if self.options.showerrors:
log_options['level'] = logging.ERROR
if self.options.logfile:
log_options['filename'] = self.options.logfile
log_options['filemode'] = 'w'
log_options['level'] = logging.DEBUG
if self.options.test and self.options.showall:
log_options['level'] = logging.DEBUG
logging.basicConfig(**log_options)
def get_profile(self, *args, **kwargs):
profile = jsbridge.CLI.get_profile(self, *args, **kwargs)
profile.install_addon(extension_path)
return profile
def run(self):
# create a Mozrunner
runner = self.create_runner()
runner.cmdargs.extend(self.options.appArgs)
# make sure the application starts in the foreground
if '-foreground' not in runner.cmdargs:
runner.cmdargs.append('-foreground')
try:
self.mozmill.start(runner=runner, profile=runner.profile)
except:
runner.cleanup()
raise
if self.tests:
# run the tests
disconnected = False
try:
self.mozmill.run_tests(self.tests)
except JSBridgeDisconnectError:
disconnected = True
if not self.mozmill.userShutdownEnabled:
self.mozmill.report_disconnect()
print 'TEST-UNEXPECTED-FAIL | Disconnect Error: Application unexpectedly closed'
runner.cleanup()
except:
runner.cleanup()
raise
# shutdown the test harness
self.mozmill.stop(fatal=disconnected)
# print statistics and send the JSON report
self.mozmill.report(self.options.report)
if self.mozmill.fails or disconnected:
sys.exit(1)
else:
if self.options.shell:
self.start_shell(runner)
else:
try:
if not hasattr(runner, 'process_handler'):
runner.start()
runner.wait()
except KeyboardInterrupt:
runner.stop()
if self.mozmill.runner is not None:
self.mozmill.runner.cleanup()
class RestartCLI(CLI):
mozmill_class = MozMillRestart
class ThunderbirdCLI(CLI):
profile_class = mozrunner.ThunderbirdProfile
runner_class = mozrunner.ThunderbirdRunner
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
return type('Enum', (), enums)
def cli():
CLI().run()
def tbird_cli():
ThunderbirdCLI().run()
def restart_cli():
RestartCLI().run()

Просмотреть файл

@ -0,0 +1,60 @@
<?xml version="1.0"?>
<!--
build.xml adapted from Shawn Wilsher's rtse
(http://shawnwilsher.com/extensions/rtse/)
-->
<project name="mozmill" default="createxpi">
<tstamp>
<format property="build.number" pattern="yyyyMMdd" offset="-1" unit="hour"/>
</tstamp>
<property name="build.version" value="1.1.${build.number}"/>
<target name="createxpi" depends="createjar">
<delete file="mozmill.xpi"/>
<zip destfile="mozmill.xpi">
<zipfileset dir="" includes="chrome/mozmill.jar"/>
<zipfileset dir="" includes="chrome/mozmill-locale.jar"/>
<zipfileset dir="" includes="chrome/mozmill-skin.jar"/>
<zipfileset dir="" includes="install.rdf"/>
<zipfileset dir="" includes="readme.txt"/>
<zipfileset dir="" includes="chrome-jar.manifest" fullpath="chrome.manifest"/>
<zipfileset dir="" includes="defaults/**" excludes="**SVN"/>
<zipfileset dir="" includes="resource/**" excludes="**SVN"/>
</zip>
<antcall target="cleanup"/>
</target>
<target name="createjar">
<mkdir dir="chrome"/>
<zip destfile="chrome/mozmill.jar">
<zipfileset dir="" includes="content/**" excludes="**SVN"/>
</zip>
<zip destfile="chrome/mozmill-locale.jar">
<zipfileset dir="" includes="locale/**" excludes="**SVN"/>
</zip>
<zip destfile="chrome/mozmill-skin.jar">
<zipfileset dir="" includes="skin/**" excludes="**SVN"/>
</zip>
</target>
<target name="unpacked">
<delete file="mozmill.xpi"/>
<zip destfile="mozmill.xpi">
<zipfileset dir="" includes="content/**" excludes="**SVN"/>
<zipfileset dir="" includes="locale/**" excludes="**SVN"/>
<zipfileset dir="" includes="skin/**" excludes="**SVN"/>
<zipfileset dir="" includes="install.rdf"/>
<zipfileset dir="" includes="readme.txt"/>
<zipfileset dir="" includes="chrome.manifest" fullpath="chrome.manifest"/>
<zipfileset dir="" includes="defaults/**" excludes="**SVN"/>
<zipfileset dir="" includes="resource/**" excludes="**SVN"/>
</zip>
</target>
<target name="cleanup">
<!-- Delete the chrome directory, any other cleanup actions go here -->
<delete dir="chrome"/>
</target>
</project>

Просмотреть файл

@ -0,0 +1,12 @@
resource mozmill resource/
content mozmill jar:chrome/mozmill.jar!/content/
locale mozmill en-US jar:chrome/mozmill-locale.jar!/locale/en-US/
skin mozmill classic/1.0 jar:chrome/mozmill-skin.jar!/skin/
overlay chrome://browser/content/browser.xul chrome://mozmill/content/overlay.xul
overlay chrome://messenger/content/mailWindowOverlay.xul chrome://mozmill/content/overlay_tb.xul
overlay chrome://calendar/content/calendar.xul chrome://mozmill/content/overlay.xul
overlay chrome://navigator/content/navigatorOverlay.xul chrome://mozmill/content/overlay_tb.xul
overlay windowtype:Songbird:Main chrome://mozmill/content/overlay.xul
style chrome://global/content/customizeToolbar.xul chrome://mozmill/skin/overlay.css

Просмотреть файл

@ -0,0 +1,15 @@
resource mozmill resource/
content mozmill content/
overlay chrome://browser/content/browser.xul chrome://mozmill/content/overlay.xul
overlay chrome://messenger/content/mailWindowOverlay.xul chrome://mozmill/content/overlay_tb.xul
overlay chrome://calendar/content/calendar.xul chrome://mozmill/content/overlay.xul
overlay chrome://sunbird/content/calendar.xul chrome://mozmill/content/overlay.xul
overlay chrome://navigator/content/navigatorOverlay.xul chrome://mozmill/content/overlay_tb.xul
overlay windowtype:Songbird:Main chrome://mozmill/content/overlay.xul
locale mozmill en-US locale/en-US/
skin mozmill classic/1.0 skin/
style chrome://global/content/customizeToolbar.xul chrome://mozmill/skin/overlay.css

Просмотреть файл

@ -0,0 +1,40 @@
/* Adds tooltip support to the Mozmill window. Taken from browser.js in Firefox */
function fillTooltip(tipElement) {
var retVal = false;
if (tipElement.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul")
return retVal;
const XLinkNS = "http://www.w3.org/1999/xlink";
var titleText = null;
var XLinkTitleText = null;
var direction = tipElement.ownerDocument.dir;
while (!titleText && !XLinkTitleText && tipElement) {
if (tipElement.nodeType == Node.ELEMENT_NODE) {
titleText = tipElement.getAttribute("title");
XLinkTitleText = tipElement.getAttributeNS(XLinkNS, "title");
var defView = tipElement.ownerDocument.defaultView;
// Work around bug 350679: "Tooltips can be fired in documents with no view"
if (!defView)
return retVal;
direction = defView.getComputedStyle(tipElement, "")
.getPropertyValue("direction");
}
tipElement = tipElement.parentNode;
}
var tipNode = document.getElementById("mozmill-tooltip");
tipNode.style.direction = direction;
for each (var t in [titleText, XLinkTitleText]) {
if (t && /\S/.test(t)) {
// Per HTML 4.01 6.2 (CDATA section), literal CRs and tabs should be
// replaced with spaces, and LFs should be removed entirely
t = t.replace(/[\r\t]/g, ' ');
t = t.replace(/\n/g, '');
tipNode.setAttribute("label", t);
retVal = true;
}
}
return retVal;
}

Просмотреть файл

@ -0,0 +1,114 @@
/* Styles for jQuery menu widget
Author: Maggie Wachs, maggie@filamentgroup.com
Date: September 2008
*/
/* REQUIRED STYLES - the menus will only render correctly with these rules */
.fg-menu-container { position: absolute; top:0; left:-999px; padding: .4em; overflow: hidden; }
.fg-menu-container.fg-menu-flyout { overflow: visible; }
.fg-menu, .fg-menu ul { list-style-type:none; padding: 0; margin:0; }
.fg-menu { position:relative; }
.fg-menu-flyout .fg-menu { position:static; }
.fg-menu ul { position:absolute; top:0; }
.fg-menu ul ul { top:-1px; }
.fg-menu-container.fg-menu-ipod .fg-menu-content,
.fg-menu-container.fg-menu-ipod .fg-menu-content ul { background: none !important; }
.fg-menu.fg-menu-scroll,
.fg-menu ul.fg-menu-scroll { overflow: scroll; overflow-x: hidden; }
.fg-menu li { clear:both; float:left; width:100%; margin: 0; padding:0; border: 0; }
.fg-menu li li { font-size:1em; } /* inner li font size must be reset so that they don't blow up */
.fg-menu-flyout ul ul { padding: .4em; }
.fg-menu-flyout li { position:relative; }
.fg-menu-scroll { overflow: scroll; overflow-x: hidden; }
.fg-menu-breadcrumb { margin: 0; padding: 0; }
.fg-menu-footer { margin-top: .4em; padding: .4em; }
.fg-menu-header { margin-bottom: .4em; padding: .4em; }
.fg-menu-breadcrumb li { float: left; list-style: none; margin: 0; padding: 0 .2em; font-size: .9em; opacity: .7; }
.fg-menu-breadcrumb li.fg-menu-prev-list,
.fg-menu-breadcrumb li.fg-menu-current-crumb { clear: left; float: none; opacity: 1; }
.fg-menu-breadcrumb li.fg-menu-current-crumb { padding-top: .2em; }
.fg-menu-breadcrumb a,
.fg-menu-breadcrumb span { float: left; }
.fg-menu-footer a:link,
.fg-menu-footer a:visited { float:left; width:100%; text-decoration: none; }
.fg-menu-footer a:hover,
.fg-menu-footer a:active { }
.fg-menu-footer a span { float:left; cursor: pointer; }
.fg-menu-breadcrumb .fg-menu-prev-list a:link,
.fg-menu-breadcrumb .fg-menu-prev-list a:visited,
.fg-menu-breadcrumb .fg-menu-prev-list a:hover,
.fg-menu-breadcrumb .fg-menu-prev-list a:active { background-image: none; text-decoration:none; }
.fg-menu-breadcrumb .fg-menu-prev-list a { float: left; padding-right: .4em; }
.fg-menu-breadcrumb .fg-menu-prev-list a .ui-icon { float: left; }
.fg-menu-breadcrumb .fg-menu-current-crumb a:link,
.fg-menu-breadcrumb .fg-menu-current-crumb a:visited,
.fg-menu-breadcrumb .fg-menu-current-crumb a:hover,
.fg-menu-breadcrumb .fg-menu-current-crumb a:active { display:block; background-image:none; font-size:1.3em; text-decoration:none; }
/* REQUIRED LINK STYLES: links are "display:block" by default; if the menu options are split into
selectable node links and 'next' links, the script floats the node links left and floats the 'next' links to the right */
.fg-menu a:link,
.fg-menu a:visited,
.fg-menu a:hover,
.fg-menu a:active { float:left; width:92%; padding:.3em 3%; text-decoration:none; outline: 0 !important; }
.fg-menu a { border: 1px dashed transparent; }
.fg-menu a.ui-state-default:link,
.fg-menu a.ui-state-default:visited,
.fg-menu a.ui-state-default:hover,
.fg-menu a.ui-state-default:active,
.fg-menu a.ui-state-hover:link,
.fg-menu a.ui-state-hover:visited,
.fg-menu a.ui-state-hover:hover,
.fg-menu a.ui-state-hover:active,
.fg-menu a.ui-state-active:link,
.fg-menu a.ui-state-active:visited,
.fg-menu a.ui-state-active:hover,
.fg-menu a.ui-state-active:active { border-style: solid; font-weight: normal; }
.fg-menu a span { display:block; cursor:pointer; }
/* SUGGESTED STYLES - for use with jQuery UI Themeroller CSS */
.fg-menu-indicator span { float:left; }
.fg-menu-indicator span.ui-icon { float:right; }
.fg-menu-content.ui-widget-content,
.fg-menu-content ul.ui-widget-content { border:0; }
/* ICONS AND DIVIDERS */
.fg-menu.fg-menu-has-icons a:link,
.fg-menu.fg-menu-has-icons a:visited,
.fg-menu.fg-menu-has-icons a:hover,
.fg-menu.fg-menu-has-icons a:active { padding-left:20px; }
.fg-menu .horizontal-divider hr, .fg-menu .horizontal-divider span { padding:0; margin:5px .6em; }
.fg-menu .horizontal-divider hr { border:0; height:1px; }
.fg-menu .horizontal-divider span { font-size:.9em; text-transform: uppercase; padding-left:.2em; }

Просмотреть файл

@ -0,0 +1,108 @@
body{ font: 11px Corbel, Verdana, Helvetica, arial, sans-serif; background-color: window; margin: 0; padding: 0;}
#tabs { position: relative;}
.tab {
font-size: 12px;
}
.bespin {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
#fileMenuButton {
float: left;
cursor: pointer;
}
#openTabs {
position: relative;
top: -4px;
margin-left: 16%;
}
#editor-tab-select {
min-width: 70px;
padding-left: 8px;
padding-right: 10px;
}
.menu {
font-size: 12px;
padding-top: 3px;
padding-left: 10px;
padding-right: 10px;
padding-bottom: 3px;
background-color: #f5f5f5;
border: 1px solid #ddd;
-moz-border-radius: 1px;
}
.menu:hover {
background-color: #ccc;
}
.menu:active {
background-color: #bbb;
}
.menuitem { cursor: pointer; padding-top: 2px; font-size: 12px; padding-bottom: 2px;}
.menuitem a { width: 100%}
.menuitem:hover { background-color: #E7E7E7;}
#dxContainer {margin-top: 16px; height: 160px;}
#inspectOptions {margin-right: 10px;}
#outClear {margin-left: 20px;}
#elementStr { margin-bottom: 8px;}
#recordToggle { margin-left: 4px;}
#outClear { position: relative; top: -3px;}
#shellInput {
width: 99%;
height: 50px;
}
#shellOutput {
overflow: auto;
width: 99%;
border: 1px solid #aaa;
}
.log,
.logger,
.pass,
.fail,
.test {
width:98%;
}
.log:hover,
.logger:hover,
.pass:hover,
.fail:hover,
.test:hover {}
.pass {
background:lightgreen;
}
.fail {
background:lightpink;
}
.test {
background:lightyellow;
}
.log {
background:lightyellow;
}
.logger {
background:lightyellow;
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 180 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 178 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 120 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 105 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 111 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 110 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 119 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 101 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.3 KiB

Просмотреть файл

@ -0,0 +1,404 @@
/*
* jQuery UI CSS Framework
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
*/
/* Layout helpers
----------------------------------*/
.ui-helper-hidden { display: none; }
.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
.ui-helper-clearfix { display: inline-block; }
/* required comment for clearfix to work in Opera \*/
* html .ui-helper-clearfix { height:1%; }
.ui-helper-clearfix { display:block; }
/* end clearfix */
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
/* Interaction Cues
----------------------------------*/
.ui-state-disabled { cursor: default !important; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
/* Misc visuals
----------------------------------*/
/* Overlays */
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
/*
* jQuery UI CSS Framework
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
*/
/* Component containers
----------------------------------*/
.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
.ui-widget-content a { color: #222222; }
.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
.ui-widget-header a { color: #222222; }
/* Interaction states
----------------------------------*/
.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #333; outline: none; }
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #333; text-decoration: none; outline: none; }
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; }
.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; outline: none; }
.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; }
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; outline: none; text-decoration: none; }
/* Interaction Cues
----------------------------------*/
.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; }
.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
.ui-state-error a, .ui-widget-content .ui-state-error a { color: #cd0a0a; }
.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a; }
.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
/* positioning */
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -96px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-off { background-position: -96px -144px; }
.ui-icon-radio-on { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
/* Misc visuals
----------------------------------*/
/* Corner radius */
.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; }
.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; }
/* Overlays */
.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; }/* Accordion
----------------------------------*/
.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
.ui-accordion .ui-accordion-li-fix { display: inline; }
.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
.ui-accordion .ui-accordion-content-active { display: block; }/* Datepicker
----------------------------------*/
.ui-datepicker { width: 17em; padding: .2em .2em 0; }
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
.ui-datepicker .ui-datepicker-prev { left:2px; }
.ui-datepicker .ui-datepicker-next { right:2px; }
.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
.ui-datepicker .ui-datepicker-next-hover { right:1px; }
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year { width: 49%;}
.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
.ui-datepicker td { border: 0; padding: 1px; }
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi { width:auto; }
.ui-datepicker-multi .ui-datepicker-group { float:left; }
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
.ui-datepicker-row-break { clear:both; width:100%; }
/* RTL support */
.ui-datepicker-rtl { direction: rtl; }
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
.ui-datepicker-cover {
display: none; /*sorry for IE5*/
display/**/: block; /*sorry for IE5*/
position: absolute; /*must have*/
z-index: -1; /*must have*/
filter: mask(); /*must have*/
top: -4px; /*must have*/
left: -4px; /*must have*/
width: 200px; /*must have*/
height: 200px; /*must have*/
}/* Dialog
----------------------------------*/
.ui-dialog { position: relative; padding: .2em; width: 300px; }
.ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; }
.ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; }
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
.ui-draggable .ui-dialog-titlebar { cursor: move; }
/* Progressbar
----------------------------------*/
.ui-progressbar { height:2em; text-align: left; }
.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* Resizable
----------------------------------*/
.ui-resizable { position: relative;}
.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Slider
----------------------------------*/
.ui-slider { position: relative; text-align: left; }
.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
.ui-slider-horizontal { height: .8em; }
.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
.ui-slider-horizontal .ui-slider-range-min { left: 0; }
.ui-slider-horizontal .ui-slider-range-max { right: 0; }
.ui-slider-vertical { width: .8em; height: 100px; }
.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
----------------------------------*/
.ui-tabs { padding: .2em; zoom: 1; }
.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .6em .2em 0 .2em; }
.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
.ui-tabs .ui-tabs-panel { padding: 1.4em 1.2em; display: block; border-width: 0; background: none; }
.ui-tabs .ui-tabs-hide { display: none !important; }

Просмотреть файл

@ -0,0 +1,231 @@
// ***** BEGIN LICENSE BLOCK *****
// Version: MPL 1.1/GPL 2.0/LGPL 2.1
//
// The contents of this file are subject to the Mozilla Public License Version
// 1.1 (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// The Original Code is Mozilla Corporation Code.
//
// The Initial Developer of the Original Code is
// Adam Christian.
// Portions created by the Initial Developer are Copyright (C) 2008
// the Initial Developer. All Rights Reserved.
//
// Contributor(s):
// Adam Christian <adam.christian@gmail.com>
// Mikeal Rogers <mikeal.rogers@gmail.com>
//
// Alternatively, the contents of this file may be used under the terms of
// either the GNU General Public License Version 2 or later (the "GPL"), or
// the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
// in which case the provisions of the GPL or the LGPL are applicable instead
// of those above. If you wish to allow use of your version of this file only
// under the terms of either the GPL or the LGPL, and not to allow others to
// use your version of this file under the terms of the MPL, indicate your
// decision by deleting the provisions above and replace them with the notice
// and other provisions required by the GPL or the LGPL. If you do not delete
// the provisions above, a recipient may use your version of this file under
// the terms of any one of the MPL, the GPL or the LGPL.
//
// ***** END LICENSE BLOCK *****
var inspection = {}; Components.utils.import('resource://mozmill/modules/inspection.js', inspection);
var utils = {}; Components.utils.import('resource://mozmill/modules/utils.js', utils);
var DomInspectorConnector = function() {
this.lastEvent = null;
this.lastTime = null;
this.on = false;
}
DomInspectorConnector.prototype.grab = function(){
var disp = $('dxDisplay').textContent;
var dispArr = disp.split(': ');
$('editorInput').value += 'new elementslib.'+dispArr[0].toUpperCase()+"('"+dispArr[1]+"')\n";
}
DomInspectorConnector.prototype.changeClick = function(e) {
if (this.on){
this.dxOff()
this.dxOn();
}
}
DomInspectorConnector.prototype.evtDispatch = function(e) {
//if this function was called less than a second ago, exit
//this should solve the flickering problem
var currentTime = new Date();
var newTime = currentTime.getTime();
if (this.lastTime != null){
var timeDiff = newTime - this.lastTime;
this.lastTime = newTime;
if (timeDiff < 2){
this.lastEvent = e;
return;
}
} else { this.lastTime = newTime; }
//Fix the scroll bar exception Bug 472124
try { var i = inspection.inspectElement(e); }
catch(err){ return; }
var dxC = i.controllerText;
var dxE = i.elementText;
var dxV = String(i.validation);
document.getElementById('dxController').innerHTML = dxC;
document.getElementById('dxValidation').innerHTML = dxV;
document.getElementById('dxElement').innerHTML = dxE;
return dxE;
}
DomInspectorConnector.prototype.dxToggle = function(){
if (this.on)
this.dxOff();
else
this.dxOn();
}
//Turn on the recorder
//Since the click event does things like firing twice when a double click goes also
//and can be obnoxious im enabling it to be turned off and on with a toggle check box
DomInspectorConnector.prototype.dxOn = function() {
this.on = true;
$("#dxToggle").text("Stop");
//defined the click method, default to dblclick
var clickMethod = "dblclick";
if (document.getElementById('inspectSingle').checked){
clickMethod = 'click';
}
var enumerator = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator)
.getEnumerator("");
while(enumerator.hasMoreElements()) {
var win = enumerator.getNext();
if (win.document.title != 'MozMill IDE'){
this.dxRecursiveBind(win, clickMethod);
}
}
var observerService =
Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.addObserver(this.observer, "toplevel-window-ready", false);
};
//when a new dom window gets opened
DomInspectorConnector.prototype.observer = {
observe: function(subject,topic,data){
var clickMethod = "dblclick";
if ($('inspectSingle').selected){
clickMethod = 'click';
}
//Attach listener to new window here
MozMilldx.dxRecursiveBind(subject, clickMethod);
}
};
DomInspectorConnector.prototype.dxOff = function() {
this.on = false;
$("#dxToggle").text("Start");
$("#dxCopy").show();
//try to cleanup left over outlines
if (this.lastEvent){
this.lastEvent.target.style.outline = "";
}
for each(win in utils.getWindows()) {
this.dxRecursiveUnBind(win, 'click');
}
for each(win in utils.getWindows()) {
this.dxRecursiveUnBind(win, 'dblclick');
}
var observerService =
Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
try {
observerService.removeObserver(this.observer, "toplevel-window-ready");
} catch(err){}
};
DomInspectorConnector.prototype.getFoc = function(e){
MozMilldx.dxOff();
e.target.style.outline = "";
e.stopPropagation();
e.preventDefault();
window.focus();
}
DomInspectorConnector.prototype.inspectorToClipboard = function(){
copyToClipboard($('#dxController')[0].innerHTML +'\n'+$('#dxElement')[0].innerHTML);
};
//Copy inspector output to clipboard if alt,shift,c is pressed
DomInspectorConnector.prototype.clipCopy = function(e){
if (e == true){
copyToClipboard($('#dxElement')[0].innerHTML + ' '+$('#dxValidation')[0].innerHTML + ' ' + $('#dxController')[0].innerHTML);
}
else if (e.altKey && e.shiftKey && (e.charCode == 199)){
copyToClipboard($('#dxElement')[0].innerHTML + ' '+$('#dxValidation')[0].innerHTML + ' ' + $('#dxController')[0].innerHTML);
}
}
//Recursively bind to all the iframes and frames within
DomInspectorConnector.prototype.dxRecursiveBind = function(frame, clickMethod) {
frame.addEventListener('mouseover', this.evtDispatch, true);
frame.addEventListener('mouseout', this.evtDispatch, true);
frame.addEventListener(clickMethod, this.getFoc, true);
frame.addEventListener('keypress', this.clipCopy, true);
var iframeCount = frame.window.frames.length;
var iframeArray = frame.window.frames;
for (var i = 0; i < iframeCount; i++)
this.dxRecursiveBind(iframeArray[i], clickMethod);
}
//Recursively bind to all the iframes and frames within
DomInspectorConnector.prototype.dxRecursiveUnBind = function(frame, clickMethod) {
try {
frame.removeEventListener('mouseover', this.evtDispatch, true);
frame.removeEventListener('mouseout', this.evtDispatch, true);
frame.removeEventListener(clickMethod, this.getFoc, true);
frame.removeEventListener('keypress', this.clipCopy, true);
}
catch(e) {
// don't want to prevent the rest of the frames from removing listeners
}
var iframeCount = frame.window.frames.length;
var iframeArray = frame.window.frames;
for (var i = 0; i < iframeCount; i++)
this.dxRecursiveUnBind(iframeArray[i], clickMethod);
}
var MozMilldx = new DomInspectorConnector();
// Scoping bug workarounds
var enableDX = function () {
MozMilldx.dxOn();
}
var disableDX = function () {
MozMilldx.dxOff();
}

Просмотреть файл

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<prefwindow id="mozmill-dxwindow"
title="DOM Explorer"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<prefpane id="dxwindow" label="DOM Explorer">
<hbox id="dxtarget" align="center">
</hbox>
</prefpane>
</prefwindow>

Просмотреть файл

@ -0,0 +1,123 @@
.bespin-completion-panel {
font-family: Helvetica, Arial, sans-serif;
position: absolute;
cursor: default;
line-height: normal;
-moz-user-select: none;
-webkit-user-select: none;
}
.bespin-completion-pointer {
position: absolute;
z-index: 2;
height: 21px;
width: 21px;
}
.bespin-completion-pointer-up {
top: 1px;
border-top: solid #555 1px;
border-left: solid #555 1px;
background-image: -moz-linear-gradient(top left, #333333, #333333 50%, transparent 50%, transparent);
background-image: -webkit-gradient(linear, left top, right bottom, from(#333333), color-stop(0.5, #333333), color-stop(0.5, transparent), to(transparent));
-moz-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
}
.bespin-completion-pointer-down {
bottom: 1px;
border-top: solid #000 1px;
border-left: solid #000 1px;
background-image: -moz-linear-gradient(top left, #000, #000 50%, transparent 50%, transparent);
background-image: -webkit-gradient(linear, left top, right bottom, from(#000), color-stop(0.5, #000), color-stop(0.5, transparent), to(transparent));
-moz-transform: rotate(225deg);
-webkit-transform: rotate(225deg);
}
.bespin-completion-bubble-outer {
position: relative;
z-index: 1;
margin: 11px 0px 11px 0px;
border-top: solid #555 1px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
}
.bespin-completion-bubble-inner {
position: relative;
z-index: 3;
padding: 6px;
background: -moz-linear-gradient(top, #333333, #000000);
background: -webkit-gradient(linear, center top, center bottom, from(#333333), to(#000000));
color: #ffffff;
font-size: 10.5pt;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
-moz-box-shadow: 0px 6px 16px 2px rgba(0, 0, 0, 0.5);
-webkit-box-shadow: 0px 6px 16px 2px rgba(0, 0, 0, 0.5);
}
.bespin-completion-panel ul {
list-style: none;
margin: 0px;
padding: 0px;
}
.bespin-completion-panel li {
text-indent: 0px;
margin: 0px;
padding: 6px 16px;
}
.bespin-completion-highlight {
position: absolute;
z-index: -1;
background-image: -moz-linear-gradient(top, #3e59be, #312d80);
background-image: -webkit-gradient(linear, center top, center bottom, from(#3e59be), to(#312d80));
border: solid rgba(37, 34, 91, 1.0) 1px;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
}
.bespin-completion-kind {
display: block;
float: left;
top: 0px;
left: 0px;
width: 8px;
height: 8px;
padding: 2px;
margin: 0px 5px 0px 0px;
font-size: 6.5pt;
font-weight: bold;
text-transform: uppercase;
text-align: center;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
.bespin-completion-kind-m {
background-color: maroon;
}
.bespin-completion-kind-f {
background-color: green;
}
.bespin-completion-top-row {
position: relative;
}
.bespin-completion-second-row {
margin: 6px 0px 0px 17px;
display: none;
}
.bespin-completion-ident {
font-weight: bold;
}
.bespin-completion-container {
color: #a0a0a0;
}

Просмотреть файл

@ -0,0 +1,144 @@
if(typeof bespin==="undefined")bespin={};if(typeof document!=="undefined"){var link=document.getElementById("bespin_base");if(link){var href=link.href;bespin.base=href.substring(href.length-1)!=="/"?href+"/":href}else bespin.base=""}
(function(){if("undefined"===typeof y)var y=function(){function j(w,t){x.push({m:w,a:t})}var x=[],E={isBootstrap:true,queue:x,register:function(w,t){if(w.match(/^tiki/)&&this.ENV)if(this.ENV.app==="tiki"&&this.ENV.mode==="test"){if(!t.dependencies)t.dependencies={};t.dependencies.core_test="~"}j("register",arguments);return this},module:function(w,t){if(w.match(/\:tiki$/))this.tikiFactory=t;j("module",arguments);return this},start:function(){var w={};this.tikiFactory(null,w,null);w=w.Browser.start(this.ENV,
this.ARGS,x);x=null;return w}};if("undefined"!==typeof ENV)E.ENV=ENV;if("undefined"!==typeof ARGV)E.ARGS=ARGV;if("undefined"!==typeof ARGS)E.ARGS=ARGS;return E}();y.register("::tiki/1.0.0",{name:"tiki",version:"1.0.0"});y.module("::tiki/1.0.0:tiki",function(j,x){var E=/^::/,w=function(a){return!!E.exec(a)},t=function(){x.debug.apply(this,arguments)};x.debug=function(){var a=Array.prototype.join.call(arguments,"");j("sys").debug(a)};var h;h=Array.isArray?Array.isArray:function(a){if("object"!==typeof a)return false;
if(a instanceof Array)return true;return a.constructor&&a.constructor.name==="Array"};x.isArray=h;var o;if(Object.create)o=Object.create;else{var s=function(){},C=s.prototype;o=function(a){if(!a)a=Object.prototype;s.prototype=a;var b=new s;b.prototype=a;s.prototype=C;return b}}x.createObject=o;var v,B,F;v=function(){return function(){return this.init?this.init.apply(this,arguments):this}};B=function(){return F(this)};F=function(a){var b=v();b.prototype=o(a.prototype);b.prototype.constructor=b;b.super_=
a;b.extend=B;return b};x.extend=F;var f=function(a,b){if(b&&!b.displayName)b.displayName="parallel#fn";return function(c){if(a.length===0)return c(null,[]);var d=a.length,l=d,m=false,z,D=function(H){if(!m){if(H){m=true;return c(H)}--l<=0&&c()}};D.displayName="parallel#tail";for(z=0;z<d;z++)b(a[z],D)}};f.displayName="parallel";var g;g=Array.prototype.map?function(a,b){return a.map(b)}:function(a,b){var c,d=a.length,l=[];for(c=0;c<d;c++)l[c]=b(a[c],c);return l};g.displayName="map";var n=function(a,
b){var c="pending",d=[],l=false,m=null,z=function(D){b||(b=this);switch(c){case "ready":D.apply(null,m);break;case "running":d.push(D);break;case "pending":d.push(D);c="running";a.call(b,function(){m=Array.prototype.slice.call(arguments);var H=d,M=m;if(l){c="pending";d=[];m=null;l=false}else{c="ready";d=null}H&&H.forEach(function(O){O.apply(null,M)})});break}return this};z.displayName="once#handler";z.reset=function(){switch(c){case "ready":c="pending";d=[];m=null;break;case "running":l=true;break}};
z.reset.displayName="once#handler.reset";return z};x.once=n;var p=function(a,b){var c,d;for(c in a)if(a.hasOwnProperty(c)){d=a[c];if("function"===typeof d)if(!d.displayName){d.displayName=b?b+"."+c:c;p(d.prototype,d.displayName)}}return a},u=F(Error);u.prototype.init=function(a,b){a=a+" not found";if(b)a="string"===typeof b?a+" "+b:a+" in package "+(b.id||"(unknown)");this.message=a;return this};x.NotFound=u;var A=F(Error);A.prototype.init=function(a,b){if("undefined"!==typeof JSON)a=JSON.stringify(a);
this.message="Invalid package definition. "+b+" "+a};x.InvalidPackageDef=A;var L=function(){var a=function(d){return d.charCodeAt(0)<=32},b=function(d){d=d.charCodeAt(0);return d>=48&&d<=57},c=function(d,l){for(var m=0,z=0,D=0,H,M;;z++,D++){H=d.charAt(z);M=l.charAt(D);if(!b(H)&&!b(M))return m;else if(b(H))if(b(M)){if(H<M)if(m===0)m=-1;else if(H>M)if(m===0)m=+1;else if(H===0&&M===0)return m}else return+1;else return-1}};return function(d,l){for(var m=0,z=0,D=0,H=0,M,O,W;;){D=H=0;M=d.charAt(m);for(O=
l.charAt(z);a(M)||M=="0";){if(M=="0")D++;else D=0;M=d.charAt(++m)}for(;a(O)||O=="0";){if(O=="0")H++;else H=0;O=l.charAt(++z)}if(b(M)&&b(O))if((W=c(d.substring(m),l.substring(z)))!==0)return W;if(M===0&&O===0)return D-H;if(M<O)return-1;else if(M>O)return+1;++m;++z}}}();x.natcompare=L;var I=function(a){return new Error(""+a+" is an invalid version string")};I.displayName="invalidVers";var N=function(a,b,c,d){c=Number(c);d=Number(d);if(isNaN(c))throw I(a);if(isNaN(d))throw I(b);return c-d};N.displayName=
"compareNum";var i,J={parse:function(a){a=a.match(/^(=|~)?([\d]+?)(\.([\d]+?)(\.(.+))?)?$/);if(!a)return null;return[a,a[2],a[4]||"0",a[6]||"0",a[1]]},major:function(a){return Number(i(a)[1])},minor:function(a){return Number(i(a)[2])},patch:function(a){a=i(a)[3];return isNaN(Number(a))?a:Number(a)},STRICT:"strict",NORMAL:"normal",mode:function(a){return i(a)[4]==="="?J.STRICT:J.NORMAL},comparePatch:function(a,b){var c,d;if(a===b)return 0;c=Number(a);d=Number(b);return isNaN(c)?isNaN(d)?L(a,b):-1:
isNaN(d)?1:c<d?-1:c>d?1:0},compare:function(a,b){var c;if(a===b)return 0;if(a)a=i(a);if(b)b=i(b);if(!a&&!b)return 0;if(!a)return-1;if(!b)return 1;c=N(a[0],b[0],a[1],b[1]);if(c===0){c=N(a[0],b[0],a[2],b[2]);if(c===0)c=J.comparePatch(a[3],b[3])}return c<0?-1:c>0?1:0},compatible:function(a,b){if(!a)return true;if(a===b)return true;if(a&&!i(a))a=null;if(b&&!i(b))b=null;if(!a)return true;if(a===b)return true;if(J.mode(a)===J.STRICT)return b&&J.compare(a,b)===0;else{if(!b)return true;if(J.major(a)!==J.major(b))return false;
return J.compare(a,b)<=0}},normalize:function(a){var b;if(!a||a.length===0)return null;a=J.parse(a);if(!a)return null;b=Number(a[3]);if(isNaN(b))b=a[3];return[Number(a[1]),Number(a[2]),b].join(".")}};x.semver=J;i=J.parse;var U=x.extend(Object);x.Factory=U;U.prototype.init=function(a,b,c){this.id=a;this.pkg=b;this.factory=c};U.prototype.call=function(a,b){var c=this.factory,d=this.__filename,l=this.__dirname;if("string"===typeof c)c=this.factory=U.compile(c,this.pkg.id+":"+this.id);a=a.createRequire(b);
var m=b.exports;c.call(m,a,m,b,d,l);return b.exports};var R=["(function(require, exports, module) {",null,"\n});\n//@ sourceURL=",null,"\n"];U.compile=function(a,b){R[1]=a;R[3]=b||"(unknown module)";a=R.join("");a=eval(a);R[1]=R[3]=null;return a};x.Factory=U;var S=x.extend(Object);x.Module=S;S.prototype.init=function(a,b,c){this.id=a;this.ownerPackage=b;this.exports={};var d=this;this.resource=function(l){return c.resource(l,d.id,b)}};var Q=x.extend(Object);x.Package=Q;Q.prototype.init=function(a,
b){w(a)||(a="::"+a);this.id=a;this.config=b;this.isReady=true};Q.prototype.get=function(a){return this.config?this.config[a]:undefined};Q.prototype.set=function(a,b){if(!this.config)this.config={};this.config[a]=b;return this};Q.prototype.requiredVersion=function(a){var b=this.get("dependencies");return b?b[a]:null};Q.prototype.canonicalPackageId=function(a,b){if(a===this.get("name")&&J.compatible(b,this.get("version")))return this.id;return null};Q.prototype.packageFor=function(a){if(a===this.id)return this;
return null};Q.prototype.ensurePackage=function(a,b){return a===this.id?b():b(new u(a,this))};Q.prototype.catalogPackages=function(){return[this]};Q.prototype.exists=function(a){return!!(this.factories&&this.factories[a])};Q.prototype.load=function(a){return this.factories?this.factories[a]:null};var e=function(a,b){return a+":"+b},k=x.extend(Object);x.Loader=k;k.prototype.init=function(a){this.sources=a||[];this.clear()};k.prototype.clear=function(){this.factories={};this.canonicalIds={};this.packages=
{};this.packageSources={};this.canonicalPackageIds={}};k.prototype.defaultPackage=new Q("default",{name:"default"});k.prototype.anonymousPackage=new Q("(anonymous)",{name:"(anonymous)"});k.prototype.canonical=function(a,b,c){var d,l,m,z;if(b&&"string"!==typeof b){c=b;b=null}if(w(a))return a;if(!c)c=this.anonymousPackage;a=this._resolve(a,b,c);if(w(a))return a;d=c?c.id:"(null)";b=this.canonicalIds;if(!b)b=this.canonicalIds={};b[d]||(b[d]={});b=b[d];if(b[a])return b[a];d=a;l=a.indexOf(":");if(l>=0){m=
a.slice(0,l);a=a.slice(l+1);if(a[0]==="/")throw new Error("Absolute path not allowed with packageId");}l=null;if(m&&m.length>0){if(m=this._canonicalPackageId(m,null,c))l=e(m,a)}else{if(c&&c.exists(a))l=e(c.id,a);else{if(m=this._canonicalPackageId(a,null,c))z=this._packageFor(m,c);if(z)if(z.exists("index"))l=e(z.id,"index");else if(z.exists(a))l=e(z.id,a)}if(!l){if(this.defaultPackage)m=this.defaultPackage.id;else if(this.workingPackage)m=this.workingPackage.id;else if(this.anonymousPackage)m=this.anonymousPackage.id;
else return null;if(m)l=e(m,a)}}return b[d]=l};k.prototype.load=function(a,b,c){var d,l,m;if(!b)b=this.anonymousPackage;d=this.factories;if(!d)d=this.factories={};if(d[a])return d[a];l=a.indexOf(":",2);m=a.slice(0,l);l=a.slice(l+1);(b=this._packageFor(m,b))||t("Loader#load - "+m+" not found for "+l);if(!b)return null;c=b.load(l,c);return d[a]=c};k.prototype.catalogPackages=function(a){if(!a)a=this.anonymousPackage;var b=[],c,d,l={};this.defaultPackage&&b.push(this.defaultPackage);var m=function(z){var D,
H,M,O;if(z){H=z.length;for(D=0;D<H;D++){O=z[D];(M=l[O.get("name")])||(M=l[O.get("name")]={});if(!M[O.get("version")]){b.push(O);M[O.get("version")]=O}}}};a&&m(a.catalogPackages());a=this.sources;d=a.length;for(c=0;c<d;c++)m(a[c].catalogPackages());l=null;return b};k.prototype.canonicalPackageId=function(a,b,c){var d;if(a instanceof Q)return a.id;if(w(a)){d=a.indexOf(":",2);if(d>=0)a=a.slice(0,d);return a}if(b&&"string"!==typeof b){c=b;b=null}if(!c)c=this.anonymousPackage;d=a.indexOf(":");if(d>=0)a=
a.slice(0,d);return this._canonicalPackageId(a,b,c)};k.prototype.packageFor=function(a,b){if(!b)b=this.anonymousPackage;var c=a.indexOf(":",2);if(c>=0)a=a.slice(0,c);return this._packageFor(a,b)};k.prototype.ready=function(a,b){if(!b)b=this.anonymousPackage;var c=a.indexOf(":",2),d;if(c>=0){d=a.slice(c+1);a=a.slice(0,c)}if(this._packageReady(a,b,{})){a=this._packageFor(a,b);if(!a)return false;return!!a.exists(d)}else return false};k.prototype.ensurePackage=function(a,b,c,d){if(b&&"string"!==typeof b){d=
c;c=b;b=null}if(c&&"function"===typeof c){d=c;c=null}if(!c)c=this.anonymousPackage;this._ensurePackage(a,b,c,{},d)};k.prototype._ensurePackage=function(a,b,c,d,l){var m=this,z;z=this._canonicalPackageId(a,b,c);if(!z)return l(new u(a,c));if(d[z])return l();d[z]=true;a=this._sourceForCanonicalPackageId(z,c);if(!a)return l(new u(z,c));a.ensurePackage(z,function(D){var H,M,O;if(D)return l(D);H=m.packageFor(z,c);if(!H)return l(new u(z,c));D=H.get("dependencies");if(!D)return l();O=[];for(M in D)D.hasOwnProperty(M)&&
O.push({packageId:M,vers:D[M]});f(O,function(W,V){m._ensurePackage(W.packageId,W.vers,H,d,V)})(l)})};k.prototype._canonicalPackageId=function(a,b,c){if(a instanceof Q)return a.id;if(w(a))return a;if(a==="default"&&this.defaultPackage)return this.defaultPackage.id;var d=this.canonicalPackageIds,l,m,z,D,H;if(!c)c=this.anonymousPackage;if(!c)throw new Error("working package is required");b||(b=c.requiredVersion(a));l=c.id;if(!d)d=this.canonicalPackageIds={};d[l]||(d[l]={});d=d[l];d[a]||(d[a]={});d=d[a];
if(d[b])return d[b];l=this.sources;m=c.canonicalPackageId(a,b);H=c;if(!m)if(m=c.canonicalPackageId(a,null))throw new Error(c.get("name")+" contains an incompatible nested package "+a+" (expected: "+b+")");if(!m&&l){D=l.length;for(z=0;!m&&z<D;z++){H=l[z];m=H.canonicalPackageId(a,b)}}m&&this._cachePackageSource(m,c,H);return d[b]=m};k.prototype._cachePackageSource=function(a,b,c){var d=this.packageSources;b=b.id;if(!d)d=this.packageSources={};d[b]||(d[b]={});d=d[b];d[a]=c};k.prototype._sourceForCanonicalPackageId=
function(a,b){var c=this.packageSources,d=b.id,l,m;if(!c)c=this.packageSources={};c[d]||(c[d]={});c=c[d];if(c[a])return c[a];d=this.sources;if(b)if(l=b.packageFor(a))m=b;if(!m&&d){b=d.length;for(l=0;!m&&l<b;l++){m=d[l];m.packageFor(a)||(m=null)}}return c[a]=m};k.prototype._packageFor=function(a,b){var c,d;if(this.defaultPackage&&a===this.defaultPackage.id)return this.defaultPackage;c=this.packages;if(!c)c=this.packages={};if(c[a])return c[a];if(b=this._sourceForCanonicalPackageId(a,b))d=b.packageFor(a);
return c[a]=d};k.prototype._packageReady=function(a,b,c){var d;if(c[a])return true;c[a]=true;b=this._packageFor(a,b);if(!b)return false;a=b.get("dependencies");for(d in a)if(a.hasOwnProperty(d)){a=a[d];a=this._canonicalPackageId(d,a,b);if(!a)return false;return this._packageReady(a,b,c)}return true};k.prototype._resolve=function(a,b,c){var d,l,m,z;if(a[0]==="/"&&a.indexOf(":")<0)return this.anonymousPackage.id+":"+a;if(a.match(/(^\.\.?\/)|(\/\.\.?\/)|(\/\.\.?\/?$)/)){if((d=a.indexOf(":"))>=0){z=a.slice(0,
d);a=a.slice(d+1);b=[]}else if(a.match(/^\.\.?\//)){if(!b)throw new Error("id required to resolve relative id: "+a);if(b.indexOf(":")>=0)throw new Error("current moduleId cannot contain packageId");if(c)z=c.id;b=b.split("/");b.pop()}else b=[];m=a.split("/");c=m.length;for(d=0;d<c;d++){l=m[d];if(l===".."){if(b.length<1)throw new Error("invalid path: "+a);b.pop()}else l!=="."&&b.push(l)}a=b.join("/");if(z)a=e(z,a)}return a};var r=x.extend(Object);x.Sandbox=r;r.prototype.init=function(a,b,c,d){this.loader=
a;this.env=b;this.args=c;d&&this.main(d);this.clear()};r.prototype.catalogPackages=function(a){return this.loader.catalogPackages(a)};r.prototype.createRequire=function(a){var b=this,c=a.id,d=a.ownerPackage,l=function(m,z){if(z&&m.indexOf(":")<0){if(z.isPackage)z=z.id;m=z+":"+m}return b.require(m,c,d)};a=l.displayName=(c||"(unknown)")+"#require";l.nativeRequire=b.nativeRequire;l.ensure=function(m,z){if(!h(m)){m=Array.prototype.slice.call(arguments);z=m.pop()}f(m,function(D,H){b.ensure(D,c,d,H)})(function(D){if(D)return z(D);
if(z.length<=1)return z();z(null,g(m,function(H){return b.require(H,c,d)}))})};l.ensure.displayName=a+".ensure";l.ready=function(m){var z,D;h(m)||(m=Array.prototype.slice.call(arguments));D=m.length;for(z=0;z<D;z++)if(!b.ready(m[z],c,d))return false;return true};l.ready.displayName=a+".ready";l.packageFor=function(m,z){return b.packageFor(m,z,d)};l.packageFor.displayName=a+".packageFor";l.ensurePackage=function(m,z,D){b.ensurePackage(m,z,d,function(H){if(H)return D(H);if(D.length<=1)return D();D(null,
b.packageFor(m,z,d))})};l.ensurePackage.displayName=a+".ensurePackage.displayName";l.catalogPackages=function(){return b.catalogPackages(d)};l.main=b.main();l.env=b.env;l.args=b.args;l.sandbox=b;l.loader=b.loader;l.isTiki=true;return l};r.prototype.Module=S;r.prototype.module=function(a,b,c){var d,l,m;b=this.loader.canonical(a,b,c);if(!b)throw new u(a,c);d=this.modules;if(!d)d=this.modules={};if(a=d[b])return a;l=b.indexOf(":",2);a=b.slice(l+1);l=b.slice(0,l);m=this.loader.packageFor(l,c);if(!m)throw new u(l,
c);return a=d[b]=new this.Module(a,m,this)};r.prototype.main=function(a,b){if(a!==undefined){this._mainModule=null;this._mainModuleId=a;this._mainModuleWorkingPackage=b;return this}else{if(!this._mainModule&&this._mainModuleId){b=this._mainModuleWorkingPackage;this._mainModule=this.module(this._mainModuleId,b)}return this._mainModule}};r.prototype.require=function(a,b,c){var d,l;b=this.loader.canonical(a,b,c);if(!b)throw new u(a,c);l=this.exports;a=this.usedExports;if(!l)l=this.exports={};if(!a)a=
this.usedExports={};if(d=l[b]){d=d.exports;a[b]||(a[b]=d);return d}d=this.loader.load(b,c,this);if(!d)throw new u(b,c);c=this.module(b,c);l[b]=c;l=d.call(this,c);c.exports=l;if(a[b]&&a[b]!==l)throw new Error("cyclical requires() in "+b);return l};r.prototype.ready=function(a,b,c){return(a=this.loader.canonical(a,b,c))?this.loader.ready(a):false};r.prototype.ensure=function(a,b,c,d){var l,m,z;if(b&&"string"!==typeof b){d=c;c=b;b=null}if(c&&"function"===typeof c){d=c;c=null}b=this.loader.canonical(a,
b,c);if(!b)return d(new u(a,c));z=b.indexOf(":",2);a=b.slice(z+1);m=b.slice(0,z);l=this.loader;l.ensurePackage(m,c,function(D){if(D)return d(D);D=l.packageFor(m,c);D.exists(a)?d():d(new u(a,D))})};r.prototype.packageFor=function(a,b,c){a=this.loader.canonicalPackageId(a,b,c);if(!a)return null;return this.loader.packageFor(a)};r.prototype.ensurePackage=function(a,b,c,d){if(b&&"string"!==typeof b){d=c;c=b;b=null}if(c&&"function"===typeof c){d=c;c=null}b=this.loader.canonicalPackageId(a,b,c);if(!b)return d(new u(a,
c));this.loader.ensurePackage(b,d)};r.prototype.resource=function(a,b,c){if(!c.resource)return null;return c.resource(a,b)};r.prototype.clear=function(){this.exports={};this.modules={};this.usedExports={};return this};var q=x.extend(Object);x.Browser=q;q.prototype.init=function(){this._ready={};this._unload={};this.clear()};q.prototype.clear=function(){this.packageInfoByName={};this.packageInfoById={};this.packages={};this.factories={};this.stylesheetActions={};this.scriptActions={};this.ensureActions=
{}};q.start=function(a,b,c){var d;d=new q;d.loader=new k([d]);d.sandbox=new r(d.loader,a,b);d.queue=c;d.require=d.sandbox.createRequire({id:"index",ownerPackage:d.loader.anonymousPackage});return d};q.prototype.replay=function(){var a=this.queue,b=a?a.length:0,c,d;this.queue=null;for(c=0;c<b;c++){d=a[c];this[d.m].apply(this,d.a)}return this};q.prototype.start=function(){return this};q.prototype.global=function(a){if(!P&&!X)return this;var b=function(){return this}(),c,d,l,m,z,D,H,M;c=this.globals;
if(!c)c=this.globals={};d=this.packageFor(a);if(!d)throw new Error(a+" package not found");l=d.get("dependencies");if(!l)return this;for(m in l)if(l.hasOwnProperty(m)){a=this.loader.canonical(m,d);if(!c[a]){c[a]=true;if(this.sandbox.ready(m,d)){a=this.sandbox.require(m,d);if(z=a.__globals__){M=z.length;for(H=0;H<M;H++){D=z[H];b[D]=a[D]}}else for(D in a)if(a.hasOwnProperty(D))b[D]=a[D]}}}return this};var G=function(a){var b,c;if(a.length===1){b=null;c=a[0];a=Array.prototype.slice.call(a,1)}else{b=
a[0];c=a[1];a=Array.prototype.slice.call(a,2)}return{target:b,method:c,args:a}},K=function(a,b,c){a[b]||(a[b]=[]);a[b].push(G(c))};q.prototype.addReadyListener=function(){if(this._ready&&this._ready.isReady)this._invoke(G(arguments));else{this._setupReadyListener();K(this._ready,"queue",arguments)}};q.prototype.addMainListener=function(){if(this._ready&&this._ready.isReady)this._invoke(G(arguments));else{this._setupReadyListener();K(this._ready,"mqueue",arguments)}};q.prototype.addUnloadListener=
function(){if(this._unload&&this._unload.isUnloading)this._invoke(G(arguments));else{this._setupUnloadListener();K(this._unload,"queue",arguments)}};q.prototype._invoke=function(a){var b=a.target,c=a.method;if("string"===typeof b)b=this.require(b);if("string"===typeof c)c=b[c];c&&c.apply(b,a.args);a.target=a.method=a.args=null};q.prototype._setupReadyListener=function(){if(this._ready.setup)return this;this._ready.setup=true;var a=this._ready,b=this,c;c=function(){if(!a.isReady){a.isReady=true;a.cleanup&&
a.cleanup();a.cleanup=null;var d,l,m;l=(d=a.queue)?d.length:0;a.queue=null;for(m=0;m<l;m++)b._invoke(d[m]);l=(d=a.mqueue)?d.length:0;a.mqueue=null;for(m=0;m<l;m++)b._invoke(d[m]);b._runMain()}};if("undefined"!==typeof document)if(document.addEventListener){a.cleanup=function(){document.removeEventListener("DOMContentLoaded",c,false);document.removeEventListener("load",c,false)};document.addEventListener("DOMContentLoaded",c,false);document.addEventListener("load",c,false)}else if(document.attachEvent){a.cleanup=
function(){document.detachEvent("onreadystatechange",c);document.detachEvent("onload",c);a.ieHandler=null};document.attachEvent("onreadystatechange",c);document.attachEvent("onload",c);if(document.documentElement.doScroll&&window==window.top){a.ieHandler=function(){if(a.ieHandler&&!a.isReady)try{document.documentElement.doScroll("left")}catch(d){setTimeout(a.ieHandler,0);return}c()};a.ieHandler()}}};q._scheduleUnloadListener=function(){if(this._unload.setup)return this;this._unload.setup=true;var a=
this._unload,b=this,c;a.isUnloading=false;c=function(){if(!a.isUnloading){a.isUnloading=true;a.cleanup&&a.cleanup();a.cleanup=null;var d=a.queue,l=d?d.length:0,m;a.queue=null;for(m=0;m<l;m++)b._invoke(d[m])}};if("undefined"!==typeof document)if(document.addEventListener){a.cleanup=function(){document.removeEventListener("unload",c)};document.addEventListener("unload",c,false)}else if(document.attachEvent){a.cleanup=function(){document.detachEvent("onunload",c)};document.attachEvent("unload",c)}};
q.prototype.main=function(a,b){this.sandbox&&this.sandbox.main(a);this._setupReadyListener();this._main={id:a,method:b}};q.prototype._runMain=function(){if(this._main){var a=this._main.id,b=this._main.method,c=this.require;if(a&&c){this._main=null;c.ensure(a,function(d){if(d)throw d;d=c(a);if("string"===typeof b)b=d[b];b&&b.call(d)})}}};q.prototype._action=function(a){var b;return b=n(function(c){b.resolve=function(d,l){b.resolve=null;c(d,l)};a()})};q.prototype._resolve=function(a,b,c){if(a[b])a[b].resolve&&
a[b].resolve(null,c);else a[b]=function(d){d(null,c)};return this};q.prototype._fail=function(a,b,c){a[b].resolve&&a[b].resolve(c)};q.prototype._normalize=function(a,b){w(b)||(b="::"+b);a.id=b;a.version=J.normalize(a.version);a["tiki:external"]=!!a["tiki:external"];a["tiki:private"]=!!a["tiki:private"];var c=a["tiki:base"];if(a["tiki:resources"])a["tiki:resources"]=g(a["tiki:resources"],function(m){if("string"===typeof m)m={id:b+":"+m,name:m};if(!m.name)throw new A(a,"resources must have a name");
if(!m.id)m.id=b+":"+m.name;if(!w(m.id))m.id="::"+m.id;if(!m.type)m.type=m.name.match(/\.js$/)?"script":m.name.match(/\.css$/)?"stylesheet":"resource";if(!m.url)m.url=c?c+"/"+m.name:m.id+m.name;return m});if(!a.dependencies)a.dependencies={};var d=a["tiki:nested"],l;if(d)for(l in d){if(d.hasOwnProperty(l))w(d[l])||(d[l]="::"+d[l])}else a["tiki:nested"]={};return a};q.prototype.register=function(a,b){var c,d,l,m=-1;b=this._normalize(b,a);a=b.id;c=this.packageInfoById;if(!c)c=this.packageInfoById={};
if(c[a]){if(!c[a]["tiki:external"])return this;d=c[a]}c[a]=b;if(b.name){a=b.name;l=b.version;c=this.packageInfoByName;if(!c)c=this.packageInfoByName={};c[a]||(c[a]={});c=c[a];if(!c[l]||c[l].length<=1)c[l]=[b];else{if(d)m=c[l].indexOf(d);if(m>=0)c[l]=c[l].slice(0,m).concat(c[l].slice(m+1));c[l].push(b)}}return this};q.prototype.module=function(a,b){w(a)||(a="::"+a);this.factories[a]=b;return this};q.prototype.script=function(a){w(a)||(a="::"+a);this._resolve(this.scriptActions,a,true)};q.prototype.stylesheet=
function(a){w(a)||(a="::"+a);this._resolve(this.stylesheetActions,a,true)};var P="undefined"!==typeof document&&document.createElement,X="undefined"!==typeof XMLHttpRequest;q.prototype.xhr=!P;q.prototype.autowrap=false;var Z=function(a){if(!a)return null;for(var b=a.length;--b>=0;)if(!a[b]["tiki:private"])return a[b];return null};q.prototype.canonicalPackageId=function(a,b){a=this.packageInfoByName[a];var c,d,l;if(b)b=J.normalize(b);if(!a)return null;if(a[b]&&a[b].length===1)return a[b][0].id;for(d in a)if(a.hasOwnProperty(d))if(J.compatible(b,
d))if(!c||J.compare(l,d)<0)if(c=Z(a[d]))l=d;return c?c.id:null};q.prototype.packageFor=function(a){var b=this.packages[a];if(b)return b;if((b=this.packageInfoById[a])&&!b["tiki:external"]){b=new this.Package(a,b,this);return this.packages[a]=b}return null};q.prototype.ensurePackage=function(a,b){var c=this.ensureActions[a];if(c)return c(b);var d=this.packageInfoById[a];if(!d)return b(new u(a,"browser package info"));var l=this;c=n(function(m){var z=1,D=false,H,M=function(Y){if(!H){if(Y){H=true;return m(Y)}z-=
1;if(z<=0&&D)return m(null,d)}},O=d.dependencies,W=d["tiki:nested"],V,T;for(V in O)if(O.hasOwnProperty(V)){T=W[V];if(!T){T=O[V];T=l.canonicalPackageId(V,T)}if(T&&l.packageInfoById[a]){z++;l.ensurePackage(T,M)}}W=(O=d["tiki:resources"])?O.length:0;for(V=0;V<W;V++){T=O[V];if(T.type!=="resource")if(T.type==="script"){z++;l.ensureScript(T.id,T.url,M)}else if(T.type==="stylesheet"){z++;l.ensureStylesheet(T.id,T.url,M)}}D=true;M()});this.ensureActions[a]=c;c(b)};q.prototype.ensureScript=function(a,b,c){var d=
this.scriptActions[a];if(d)return d(c);var l=this;d=this._action(function(){l._loadScript(a,b)});this.scriptActions[a]=d;return d(c)};q.prototype.ensureStylesheet=function(a,b,c){var d=this.stylesheetActions[a];if(d)return d(c);var l=this;d=this._action(function(){l._loadStylesheet(a,b)});this.stylesheetActions[a]=d;return d(c)};q.prototype._injectScript=function(a,b){var c;a=document.body;c=document.createElement("script");c.src=b;a.appendChild(c)};q.prototype._xhrScript=function(a,b){var c=this.autowrap,
d=new XMLHttpRequest;d.open("GET",b,true);d.onreadystatechange=function(){if(!(d.readyState!==4||d.status!==200&&d.status!==0)){var l=d.responseText;if(c)l="tiki.module('"+a+"', function(require, exports, module) {"+l+"});tiki.script('"+a+"');";eval(l+"\n//@ sourceURL="+b)}};d.send(null)};q.prototype._loadScript=function(a,b){if(this.autowrap){this.xhr=true;X||t("Autowrap is on but XHR is not available. Danger ahead.")}if(X&&P)if(this.xhr)try{return this._xhrScript(a,b)}catch(c){return this._injectScript(a,
b)}else try{return this._injectScript(a,b)}catch(d){return this._xhrScript(a,b)}else if(X)return this._xhrScript(a,b);else if(P)return this._injectScript(a,b);t("Browser#_loadScript() not supported on this platform.");this.script(a)};q.prototype._loadStylesheet=P?function(a,b){var c,d;c=document.getElementsByTagName("head")[0]||document.body;d=document.createElement("link");d.rel="stylesheet";d.href=b;d.type="text/css";c.appendChild(d);this.stylesheet(a)}:function(a){t("Browser#_loadStylesheet() not supported on this platform.");
this.stylesheet(a)};S=Q.extend();q.prototype.Package=S;S.prototype.init=function(a,b,c){Q.prototype.init.call(this,a,b);this.source=c};S.prototype.canonicalPackageId=function(a,b){var c;if(c=Q.prototype.canonicalPackageId.call(this,a,b))return c;c=(this.get("tiki:nested")||{})[a];if(!c)return null;return(a=this.source.packageInfoById[c])&&J.compatible(b,a.version)?c:null};S.prototype.packageFor=function(a){var b=Q.prototype.packageFor.call(this,a);return b?b:this.source.packageFor(a)};S.prototype.ensurePackage=
function(a,b){if(a===this.id)return b();this.source.ensurePackage(a,b)};S.prototype.catalogPackages=function(){var a=[this],b,c;b=this.get("tiki:nested")||{};for(c in b)b.hasOwnProperty(c)&&a.push(this.source.packageFor(b[c]));return a};S.prototype.exists=function(a){return!!this.source.factories[this.id+":"+a]};S.prototype.load=function(a){var b;return(b=this.source.factories[this.id+":"+a])?new this.Factory(a,this,b):null};S.prototype.Factory=U;p(x,"tiki")});y=y.start();y.replay();bespin.tiki=y})();
bespin.tiki.register("::bespin",{name:"bespin",dependencies:{}});bespin.bootLoaded=true;
bespin.tiki.module("bespin:builtins",function(y,j){j.metadata={bespin:{provides:[{ep:"extensionpoint",name:"extensionpoint",indexOx:"name",register:"plugins#registerExtensionPoint",unregister:"plugins#unregisterExtensionPoint",description:"Defines a new extension point",params:[{name:"name",type:"string",description:"the extension point's name",required:true},{name:"description",type:"string",description:"description of what the extension point is for"},{name:"params",type:"array of objects",description:"parameters that provide the metadata for a given extension. Each object should have name and description, minimally. It can also have a 'type' (eg string, pointer, or array) and required to denote whether or not this parameter must be present on the extension."},
{name:"indexOn",type:"string",description:"You can provide an 'indexOn' property to name a property of extensions through which you'd like to be able to easily look up the extension."},{name:"register",type:"pointer",description:"function that is called when a new extension is discovered. Note that this should be used sparingly, because it will cause your plugin to be loaded whenever a matching plugin appears."},{name:"unregister",type:"pointer",description:"function that is called when an extension is removed. Note that this should be used sparingly, because it will cause your plugin to be loaded whenever a matching plugin appears."}]},
{ep:"extensionpoint",name:"extensionhandler",register:"plugins#registerExtensionHandler",unregister:"plugins#unregisterExtensionHandler",description:"Used to attach listeners ",params:[{name:"name",type:"string",description:"name of the extension point to listen to",required:true},{name:"register",type:"pointer",description:"function that is called when a new extension is discovered. Note that this should be used sparingly, because it will cause your plugin to be loaded whenever a matching plugin appears."},
{name:"unregister",type:"pointer",description:"function that is called when an extension is removed. Note that this should be used sparingly, because it will cause your plugin to be loaded whenever a matching plugin appears."}]},{ep:"extensionpoint",name:"factory",description:"Provides a factory for singleton components. Each extension needs to provide a name, a pointer and an action. The action can be 'call' (if the pointer refers to a function), 'new' (if the pointer refers to a traditional JS object) or 'value' (if the pointer refers to the object itself that is the component).",
indexOn:"name"},{ep:"factory",name:"hub",action:"create",pointer:"util/hub#Hub"},{ep:"extensionpoint",name:"command",description:"Editor commands/actions. TODO: list parameters here."}]}}});
bespin.tiki.module("bespin:console",function(y,j){y=y("util/util");var x=function(){},E=["assert","count","debug","dir","dirxml","error","group","groupEnd","info","log","profile","profileEnd","time","timeEnd","trace","warn"];if(typeof window==="undefined"){var w={};E.forEach(function(t){w[t]=function(){var h=Array.prototype.slice.call(arguments);postMessage(JSON.stringify({op:"log",method:t,args:h}))}});j.console=w}else if(y.isSafari||y.isChrome)j.console=window.console;else{j.console={};E.forEach(function(t){j.console[t]=
window.console&&window.console[t]?window.console[t]:x})}});
bespin.tiki.module("bespin:globals",function(){if(!Object.defineProperty)Object.defineProperty=function(y,j,x){var E=Object.prototype.hasOwnProperty;if(typeof x=="object"&&y.__defineGetter__){if(E.call(x,"value")){if(!y.__lookupGetter__(j)&&!y.__lookupSetter__(j))y[j]=x.value;if(E.call(x,"get")||E.call(x,"set"))throw new TypeError("Object doesn't support this action");}else typeof x.get=="function"&&y.__defineGetter__(j,x.get);typeof x.set=="function"&&y.__defineSetter__(j,x.set)}return y};if(!Object.defineProperties)Object.defineProperties=
function(y,j){for(var x in j)Object.prototype.hasOwnProperty.call(j,x)&&Object.defineProperty(y,x,j[x]);return y};(function(){if(!Array.isArray)Array.isArray=function(y){return y&&Object.prototype.toString.call(y)=="[object Array]"};if(!Object.keys)Object.keys=function(y){var j,x=[];for(j in y)y.hasOwnProperty(j)&&x.push(j);return x};if(!Function.prototype.bind)Function.prototype.bind=function(){var y=Array.prototype.slice.call(arguments),j=this,x=function(){return j.call.apply(j,y.concat(Array.prototype.slice.call(arguments)))};
x.name=this.name;x.displayName=this.displayName;x.length=this.length;x.unbound=j;return x}})()});bespin.tiki.module("bespin:index",function(y,j){j.versionNumber="0.9a1";j.versionCodename="Edison";j.apiVersion="4"});
bespin.tiki.module("bespin:plugins",function(y,j){y("globals");var x=y("promise").Promise,E=y("promise").group,w=y("builtins"),t=y("console").console,h=y("util/util");y("util/stacktrace");var o=y("proxy"),s=y.loader.sources[0],C=function(f,g){if(g){g=g.split("#");return{modName:g[0]?f+":"+g[0]:f,objName:g[1]}}},v=function(f){var g=y(f.modName);if(f.objName)return g[f.objName];return g};j.Extension=function(f){this.pluginName=null;for(property in f)if(f.hasOwnProperty(property))this[property]=f[property];
this._observers=[]};j.Extension.prototype={load:function(f,g,n){n=n||j.catalog;var p=new x,u=function(I){f&&f(I);p.resolve(I)};g=this[g||"pointer"];if(h.isFunction(g)){u(g);return p}var A=C(this.pluginName,g);if(!A){t.error("Extension cannot be loaded because it has no 'pointer'");t.log(this);p.reject(new Error("Extension has no 'pointer' to call"));return p}var L=this.pluginName;n.loadPlugin(L).then(function(){y.ensure(A.modName,function(){var I=v(A);u(I)})},function(I){t.error("Failed to load plugin ",
L,I)});return p},observe:function(f,g,n){this._observers.push({plugin:f,callback:g,property:n});this.load(g,n)},getPluginName:function(){return this.pluginName},_getLoaded:function(f){f=this._getPointer(f);return v(f)}};j.ExtensionPoint=function(f,g){this.name=f;this.catalog=g;this.indexOn=this.pluginName=undefined;this.extensions=[];this.handlers=[]};j.ExtensionPoint.prototype={getImplementingPlugins:function(){var f={};this.extensions.forEach(function(n){f[n.pluginName]=true});var g=Object.keys(f);
g.sort();return g},getDefiningPluginName:function(){return this.pluginName},getByKey:function(f){var g=this.indexOn;if(g)for(var n=0;n<this.extensions.length;n++)if(this.extensions[n][g]==f)return this.extensions[n]},register:function(f){var g=this.catalog;this.extensions.push(f);this.handlers.forEach(function(n){n.register&&n.load(function(p){p?p(f,g):t.error("missing register function for pluginName=",f.pluginName,", extension=",f.name)},"register",g)})},unregister:function(f){var g=this.catalog;
this.extensions.splice(this.extensions.indexOf(f),1);this.handlers.forEach(function(n){n.unregister&&n.load(function(p){p?p(f,g):t.error("missing unregister function for pluginName=",f.pluginName,", extension=",f.name)},"unregister",g)})},orderExtensions:function(f){for(var g=[],n=0;n<f.length;n++)for(var p=0;p!=this.extensions.length;)if(this.extensions[p].pluginName===f[n]){g.push(this.extensions[p]);this.extensions.splice(p,1)}else p++;this.extensions=g.concat(this.extensions)}};j.Plugin=function(f){this.name=
this.catalog=null;this.provides=[];this.stylesheets=[];this.reloadPointer=this.reloadURL=null;for(property in f)if(f.hasOwnProperty(property))this[property]=f[property]};j.Plugin.prototype={register:function(){this.provides.forEach(function(f){this.catalog.getExtensionPoint(f.ep,true).register(f)},this)},unregister:function(){this.provides.forEach(function(f){this.catalog.getExtensionPoint(f.ep,true).unregister(f)},this)},_getObservers:function(){var f={};this.provides.forEach(function(g){t.log("ep: ",
g.ep);t.log(g._observers);f[g.ep]=g._observers});return f},_findDependents:function(f,g,n){var p=this.name,u=this;f.forEach(function(A){if(A!=p){var L=u.catalog.plugins[A];if(L&&L.dependencies)for(dependName in L.dependencies)if(dependName==p&&!g[A]){g[A]={keepModule:false};n||L._findDependents(f,g)}}})},_cleanup:function(f){this.stylesheets.forEach(function(L){for(var I=document.getElementsByTagName("link"),N=0;N<I.length;N++)if(I[N].href.indexOf(L.url)!=-1){I[N].parentNode.removeChild(I[N]);break}});
var g=this.name,n=new RegExp("^"+g+"$"),p=new RegExp("^::"+g+":");g=new RegExp("^::"+g+"$");var u=y.sandbox,A=y.loader;if(!f){F(p,A.factories);F(g,A.canonicalIds);F(g,A.canonicalPackageIds);F(g,A.packageSources);F(g,A.packages);F(n,s.packageInfoByName);F(p,s.factories);F(p,s.scriptActions);F(p,s.stylesheetActions);F(g,s.packages);F(g,s.ensureActions);F(g,s.packageInfoById)}F(p,u.exports);F(p,u.modules);F(p,u.usedExports)},reload:function(f){if(this.reloadURL){if(this.reloadPointer){var g=C(this.name,
this.reloadPointer);if(func=v(g))func();else{t.error("Reload function could not be loaded. Aborting reload.");return}}var n={};this._findDependents(Object.keys(this.catalog.plugins),n);var p={pluginName:this.name,dependents:n};for(var u in n){g=this.catalog.plugins[u];if(g.preRefresh){g=C(u,g.preRefresh);if(func=v(g))n[u]=func(p)}}this.unregister();for(u in n)this.catalog.plugins[u].unregister();this._cleanup(this.name);g=[];var A=y.sandbox,L=Object.keys(A.modules),I=L.length,N=[];for(u in n)n[u].keepModule||
N.push(new RegExp("^::"+u+":"));for(var i=new RegExp("^::"+this.name+":");--I>=0;){var J=L[I];if(i.exec(J))g.push(J);else for(var U=N.length;--U>=0;)if(N[U].exec(J)){g.push(J);break}}g.forEach(function(R){delete A.exports[R];delete A.modules[R];delete A.usedExports[R]});g=function(){this.catalog.loadPlugin(this.name).then(function(){for(u in n)this.catalog.plugins[u].register();for(u in n)if(n[u].callPointer){var R=C(u,n[u].callPointer);(R=v(R))&&R(p)}f&&f()}.bind(this))}.bind(this);L=function(){t.error("Failed to load metadata from "+
this.reloadURL)}.bind(this);this.catalog.loadMetadataFromURL(this.reloadURL).then(g,L)}}};var B=function(f,g,n){g=g.split(".");f=f;var p=g.length-1;if(p>0)for(var u=0;u<p;u++)f=f[g[u]];f[p]=n};j.Catalog=function(){this.points={};this.plugins={};this.metadata={};this.USER_DEACTIVATED="USER";this.DEPENDS_DEACTIVATED="DEPENDS";this.deactivatedPlugins={};this._extensionsOrdering=[];this.instances={};this.instancesLoadPromises={};this._objectDescriptors={};this.children=[];this.getExtensionPoint("extensionpoint",
true).indexOn="name";this.registerMetadata(w.metadata)};j.Catalog.prototype={shareExtension:function(f){return this.plugins[f.pluginName].share},isPluginLoaded:function(f){return Object.keys(y.sandbox.usedExports).some(function(g){return g.indexOf("::"+f+":")==0})},registerObject:function(f,g){this._objectDescriptors[f]=g},_setObject:function(f,g){this.instances[f]=g},createObject:function(f){if(this.instancesLoadPromises[f]!==undefined)return this.instancesLoadPromises[f];var g=this._objectDescriptors[f];
if(g===undefined)throw new Error('Tried to create object "'+f+'" but that object is not registered.');var n=g.factory||f,p=this.getExtensionByKey("factory",n);if(p===undefined)throw new Error('When creating object "'+f+'", there is no factory called "'+n+'" available."');if(this.parent&&this.shareExtension(p))return this.instancesLoadPromises[f]=this.parent.createObject(f);var u=this.instancesLoadPromises[f]=new x,A=g.arguments||[];n=[];if(g.objects){g=g.objects;for(var L in g){var I=this.createObject(g[L]);
n.push(I);I.location=L;I.then(function(N){B(A,I.location,N)})}}E(n).then(function(){p.load().then(function(N){var i=p.action;if(i==="call")N=N.apply(N,A);else if(i==="new"){if(A.length>1){u.reject(new Error("For object "+f+", create a simple factory function and change the action to call because JS cannot handle this case."));return}N=new N(A[0])}else if(i==="value")N=N;else{u.reject(new Error("Create action must be call|new|value. Found"+i));return}this.instances[f]=N;u.resolve(N)}.bind(this))}.bind(this));
return u},getObject:function(f){return this.instances[f]||(this.parent?this.parent.getObject(f):undefined)},getExtensionPoint:function(f,g){if(g&&this.points[f]===undefined)this.points[f]=new j.ExtensionPoint(f,this);return this.points[f]},getExtensions:function(f){f=this.getExtensionPoint(f);if(f===undefined)return[];return f.extensions},orderExtensions:function(f){f=f||this._extensionsOrdering;for(name in this.points)this.points[name].orderExtensions(f);this._extensionsOrdering=f},getExtensionsOrdering:function(){return this._extensionsOrdering},
getExtensionByKey:function(f,g){f=this.getExtensionPoint(f);if(f!==undefined)return f.getByKey(g)},_toposort:function(f){var g=[],n={},p=function(A){if(!(A in n||!(A in f))){n[A]=true;var L=f[A].dependencies;if(!h.none(L))for(var I in L)p(I);g.push(A)}};for(var u in f)p(u);return g},registerMetadata:function(f){if(this.parent)this.parent.registerMetadata(f);else{for(var g in f){var n=f[g];if(n.errors){t.error("Plugin ",g," has errors:");n.errors.forEach(function(p){t.error(p)});delete f[g]}else{if(n.dependencies)n.depends=
Object.keys(n.dependencies);n.name=g;n.version=null;s.canonicalPackageId(g)===null&&s.register("::"+g,n)}}h.mixin(this.metadata,h.clone(f,true));this.children.forEach(function(p){p._registerMetadata(h.clone(f,true))});this._registerMetadata(h.clone(f,true))}},_registerMetadata:function(f){var g,n=this.plugins;this._toposort(f).forEach(function(p){if(this.plugins[p])if(this.isPluginLoaded(p))return;else{var u=this.plugins[p];u.unregister()}var A=f[p],L=!this.deactivatedPlugins[p];if(L&&A.depends&&
A.depends.length!=0)if(!A.depends.some(function(i){return!this.deactivatedPlugins[i]},this)){this.deactivatedPlugins[p]="DEPENDS";L=false}A.catalog=this;A.name=p;u=new j.Plugin(A);n[p]=u;if(A.provides){u=A.provides;for(A=0;A<u.length;A++){var I=new j.Extension(u[A]);I.pluginName=p;u[A]=I;var N=I.ep;if(N=="extensionpoint"&&I.name=="extensionpoint")j.registerExtensionPoint(I,this,false);else if(L)this.getExtensionPoint(I.ep,true).register(I);else N=="extensionpoint"&&j.registerExtensionPoint(I,this,
true)}}else A.provides=[]},this);for(g in f)this._checkLoops(g,n,[]);this.orderExtensions()},loadPlugin:function(f){var g=new x,n=this.plugins[f];if(n.objects){var p=[];n.objects.forEach(function(u){p.push(this.createObject(u))}.bind(this));E(p).then(function(){y.ensurePackage(f,function(){g.resolve()})})}else y.ensurePackage(f,function(u){u?g.reject(u):g.resolve()});return g},loadMetadataFromURL:function(f){var g=new x;o.xhr("GET",f,true).then(function(n){this.registerMetadata(JSON.parse(n));g.resolve()}.bind(this),
function(n){g.reject(n)});return g},deactivatePlugin:function(f,g){var n=this.plugins[f];if(!n){g||(this.deactivatedPlugins[f]="USER");return'There is no plugin named "'+f+'" in this catalog.'}if(this.deactivatedPlugins[f]){g||(this.deactivatedPlugins[f]="USER");return'The plugin "'+f+'" is already deactivated'}this.deactivatedPlugins[f]=g?"DEPENDS":"USER";var p={},u=[];n._findDependents(Object.keys(this.plugins),p,true);Object.keys(p).forEach(function(A){A=this.deactivatePlugin(A,true);if(Array.isArray(A))u=
u.concat(A)},this);n.unregister();g&&u.push(f);return u},activatePlugin:function(f,g){var n=this.plugins[f];if(!n)return'There is no plugin named "'+f+'" in this catalog.';if(!this.deactivatedPlugins[f])return'The plugin "'+f+'" is already activated';if(!(g&&this.deactivatedPlugins[f]==="USER")){if(n.depends&&n.depends.length!=0)if(!n.depends.some(function(A){return!this.deactivatedPlugins[A]},this)){this.deactivatedPlugins[f]="DEPENDS";return'Can not activate plugin "'+f+'" as some of its dependent plugins are not activated'}n.register();
this.orderExtensions();delete this.deactivatedPlugins[f];var p=[],u={};n._findDependents(Object.keys(this.plugins),u,true);Object.keys(u).forEach(function(A){A=this.activatePlugin(A,true);if(Array.isArray(A))p=p.concat(A)},this);g&&p.push(f);return p}},removePlugin:function(f){var g=this.plugins[f];if(g==undefined)throw new Error("Attempted to remove plugin "+f+" which does not exist.");g.unregister();g._cleanup(true);delete this.metadata[f];delete this.plugins[f]},getResourceURL:function(f){var g=
document.getElementById("bespin_base"),n="";if(g){n+=g.href;h.endsWith(n,"/")||(n+="/")}f=this.plugins[f];if(f!=undefined)return n+f.resourceURL},_checkLoops:function(f,g,n){var p=false;n.forEach(function(L){if(f===L){t.error("Circular dependency",f,n);p=true}});if(p)return true;n.push(f);if(g[f]){if(g[f].dependencies)for(var u in g[f].dependencies){var A=n.slice();if(this._checkLoops(u,g,A)){t.error("Errors found when looking at ",f);return true}}}else t.error("Missing metadata for ",f);return false},
getPlugins:function(f){var g=[],n=f.onlyType;for(var p in this.plugins){var u=this.plugins[p];n&&u.type&&u.type!=n||u.name=="bespin"||g.push(u)}var A=f.sortBy;A||(A=["name"]);g.sort(function(L,I){for(var N=0;N<A.length;N++){p=A[N];if(L[p]<I[p])return-1;else if(I[p]<L[p])return 1}return 0});return g},loadObjectForPropertyPath:function(f,g){var n=new x,p=/^([^:]+):([^#]+)#(.*)$/.exec(f);if(p===null)throw new Error("loadObjectForPropertyPath: malformed path: '"+f+"'");p=p[1];if(p===""){if(h.none(g))throw new Error("loadObjectForPropertyPath: no plugin name supplied and no context is present");
p=g}y.ensurePackage(p,function(){n.resolve(this.objectForPropertyPath(f))}.bind(this));return n},objectForPropertyPath:function(f,g,n){n=n==undefined?f.length:n;g||(g=window);var p=f.split("#");if(p.length!==1){g=y(p[0]);if(g===undefined)return;f=p[1];g=g;n-=p[0].length}for(var u=0;g&&u<n;){p=f.indexOf(".",u);if(p<0||p>n)p=n;u=f.slice(u,p);g=g[u];u=p+1}if(u<n)g=undefined;return g},publish:function(f,g,n,p){if(this.shareExtension(this.getExtensionPoint(g)))if(this.parent)this.parent.publish(f,g,n,
p);else{this.children.forEach(function(u){u._publish(f,g,n,p)});this._publish(f,g,n,p)}else this._publish(f,g,n,p)},_publish:function(f,g,n,p){this.getExtensions(g).forEach(function(u){if(u.match&&!u.regexp)u.regexp=new RegExp(u.match);if(u.regexp&&u.regexp.test(n)||u.key===n||h.none(u.key)&&h.none(n))u.load().then(function(A){A(f,n,p)})})},registerExtension:function(f,g){g=new j.Extension(g);g.pluginName="__dynamic";this.getExtensionPoint(f).register(g)}};j.registerExtensionPoint=function(f,g,n){var p=
g.getExtensionPoint(f.name,true);p.description=f.description;p.pluginName=f.pluginName;p.params=f.params;if(f.indexOn)p.indexOn=f.indexOn;if(!n&&(f.register||f.unregister))j.registerExtensionHandler(f,g)};j.registerExtensionHandler=function(f,g){if(!(g.parent&&g.shareExtension(f))){var n=g.getExtensionPoint(f.name,true);n.handlers.push(f);if(f.register){var p=h.clone(n.extensions);f.load(function(u){if(!u)throw f.name+" is not ready";p.forEach(function(A){u(A,g)})},"register",g)}}};j.unregisterExtensionPoint=
function(f){if(f.register||f.unregister)j.unregisterExtensionHandler(f)};j.unregisterExtensionHandler=function(f,g){if(!(g.parent&&g.shareExtension(f))){g=g.getExtensionPoint(f.name,true);if(g.handlers.indexOf(f)!=-1){g.handlers.splice(g.handlers.indexOf(f),1);if(f.unregister){var n=h.clone(g.extensions);f.load(function(p){if(!p)throw f.name+" is not ready";n.forEach(function(u){p(u)})},"unregister")}}}};j.catalog=new j.Catalog;var F=function(f,g){for(var n=Object.keys(g),p=n.length;--p>0;)f.exec(n[p])&&
delete g[n[p]]};j.getUserPlugins=function(){return j.catalog.getPlugins({onlyType:"user"})}});
bespin.tiki.module("bespin:promise",function(y,j){var x=y("bespin:console").console;y("bespin:util/stacktrace");var E=0;j._outstanding=[];j._recent=[];j.Promise=function(){this._status=0;this._value=undefined;this._onSuccessHandlers=[];this._onErrorHandlers=[];this._id=E++;j._outstanding[this._id]=this};j.Promise.prototype.isPromise=true;j.Promise.prototype.isComplete=function(){return this._status!=0};j.Promise.prototype.isResolved=function(){return this._status==1};j.Promise.prototype.isRejected=
function(){return this._status==-1};j.Promise.prototype.then=function(w,t){if(typeof w==="function")if(this._status===1)w.call(null,this._value);else this._status===0&&this._onSuccessHandlers.push(w);if(typeof t==="function")if(this._status===-1)t.call(null,this._value);else this._status===0&&this._onErrorHandlers.push(t);return this};j.Promise.prototype.chainPromise=function(w){var t=new j.Promise;t._chainedFrom=this;this.then(function(h){try{t.resolve(w(h))}catch(o){t.reject(o)}},function(h){t.reject(h)});
return t};j.Promise.prototype.resolve=function(w){return this._complete(this._onSuccessHandlers,1,w,"resolve")};j.Promise.prototype.reject=function(w){return this._complete(this._onErrorHandlers,-1,w,"reject")};j.Promise.prototype._complete=function(w,t,h,o){if(this._status!=0){x.group("Promise already closed");x.error("Attempted "+o+"() with ",h);x.error("Previous status = ",this._status,", previous value = ",this._value);x.trace();if(this._completeTrace){x.error("Trace of previous completion:");
this._completeTrace.log(5)}x.groupEnd();return this}this._status=t;this._value=h;w.forEach(function(s){s.call(null,this._value)},this);this._onSuccessHandlers.length=0;this._onErrorHandlers.length=0;delete j._outstanding[this._id];for(j._recent.push(this);j._recent.length>20;)j._recent.shift();return this};j.group=function(w){w instanceof Array||(w=Array.prototype.slice.call(arguments));if(w.length===0)return(new j.Promise).resolve([]);var t=new j.Promise,h=[],o=0,s=function(C){return function(v){h[C]=
v;o++;t._status!==-1&&o===w.length&&t.resolve(h)}};w.forEach(function(C,v){v=s(v);var B=t.reject.bind(t);C.then(v,B)});return t}});
bespin.tiki.module("bespin:proxy",function(y,j){y("util/util");var x=y("promise").Promise;j.xhr=function(E,w,t,h){var o=new x;if(!bespin.proxy||!bespin.proxy.xhr){var s=new XMLHttpRequest;s.onreadystatechange=function(){if(s.readyState===4){var C=s.status;if(C!==0&&C!==200){C=new Error(s.responseText+" (Status "+s.status+")");C.xhr=s;o.reject(C)}else o.resolve(s.responseText)}}.bind(this);s.open("GET",w,t);h&&h(s);s.send()}else bespin.proxy.xhr.call(this,E,w,t,h,o);return o};j.Worker=function(E){return!bespin.proxy||
!bespin.proxy.worker?new Worker(E):new bespin.proxy.worker(E)}});
bespin.tiki.module("bespin:sandbox",function(y,j){var x=y("tiki"),E=y("bespin:util/util"),w=y("bespin:plugins").catalog;if(w.parent)throw new Error("The sandbox module can't be used inside of a slave catalog!");y=function(){x.Sandbox.call(this,bespin.tiki.require.loader,{},[]);var t=this.require("bespin:plugins").catalog;t.parent=w;w.children.push(t);t.deactivatePlugin=E.clone(w.deactivatePlugin);t._extensionsOrdering=E.clone(w._extensionsOrdering);t._registerMetadata(E.clone(w.metadata,true))};y.prototype=
new x.Sandbox;y.prototype.require=function(t,h,o){var s=this.loader.canonical(t,h,o).substring(2).split(":")[0];return w.plugins[s].share?bespin.tiki.sandbox.require(t,h,o):x.Sandbox.prototype.require.call(this,t,h,o)};j.Sandbox=y});
bespin.tiki.module("bespin:util/cookie",function(y,j){var x=function(E,w){return E.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,function(t){if(w&&w.indexOf(t)!=-1)return t;return"\\"+t})};j.get=function(E){E=new RegExp("(?:^|; )"+x(E)+"=([^;]*)");return(E=document.cookie.match(E))?decodeURIComponent(E[1]):undefined};j.set=function(E,w,t){t=t||{};if(typeof t.expires=="number"){var h=new Date;h.setTime(h.getTime()+t.expires*24*60*60*1E3);t.expires=h}if(t.expires&&t.expires.toUTCString)t.expires=t.expires.toUTCString();
w=encodeURIComponent(w);E=E+"="+w;var o;for(o in t){E+="; "+o;w=t[o];if(w!==true)E+="="+w}document.cookie=E};j.remove=function(E){j.set(E,"",{expires:-1})};j.isSupported=function(){if(!("cookieEnabled"in navigator)){j.set("__djCookieTest__","CookiesAllowed");navigator.cookieEnabled=j.get("__djCookieTest__")=="CookiesAllowed";navigator.cookieEnabled&&j.remove("__djCookieTest__")}return navigator.cookieEnabled}});
bespin.tiki.module("bespin:util/scratchcanvas",function(y,j){var x=y("bespin:util/util"),E=function(){this._canvas=document.getElementById("bespin-scratch-canvas");if(x.none(this._canvas)){this._canvas=document.createElement("canvas");this._canvas.id="bespin-scratch-canvas";this._canvas.width=400;this._canvas.height=300;this._canvas.style.position="absolute";this._canvas.style.top="-10000px";this._canvas.style.left="-10000px";document.body.appendChild(this._canvas)}};E.prototype.getContext=function(){return this._canvas.getContext("2d")};
E.prototype.measureStringWidth=function(t,h){if(x.none(h))h="M";var o=this.getContext();o.save();o.font=t;t=o.measureText(h).width;o.restore();return t};var w=null;j.get=function(){if(w===null)w=new E;return w}});
bespin.tiki.module("bespin:util/stacktrace",function(y,j){function x(v){for(var B=0;B<v.length;++B){var F=v[B];if(typeof F=="object")v[B]="#object";else if(typeof F=="function")v[B]="#function";else if(typeof F=="string")v[B]='"'+F+'"'}return v.join(",")}function E(){}var w=y("bespin:util/util"),t=y("bespin:console").console,h=function(){if(w.isMozilla)return"firefox";else if(w.isOpera)return"opera";else if(w.isSafari)return"other";try{0()}catch(v){if(v.arguments)return"chrome";if(v.stack)return"firefox";
if(window.opera&&!("stacktrace"in v))return"opera"}return"other"}(),o={chrome:function(v){var B=v.stack;if(!B){t.log(v);return[]}return B.replace(/^.*?\n/,"").replace(/^.*?\n/,"").replace(/^.*?\n/,"").replace(/^[^\(]+?[\n$]/gm,"").replace(/^\s+at\s+/gm,"").replace(/^Object.<anonymous>\s*\(/gm,"{anonymous}()@").split("\n")},firefox:function(v){var B=v.stack;if(!B){t.log(v);return[]}B=B.replace(/(?:\n@:0)?\s+$/m,"");B=B.replace(/^\(/gm,"{anonymous}(");return B.split("\n")},opera:function(v){v=v.message.split("\n");
var B=/Line\s+(\d+).*?script\s+(http\S+)(?:.*?in\s+function\s+(\S+))?/i,F,f,g;F=4;f=0;for(g=v.length;F<g;F+=2)if(B.test(v[F]))v[f++]=(RegExp.$3?RegExp.$3+"()@"+RegExp.$2+RegExp.$1:"{anonymous}()@"+RegExp.$2+":"+RegExp.$1)+" -- "+v[F+1].replace(/^\s+/,"");v.splice(f,v.length-f);return v},other:function(v){for(var B=/function\s*([\w\-$]+)?\s*\(/i,F=[],f=0,g,n;v&&F.length<10;){g=B.test(v.toString())?RegExp.$1||"{anonymous}":"{anonymous}";n=Array.prototype.slice.call(v.arguments);F[f++]=g+"("+x(n)+")";
if(v===v.caller&&window.opera)break;v=v.caller}return F}};E.prototype={sourceCache:{},ajax:function(v){var B=this.createXMLHTTPObject();if(B){B.open("GET",v,false);B.setRequestHeader("User-Agent","XMLHTTP/1.0");B.send("");return B.responseText}},createXMLHTTPObject:function(){for(var v,B=[function(){return new XMLHttpRequest},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml3.XMLHTTP")},function(){return new ActiveXObject("Microsoft.XMLHTTP")}],F=0;F<
B.length;F++)try{v=B[F]();this.createXMLHTTPObject=B[F];return v}catch(f){}},getSource:function(v){v in this.sourceCache||(this.sourceCache[v]=this.ajax(v).split("\n"));return this.sourceCache[v]},guessFunctions:function(v){for(var B=0;B<v.length;++B){var F=v[B],f=/{anonymous}\(.*\)@(\w+:\/\/([-\w\.]+)+(:\d+)?[^:]+):(\d+):?(\d+)?/.exec(F);if(f){var g=f[1];f=f[4];if(g&&f){g=this.guessFunctionName(g,f);v[B]=F.replace("{anonymous}",g)}}}return v},guessFunctionName:function(v,B){try{return this.guessFunctionNameFromLines(B,
this.getSource(v))}catch(F){return"getSource failed with url: "+v+", exception: "+F.toString()}},guessFunctionNameFromLines:function(v,B){for(var F=/function ([^(]*)\(([^)]*)\)/,f=/['"]?([0-9A-Za-z_]+)['"]?\s*[:=]\s*(function|eval|new Function)/,g="",n=0;n<10;++n){g=B[v-n]+g;if(g!==undefined){var p=f.exec(g);if(p)return p[1];else p=F.exec(g);if(p&&p[1])return p[1]}}return"(?)"}};var s=new E,C=[/http:\/\/localhost:4020\/sproutcore.js:/];j.ignoreFramesMatching=function(v){C.push(v)};j.Trace=function(v,
B){this._ex=v;this._stack=o[h](v);if(B)this._stack=s.guessFunctions(this._stack)};j.Trace.prototype.log=function(v){if(v<=0)v=999999999;for(var B=0,F=0;F<this._stack.length&&B<v;F++){var f=this._stack[F],g=true;C.forEach(function(n){if(n.test(f))g=false});if(g){t.debug(f);B++}}}});
bespin.tiki.module("bespin:util/util",function(y,j){j.queryToObject=function(h,o){var s={};h=h.split(o||"&");var C=decodeURIComponent;h.forEach(function(v){if(v.length){var B=v.split("=");v=C(B.shift());B=C(B.join("="));if(j.isString(s[v]))s[v]=[s[v]];if(Array.isArray(s[v]))s[v].push(B);else s[v]=B}});return s};j.objectToQuery=function(h){var o=encodeURIComponent,s=[],C={};for(var v in h){var B=h[v];if(B!=C[v]){var F=o(v)+"=";if(B.isArray)for(var f=0;f<B.length;f++)s.push(F+o(B[f]));else s.push(F+
o(B))}}return s.join("&")};var x=0,E={};j.rateLimit=function(h,o,s){if(h){var C=x++;return function(){E[C]&&clearTimeout(E[C]);E[C]=setTimeout(function(){s.apply(o,arguments);delete E[C]},h)}}};j.isString=function(h){return typeof h=="string"||h instanceof String};j.isBoolean=function(h){return typeof h=="boolean"};j.isNumber=function(h){return typeof h=="number"&&isFinite(h)};j.isObject=function(h){return h!==undefined&&(h===null||typeof h=="object"||Array.isArray(h)||j.isFunction(h))};j.isFunction=
function(){var h=function(o){var s=typeof o;return o&&(s=="function"||o instanceof Function)&&!o.nodeType};return j.isSafari?function(o){if(typeof o=="function"&&o=="[object NodeList]")return false;return h(o)}:h}();j.endsWith=function(h,o){if(!h)return false;return h.match(new RegExp(o+"$"))};j.include=function(h,o){return h.indexOf(o)>-1};j.indexOfProperty=function(h,o,s){for(var C=0;C<h.length;C++)if(h[C][o]==s)return C;return null};j.last=function(h){if(Array.isArray(h))return h[h.length-1]};
j.shrinkArray=function(h){var o=[],s=true;h.reverse().forEach(function(C){if(!(s&&C===undefined)){s=false;o.push(C)}});return o.reverse()};j.makeArray=function(h,o){if(h<1)return[];o||(o=" ");for(var s=[],C=0;C<h;C++)s.push(o);return s};j.repeatString=function(h,o){for(var s="",C=0;C<o;C++)s+=h;return s};j.leadingSpaces=function(h){for(var o=0,s=0;s<h.length;s++)if(h[s]==" "||h[s]==""||h[s]===undefined)o++;else return o;return o};j.leadingTabs=function(h){for(var o=0,s=0;s<h.length;s++)if(h[s]=="\t"||
h[s]==""||h[s]===undefined)o++;else return o;return o};j.leadingWhitespace=function(h){for(var o=[],s=0;s<h.length;s++)if(h[s]==" "||h[s]=="\t"||h[s]==""||h[s]===undefined)o.push(h[s]);else return o;return o};j.englishFromCamel=function(h){h.replace(/([A-Z])/g,function(o){return" "+o.toLowerCase()}).trim()};j.OS={LINUX:"LINUX",MAC:"MAC",WINDOWS:"WINDOWS"};y=navigator.userAgent;var w=navigator.appVersion;j.isLinux=w.indexOf("Linux")>=0;j.isWindows=w.indexOf("Win")>=0;j.isWebKit=parseFloat(y.split("WebKit/")[1])||
undefined;j.isChrome=parseFloat(y.split("Chrome/")[1])||undefined;j.isMac=w.indexOf("Macintosh")>=0;j.isMozilla=w.indexOf("Gecko/")>=0;if(y.indexOf("AdobeAIR")>=0)j.isAIR=1;var t=Math.max(w.indexOf("WebKit"),w.indexOf("Safari"),0);if(t&&!j.isChrome){j.isSafari=parseFloat(w.split("Version/")[1]);if(!j.isSafari||parseFloat(w.substr(t+7))<=419.3)j.isSafari=2}if(y.indexOf("Gecko")>=0&&!j.isWebKit)j.isMozilla=parseFloat(w);j.getOS=function(){return j.isMac?j.OS.MAC:j.isLinux?j.OS.LINUX:j.OS.WINDOWS};j.contains=
typeof document!=="undefined"&&document.compareDocumentPosition?function(h,o){return h.compareDocumentPosition(o)&16}:function(h,o){return h!==o&&(h.contains?h.contains(o):true)};j.stopEvent=function(h){h.preventDefault();h.stopPropagation()};j.randomPassword=function(h){h=h||16;for(var o="",s=0;s<h;s++){var C=Math.floor(Math.random()*62);o+="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".charAt(C)}return o};j.isEmpty=function(h){for(var o in h)if(h.hasOwnProperty(o))return false;
return true};j.isMyProject=function(h){return h.indexOf("+")==-1};j.formatDate=function(h){if(!h)return"Unknown";return h.getDate()+" "+j.formatDate.shortMonths[h.getMonth()]+" "+h.getFullYear()};j.formatDate.shortMonths=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];j.addClass=function(h,o){o=o.split(/\s+/);for(var s=" "+h.className+" ",C=0,v=o.length,B;C<v;++C)if((B=o[C])&&s.indexOf(" "+B+" ")<0)s+=B+" ";h.className=s.trim()};j.removeClass=function(h,o){if(o!==undefined){var s=
o.split(/\s+/);o=" "+h.className+" ";for(var C=0,v=s.length;C<v;++C)o=o.replace(" "+s[C]+" "," ");o=o.trim()}else o="";if(h.className!=o)h.className=o};j.setClass=function(h,o,s){s?j.addClass(h,o):j.removeClass(h,o)};j.none=function(h){return h===null||h===undefined};j.clone=function(h,o){if(Array.isArray(h)&&!o)return h.slice();if(typeof h==="object"||Array.isArray(h)){if(h===null)return null;var s=Array.isArray(h)?[]:{};for(var C in h)s[C]=o&&(typeof h[C]==="object"||Array.isArray(h[C]))?j.clone(h[C],
true):h[C];return s}if(h.clone&&typeof h.clone==="function")return h.clone();return h};j.mixin=function(h,o){for(var s in o){var C=o.__lookupGetter__(s),v=o.__lookupSetter__(s);if(C||v){C&&h.__defineGetter__(s,C);v&&h.__defineSetter__(s,v)}else h[s]=o[s]}return h};j.replace=function(h,o,s,C){return h.slice(0,o).concat(C).concat(h.slice(o+s))};j.rectsEqual=function(h,o,s){if(!h||!o)return h==o;if(!s&&s!==0)s=0.1;if(h.y!=o.y&&Math.abs(h.y-o.y)>s)return false;if(h.x!=o.x&&Math.abs(h.x-o.x)>s)return false;
if(h.width!=o.width&&Math.abs(h.width-o.width)>s)return false;if(h.height!=o.height&&Math.abs(h.height-o.height)>s)return false;return true}});bespin.tiki.register("::syntax_directory",{name:"syntax_directory",dependencies:{}});
bespin.tiki.module("syntax_directory:index",function(y,j){function x(t){this.extension=t;this.name=t.name;this.fileExts=t.hasOwnProperty("fileexts")?t.fileexts:[]}function E(t){w.register(t)}y("bespin:plugins");var w={_fileExts:{},_syntaxInfo:{},get:function(t){return this._syntaxInfo[t]},hasSyntax:function(t){return this._syntaxInfo.hasOwnProperty(t)},register:function(t){var h=new x(t);this._syntaxInfo[h.name]=h;var o=this._fileExts;h.fileExts.forEach(function(s){o[s]=h.name})},syntaxForFileExt:function(t){t=
t.toLowerCase();var h=this._fileExts;return h.hasOwnProperty(t)?h[t]:"plain"}};j.syntaxDirectory=w;j.discoveredNewSyntax=E});bespin.tiki.register("::underscore",{name:"underscore",dependencies:{}});
bespin.tiki.module("underscore:index",function(y,j){(function(){var x=this,E=x._,w=typeof StopIteration!=="undefined"?StopIteration:"__break__",t=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},h=Array.prototype,o=Object.prototype,s=h.slice,C=h.unshift,v=o.toString,B=o.hasOwnProperty,F=h.forEach,f=h.map,g=h.reduce,n=h.reduceRight,p=h.filter,u=h.every,A=h.some,L=h.indexOf,I=h.lastIndexOf;o=Array.isArray;var N=Object.keys,i=function(e){return new R(e)};if(typeof j!=="undefined")j._=
i;x._=i;i.VERSION="1.0.2";var J=i.forEach=function(e,k,r){try{if(F&&e.forEach===F)e.forEach(k,r);else if(i.isNumber(e.length))for(var q=0,G=e.length;q<G;q++)k.call(r,e[q],q,e);else for(q in e)B.call(e,q)&&k.call(r,e[q],q,e)}catch(K){if(K!=w)throw K;}return e};i.map=function(e,k,r){if(f&&e.map===f)return e.map(k,r);var q=[];J(e,function(G,K,P){q.push(k.call(r,G,K,P))});return q};i.reduce=function(e,k,r,q){if(g&&e.reduce===g)return e.reduce(i.bind(r,q),k);J(e,function(G,K,P){k=r.call(q,k,G,K,P)});return k};
i.reduceRight=function(e,k,r,q){if(n&&e.reduceRight===n)return e.reduceRight(i.bind(r,q),k);e=i.clone(i.toArray(e)).reverse();return i.reduce(e,k,r,q)};i.detect=function(e,k,r){var q;J(e,function(G,K,P){if(k.call(r,G,K,P)){q=G;i.breakLoop()}});return q};i.filter=function(e,k,r){if(p&&e.filter===p)return e.filter(k,r);var q=[];J(e,function(G,K,P){k.call(r,G,K,P)&&q.push(G)});return q};i.reject=function(e,k,r){var q=[];J(e,function(G,K,P){!k.call(r,G,K,P)&&q.push(G)});return q};i.every=function(e,k,
r){k=k||i.identity;if(u&&e.every===u)return e.every(k,r);var q=true;J(e,function(G,K,P){(q=q&&k.call(r,G,K,P))||i.breakLoop()});return q};i.some=function(e,k,r){k=k||i.identity;if(A&&e.some===A)return e.some(k,r);var q=false;J(e,function(G,K,P){if(q=k.call(r,G,K,P))i.breakLoop()});return q};i.include=function(e,k){if(L&&e.indexOf===L)return e.indexOf(k)!=-1;var r=false;J(e,function(q){if(r=q===k)i.breakLoop()});return r};i.invoke=function(e,k){var r=i.rest(arguments,2);return i.map(e,function(q){return(k?
q[k]:q).apply(q,r)})};i.pluck=function(e,k){return i.map(e,function(r){return r[k]})};i.max=function(e,k,r){if(!k&&i.isArray(e))return Math.max.apply(Math,e);var q={computed:-Infinity};J(e,function(G,K,P){K=k?k.call(r,G,K,P):G;K>=q.computed&&(q={value:G,computed:K})});return q.value};i.min=function(e,k,r){if(!k&&i.isArray(e))return Math.min.apply(Math,e);var q={computed:Infinity};J(e,function(G,K,P){K=k?k.call(r,G,K,P):G;K<q.computed&&(q={value:G,computed:K})});return q.value};i.sortBy=function(e,
k,r){return i.pluck(i.map(e,function(q,G,K){return{value:q,criteria:k.call(r,q,G,K)}}).sort(function(q,G){q=q.criteria;G=G.criteria;return q<G?-1:q>G?1:0}),"value")};i.sortedIndex=function(e,k,r){r=r||i.identity;for(var q=0,G=e.length;q<G;){var K=q+G>>1;r(e[K])<r(k)?(q=K+1):(G=K)}return q};i.toArray=function(e){if(!e)return[];if(e.toArray)return e.toArray();if(i.isArray(e))return e;if(i.isArguments(e))return s.call(e);return i.values(e)};i.size=function(e){return i.toArray(e).length};i.first=function(e,
k,r){return k&&!r?s.call(e,0,k):e[0]};i.rest=function(e,k,r){return s.call(e,i.isUndefined(k)||r?1:k)};i.last=function(e){return e[e.length-1]};i.compact=function(e){return i.filter(e,function(k){return!!k})};i.flatten=function(e){return i.reduce(e,[],function(k,r){if(i.isArray(r))return k.concat(i.flatten(r));k.push(r);return k})};i.without=function(e){var k=i.rest(arguments);return i.filter(e,function(r){return!i.include(k,r)})};i.uniq=function(e,k){return i.reduce(e,[],function(r,q,G){if(0==G||
(k===true?i.last(r)!=q:!i.include(r,q)))r.push(q);return r})};i.intersect=function(e){var k=i.rest(arguments);return i.filter(i.uniq(e),function(r){return i.every(k,function(q){return i.indexOf(q,r)>=0})})};i.zip=function(){for(var e=i.toArray(arguments),k=i.max(i.pluck(e,"length")),r=new Array(k),q=0;q<k;q++)r[q]=i.pluck(e,String(q));return r};i.indexOf=function(e,k){if(L&&e.indexOf===L)return e.indexOf(k);for(var r=0,q=e.length;r<q;r++)if(e[r]===k)return r;return-1};i.lastIndexOf=function(e,k){if(I&&
e.lastIndexOf===I)return e.lastIndexOf(k);for(var r=e.length;r--;)if(e[r]===k)return r;return-1};i.range=function(e,k,r){var q=i.toArray(arguments),G=q.length<=1;e=G?0:q[0];k=G?q[0]:q[1];r=q[2]||1;q=Math.ceil((k-e)/r);if(q<=0)return[];q=new Array(q);G=e;for(var K=0;;G+=r){if((r>0?G-k:k-G)>=0)return q;q[K++]=G}};i.bind=function(e,k){var r=i.rest(arguments,2);return function(){return e.apply(k||{},r.concat(i.toArray(arguments)))}};i.bindAll=function(e){var k=i.rest(arguments);if(k.length==0)k=i.functions(e);
J(k,function(r){e[r]=i.bind(e[r],e)});return e};i.delay=function(e,k){var r=i.rest(arguments,2);return setTimeout(function(){return e.apply(e,r)},k)};i.defer=function(e){return i.delay.apply(i,[e,1].concat(i.rest(arguments)))};i.wrap=function(e,k){return function(){var r=[e].concat(i.toArray(arguments));return k.apply(k,r)}};i.compose=function(){var e=i.toArray(arguments);return function(){for(var k=i.toArray(arguments),r=e.length-1;r>=0;r--)k=[e[r].apply(this,k)];return k[0]}};i.keys=N||function(e){if(i.isArray(e))return i.range(0,
e.length);var k=[];for(var r in e)B.call(e,r)&&k.push(r);return k};i.values=function(e){return i.map(e,i.identity)};i.functions=function(e){return i.filter(i.keys(e),function(k){return i.isFunction(e[k])}).sort()};i.extend=function(e){J(i.rest(arguments),function(k){for(var r in k)e[r]=k[r]});return e};i.clone=function(e){if(i.isArray(e))return e.slice(0);return i.extend({},e)};i.tap=function(e,k){k(e);return e};i.isEqual=function(e,k){if(e===k)return true;var r=typeof e;if(r!=typeof k)return false;
if(e==k)return true;if(!e&&k||e&&!k)return false;if(e.isEqual)return e.isEqual(k);if(i.isDate(e)&&i.isDate(k))return e.getTime()===k.getTime();if(i.isNaN(e)&&i.isNaN(k))return true;if(i.isRegExp(e)&&i.isRegExp(k))return e.source===k.source&&e.global===k.global&&e.ignoreCase===k.ignoreCase&&e.multiline===k.multiline;if(r!=="object")return false;if(e.length&&e.length!==k.length)return false;r=i.keys(e);var q=i.keys(k);if(r.length!=q.length)return false;for(var G in e)if(!(G in k)||!i.isEqual(e[G],k[G]))return false;
return true};i.isEmpty=function(e){if(i.isArray(e)||i.isString(e))return e.length===0;for(var k in e)if(B.call(e,k))return false;return true};i.isElement=function(e){return!!(e&&e.nodeType==1)};i.isArray=o||function(e){return!!(e&&e.concat&&e.unshift&&!e.callee)};i.isArguments=function(e){return e&&e.callee};i.isFunction=function(e){return!!(e&&e.constructor&&e.call&&e.apply)};i.isString=function(e){return!!(e===""||e&&e.charCodeAt&&e.substr)};i.isNumber=function(e){return e===+e||v.call(e)==="[object Number]"};
i.isBoolean=function(e){return e===true||e===false};i.isDate=function(e){return!!(e&&e.getTimezoneOffset&&e.setUTCFullYear)};i.isRegExp=function(e){return!!(e&&e.test&&e.exec&&(e.ignoreCase||e.ignoreCase===false))};i.isNaN=function(e){return i.isNumber(e)&&isNaN(e)};i.isNull=function(e){return e===null};i.isUndefined=function(e){return typeof e=="undefined"};i.noConflict=function(){x._=E;return this};i.identity=function(e){return e};i.times=function(e,k,r){for(var q=0;q<e;q++)k.call(r,q)};i.breakLoop=
function(){throw w;};i.mixin=function(e){J(i.functions(e),function(k){Q(k,i[k]=e[k])})};var U=0;i.uniqueId=function(e){var k=U++;return e?e+k:k};i.templateSettings={start:"<%",end:"%>",interpolate:/<%=(.+?)%>/g};i.template=function(e,k){var r=i.templateSettings,q=new RegExp("'(?=[^"+r.end.substr(0,1)+"]*"+t(r.end)+")","g");e=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+e.replace(/[\r\t\n]/g," ").replace(q,"\t").split("'").join("\\'").split("\t").join("'").replace(r.interpolate,
"',$1,'").split(r.start).join("');").split(r.end).join("p.push('")+"');}return p.join('');");return k?e(k):e};i.each=i.forEach;i.foldl=i.inject=i.reduce;i.foldr=i.reduceRight;i.select=i.filter;i.all=i.every;i.any=i.some;i.head=i.first;i.tail=i.rest;i.methods=i.functions;var R=function(e){this._wrapped=e},S=function(e,k){return k?i(e).chain():e},Q=function(e,k){R.prototype[e]=function(){var r=i.toArray(arguments);C.call(r,this._wrapped);return S(k.apply(i,r),this._chain)}};i.mixin(i);J(["pop","push",
"reverse","shift","sort","splice","unshift"],function(e){var k=h[e];R.prototype[e]=function(){k.apply(this._wrapped,arguments);return S(this._wrapped,this._chain)}});J(["concat","join","slice"],function(e){var k=h[e];R.prototype[e]=function(){return S(k.apply(this._wrapped,arguments),this._chain)}});R.prototype.chain=function(){this._chain=true;return this};R.prototype.value=function(){return this._wrapped}})();j._.noConflict()});
bespin.tiki.require("bespin:plugins").catalog.registerMetadata({bespin:{testmodules:[],resourceURL:"resources/bespin/",name:"bespin",environments:{main:true,worker:true},type:"plugins/boot"},syntax_directory:{resourceURL:"resources/syntax_directory/",name:"syntax_directory",environments:{main:true,worker:true},dependencies:{},testmodules:[],provides:[{register:"#discoveredNewSyntax",ep:"extensionhandler",name:"syntax"}],type:"plugins/supported",description:"Catalogs the available syntax engines"},
underscore:{testmodules:[],type:"plugins/thirdparty",resourceURL:"resources/underscore/",description:"Functional Programming Aid for Javascript. Works well with jQuery.",name:"underscore"}});typeof window==="undefined"?importScripts("BespinWorker.js"):function(){var y=document.createElement("script");y.setAttribute("src",bespin.base+"BespinMain.js");document.getElementsByTagName("head")[0].appendChild(y)}();

Просмотреть файл

@ -0,0 +1,471 @@
bespin.tiki.register("::text_editor",{name:"text_editor",dependencies:{completion:"0.0.0",undomanager:"0.0.0",settings:"0.0.0",canon:"0.0.0",rangeutils:"0.0.0",traits:"0.0.0",theme_manager:"0.0.0",keyboard:"0.0.0",edit_session:"0.0.0",syntax_manager:"0.0.0"}});
bespin.tiki.module("text_editor:commands/editing",function(y,s){var v=y("settings").settings,r=y("environment").env,l=y("rangeutils:utils/range");s.backspace=function(){r.view.performBackspaceOrDelete(true)};s.deleteCommand=function(){r.view.performBackspaceOrDelete(false)};s.deleteLines=function(){if(!r.model.readOnly)if(r.model.lines.length!=1){var d=r.view;d.groupChanges(function(){var f=d.getSelectedRange(),m=r.model.lines,i=m.length-1,g;g=f.start.row==i?{col:m[i-1].length,row:i-1}:{col:0,row:f.start.row};
d.replaceCharacters({start:g,end:f.end.row==i?{col:m[i].length,row:i}:{col:0,row:f.end.row+1}},"");d.moveCursorTo(g)})}};var h=function(d,f){var m=f.getSelectedRange().start;d=/^\s*/.exec(d.lines[m.row].substring(0,m.col));f.insertText("\n"+d)};s.insertText=function(d){r.view.insertText(d.text)};s.newline=function(){h(r.model,r.view)};s.joinLines=function(){var d=r.model;if(!d.readOnly){var f=r.view,m=f.getSelectedRange(),i=d.lines,g=m.end.row;i.length!=g&&f.groupChanges(function(){f.replaceCharacters({start:{col:i[g].length,
row:g},end:{col:/^\s*/.exec(i[g+1])[0].length,row:g+1}},"")})}};s.openLine=function(){if(!r.model.readOnly){var d=r.model,f=r.view,m=f.getSelectedRange().end.row;f.moveCursorTo({row:m,col:d.lines[m].length});h(d,f)}};s.tab=function(){var d=r.view;d.groupChanges(function(){var f=v.get("tabstop"),m=d.getSelectedRange(),i="";if(l.isZeroLength(m)){var g=r.model.lines[m.start.row].substring(m.start.col).match(/^\s*/)[0].length;f=f-(m.start.col+g)%f;for(var j=0;j<f;j++)i+=" ";d.replaceCharacters({start:m.start,
end:m.start},i);d.moveCursorTo({col:m.start.col+f+g,row:m.end.row})}else{for(j=0;j<f;j++)i+=" ";for(j=m.start.row-1;j++<m.end.row;){g=j==m.start.row?m.start.col:0;d.replaceCharacters({start:{row:j,col:g},end:{row:j,col:g}},i)}d.setSelection({start:m.start,end:{col:m.end.col+f,row:m.end.row}})}}.bind(this))};s.untab=function(){var d=r.view;d.groupChanges(function(){var f=v.get("tabstop"),m=d.getSelectedRange(),i=r.model.lines,g=0;if(l.isZeroLength(m)){g=Math.min(i[m.start.row].substring(0,m.start.col).match(/\s*$/)[0].length,
(m.start.col-f)%f||f);d.replaceCharacters({start:{col:m.start.col-g,row:m.start.row},end:m.start},"");d.moveCursorTo({row:m.start.row,col:m.end.col-g})}else{for(var j,q=m.start.row-1;q++<m.end.row;){j=q==m.start.row?m.start.col:0;g=Math.min(i[q].substring(j).match(/^\s*/)[0].length,f);d.replaceCharacters({start:{row:q,col:j},end:{row:q,col:j+g}},"")}d.setSelection({start:{row:m.start.row,col:m.start.col},end:{row:m.end.row,col:m.end.col-g}})}}.bind(this))}});
bespin.tiki.module("text_editor:commands/editor",function(y,s){y("bespin:plugins");var v=y("settings").settings,r=y("environment").env;s.findNextCommand=function(){var h=r.view,d=h.editor.searchController,f=h.getSelectedRange();if(d=d.findNext(f.end,true)){h.setSelection(d,true);h.focus()}};s.findPrevCommand=function(){var h=r.view,d=h.editor.searchController,f=h.getSelectedRange();if(d=d.findPrevious(f.start,true)){h.setSelection(d,true);h.focus()}};var l=function(h){var d=r.view,f=d.getSelectedCharacters();
h=h(f);d=d.getSelectedRange();r.model.replaceCharacters(d,h)};s.replaceCommand=function(h){l(function(d){return d.replace(h.search+"/g",h.replace)})};s.entabCommand=function(){tabstop=v.get("tabstop");l(function(h){return h.replace(" {"+tabstop+"}","\t")})};s.detabCommand=function(){tabstop=v.get("tabstop");l(function(h){return h.replace("\t",(new Array(tabstop+1)).join(" "))})};s.trimCommand=function(h){l(function(d){d=d.split("\n");d=d.map(function(f){if(h.side==="left"||h.side==="both")f=f.replace(/^\s+/,
"");if(h.side==="right"||h.side==="both")f=f.replace(/\s+$/,"");return f});return d.join("\n")})};s.ucCommand=function(){l(function(h){return h.toUpperCase()})};s.lcCommand=function(){l(function(h){return h.toLowerCase()})}});
bespin.tiki.module("text_editor:commands/movement",function(y,s){y("rangeutils:utils/range");var v=y("environment").env;s.moveDown=function(){v.view.moveDown()};s.moveLeft=function(){v.view.moveLeft()};s.moveRight=function(){v.view.moveRight()};s.moveUp=function(){v.view.moveUp()};s.selectDown=function(){v.view.selectDown()};s.selectLeft=function(){v.view.selectLeft()};s.selectRight=function(){v.view.selectRight()};s.selectUp=function(){v.view.selectUp()};var r=function(m,i){var g=v.view,j=v.model.lines,
q=g.getSelectedRange(true);i=i?q.end.row:j.length-1;g.moveCursorTo({row:i,col:j[i].length},m)};s.moveLineEnd=function(){r(false,true)};s.selectLineEnd=function(){r(true,true)};s.moveDocEnd=function(){r(false,false)};s.selectDocEnd=function(){r(true,false)};var l=function(m,i){var g=v.view,j=g.getSelectedRange(true);g.moveCursorTo({row:i?j.end.row:0,col:0},m)};s.moveLineStart=function(){l(false,true)};s.selectLineStart=function(){l(true,true)};s.moveDocStart=function(){l(false,false)};s.selectDocStart=
function(){l(true,false)};var h=function(m,i,g,j,q){var t=0,B=false;if(j<0){g--;if(q)t=1}for(;g<i.length&&g>-1;){if(q=m.isDelimiter(i[g]))t++;else B=true;if((q||t>1)&&B)break;g+=j}j<0&&g++;return g},d=function(m){var i=v.view,g=v.model.lines,j=i.getSelectedRange(true).end,q=j.row;j=j.col;var t=g[q],B=false;if(j>=t.length){q++;B=true;if(q<g.length){j=0;t=g[q]}else t=""}j=h(i,t,j,1,B);i.moveCursorTo({row:q,col:j},m)},f=function(m){var i=v.view,g=v.model.lines,j=i.getSelectedRange(true).end,q=j.row;
j=j.col;var t=g[q],B=false;if(j>t.length)j=t.length;else if(j==0){q--;B=true;if(q>-1){t=g[q];j=t.length}else t=""}j=h(i,t,j,-1,B);i.moveCursorTo({row:q,col:j},m)};s.moveNextWord=function(){d(false)};s.selectNextWord=function(){d(true)};s.movePreviousWord=function(){f(false)};s.selectPreviousWord=function(){f(true)};s.selectAll=function(){v.view.selectAll()}});
bespin.tiki.module("text_editor:commands/scrolling",function(y,s){var v=y("environment").env;s.scrollDocStart=function(){v.view.scrollToPosition({col:0,row:0})};s.scrollDocEnd=function(){v.view.scrollToPosition(v.model.range.end)};s.scrollPageDown=function(){v.view.scrollPageDown()};s.scrollPageUp=function(){v.view.scrollPageUp()}});
bespin.tiki.module("text_editor:controllers/layoutmanager",function(y,s){var v=y("bespin:util/util"),r=y("events").Event;y("rangeutils:utils/range");var l=y("syntax_manager").SyntaxManager,h=y("models/textstorage").TextStorage,d=y("bespin:plugins").catalog,f=y("settings").settings,m=y("bespin:util/scratchcanvas"),i={};y=function(){var g=f.get("fontsize"),j=f.get("fontface");j=g+"px "+j;for(var q=m.get(),t="",B=0;B<100;B++)t+="M";j=q.measureStringWidth(j,t)/100;i.characterWidth=j;i.lineHeight=Math.floor(g*
1.6);i.lineAscent=Math.floor(g*1.3)};y();d.registerExtension("settingChange",{match:"font[size|face]",pointer:y});s.LayoutManager=function(g){this.changedTextAtRow=new r;this.invalidatedRects=new r;this.fontDimension=i;if(g.textStorage){g._textStorage=g.textStorage;delete g.textStorage}else this._textStorage=new h;v.mixin(this,g);this._textStorage.changed.add(this.textStorageChanged.bind(this));this.textLines=[{characters:"",colors:[{start:0,end:0,color:"plain"}]}];this.syntaxManager=g=new l(this);
g.attrsChanged.add(this._attrsChanged.bind(this));this._size={width:0,height:0};this.sizeChanged=new r;this._height=0;this._recomputeEntireLayout()};s.LayoutManager.prototype={_maximumWidth:0,_textStorage:null,_size:null,sizeChanged:null,_theme:{},margin:{left:5,bottom:6,top:0,right:12},pluginCatalog:d,syntaxManager:null,textLines:null,_attrsChanged:function(g,j){this.updateTextRows(g,j);this.invalidatedRects(this,this.rectsForRange({start:{row:g,col:0},end:{row:j,col:0}}))},_computeInvalidRects:function(g,
j){var q=this.characterRectForPosition(g.start),t={x:q.x,y:q.y,width:Number.MAX_VALUE,height:q.height};return g.end.row===j.end.row?[t]:[t,{x:0,y:q.y+i.lineHeight,width:Number.MAX_VALUE,height:Number.MAX_VALUE}]},_lastCharacterPosition:function(){return{row:this.textLines.length-1,col:this._maximumWidth}},_recalculateMaximumWidth:function(){var g=0;this.textLines.forEach(function(j){j=j.characters.length;if(g<j)g=j});this._maximumWidth=g;this.size={width:g,height:this.textLines.length}},_recomputeEntireLayout:function(){var g=
this._textStorage.range;this._recomputeLayoutForRanges(g,g)},_recomputeLayoutForRanges:function(g,j){for(var q=g.start.row,t=g.end.row,B=j.end.row,C=B-q+1,e=this._textStorage.lines,K=this._theme.plain,L=[],n=0;n<C;n++)L[n]={characters:e[q+n],colors:[{start:0,end:null,color:K}]};this.textLines=v.replace(this.textLines,q,t-q+1,L);this._recalculateMaximumWidth();t=this.textLines.length;C=this.syntaxManager;if(this._height!==t)this._height=t;C.invalidateRow(q);this.updateTextRows(q,B+1);this.changedTextAtRow(this,
q);this.invalidatedRects(this,this._computeInvalidRects(g,j))},boundingRect:function(){return this.rectsForRange({start:{row:0,col:0},end:{row:this.textLines.length-1,col:this._maximumWidth}})[0]},characterAtPoint:function(g){var j=this.margin,q=g.x-j.left,t=i.characterWidth,B=this._textStorage;g=B.clampPosition({row:Math.floor((g.y-j.top)/i.lineHeight),col:Math.floor(q/t)});B=B.lines[g.row].length;g.partialFraction=q<0||g.col===B?0:q%t/t;return g},characterRangeForBoundingRect:function(g){var j=
i.lineHeight,q=i.characterWidth,t=this.margin,B=g.x-t.left;t=g.y-t.top;return{start:{row:Math.max(Math.floor(t/j),0),col:Math.max(Math.floor(B/q),0)},end:{row:Math.floor((t+g.height-1)/j),col:Math.floor((B+g.width-1)/q)+1}}},characterRectForPosition:function(g){return this.rectsForRange({start:g,end:{row:g.row,col:g.col+1}})[0]},lineRectForRow:function(g){return this.rectsForRange({start:{row:g,col:0},end:{row:g,col:this._maximumWidth}})[0]},rectForPosition:function(g){var j=this.margin,q=i.characterWidth,
t=i.lineHeight;return{x:j.left+q*g.col,y:j.top+t*g.row,width:q,height:t}},rectsForRange:function(g){var j=i.characterWidth,q=i.lineHeight,t=this._maximumWidth,B=this.margin,C=g.start,e=g.end;g=C.row;var K=C.col;C=e.row;e=e.col;if(g===C)return[{x:B.left+j*K,y:B.top+q*g,width:j*(e-K),height:q}];var L=[],n;if(K===0)n=g;else{n=g+1;L.push({x:B.left+j*K,y:B.top+q*g,width:99999,height:q})}if(e===0)t=C-1;else if(e===t)t=C;else{t=C-1;L.push({x:B.left,y:B.top+q*C,width:j*e,height:q})}L.push({x:B.left,y:B.top+
q*n,width:99999,height:q*(t-n+1)});return L},textStorageChanged:function(g,j){this._recomputeLayoutForRanges(g,j)},updateTextRows:function(g,j){var q=this.textLines;j=this.syntaxManager.getAttrsForRows(g,j);for(var t=0;t<j.length;t++)q[g+t].colors=j[t]}};Object.defineProperties(s.LayoutManager.prototype,{size:{set:function(g){if(g.width!==this._size.width||g.height!==this._size.height){this.sizeChanged(g);this._size=g}},get:function(){return this._size}},textStorage:{get:function(){return this._textStorage}}})});
bespin.tiki.module("text_editor:controllers/search",function(y,s){var v=y("bespin:util/util");y("rangeutils:utils/range");y("bespin:console");s.EditorSearchController=function(r){this.editor=r};s.EditorSearchController.prototype={editor:null,_escapeString:/(\/|\.|\*|\+|\?|\||\(|\)|\[|\]|\{|\}|\\)/g,_findMatchesInString:function(r){var l=[],h=this.searchRegExp,d;for(h.lastIndex=0;;){d=h.exec(r);if(d===null)break;l.push(d);h.lastIndex=d.index+d[0].length}return l},_makeRange:function(r,l){return{start:{row:l,
col:r.index},end:{row:l,col:r.index+r[0].length}}},isRegExp:null,searchRegExp:null,searchText:null,setSearchText:function(r,l){this.searchRegExp=l?new RegExp(r):new RegExp(r.replace(this._escapeString,"\\$1"),"gi");this.isRegExp=l;this.searchText=r},findNext:function(r,l){var h=this.searchRegExp;if(v.none(h))return null;r=r||this.editor.textView.getSelectedRange().end;var d=this.editor.layoutManager.textStorage.lines,f;h.lastIndex=r.col;var m;for(m=r.row;m<d.length;m++){f=h.exec(d[m]);if(!v.none(f))return this._makeRange(f,
m)}if(!l)return null;for(m=0;m<=r.row;m++){f=h.exec(d[m]);if(!v.none(f))return this._makeRange(f,m)}return null},findPrevious:function(r,l){if(v.none(this.searchRegExp))return null;r=r||this.editor.textView.getSelectedRange().start;var h=this.editor.buffer.layoutManager.textStorage.lines,d;d=this._findMatchesInString(h[r.row].substring(0,r.col));if(d.length!==0)return this._makeRange(d[d.length-1],r.row);var f;for(f=r.row-1;f!==-1;f--){d=this._findMatchesInString(h[f]);if(d.length!==0)return this._makeRange(d[d.length-
1],f)}if(!l)return null;for(f=h.length-1;f>=r.row;f--){d=this._findMatchesInString(h[f]);if(d.length!==0)return this._makeRange(d[d.length-1],f)}return null}}});
bespin.tiki.module("text_editor:controllers/undo",function(y,s){var v=y("bespin:console").console,r=y("environment").env;s.EditorUndoController=function(l){this.editor=l;l=this.textView=l.textView;l.beganChangeGroup.add(function(h,d){this._beginTransaction();this._record.selectionBefore=d}.bind(this));l.endedChangeGroup.add(function(h,d){this._record.selectionAfter=d;this._endTransaction()}.bind(this));l.replacedCharacters.add(function(h,d,f){if(!this._inTransaction)throw new Error("UndoController.textViewReplacedCharacters() called outside a transaction");
this._record.patches.push({oldCharacters:this._deletedCharacters,oldRange:d,newCharacters:f,newRange:this.editor.layoutManager.textStorage.resultingRangeForReplacement(d,f.split("\n"))});this._deletedCharacters=null}.bind(this));l.willReplaceRange.add(function(h,d){if(!this._inTransaction)throw new Error("UndoController.textViewWillReplaceRange() called outside a transaction");this._deletedCharacters=this.editor.layoutManager.textStorage.getCharacters(d)}.bind(this))};s.EditorUndoController.prototype=
{_inTransaction:false,_record:null,textView:null,_beginTransaction:function(){if(this._inTransaction){v.trace();throw new Error("UndoController._beginTransaction() called with a transaction already in place");}this._inTransaction=true;this._record={patches:[]}},_endTransaction:function(){if(!this._inTransaction)throw new Error("UndoController._endTransaction() called without a transaction in place");this.editor.buffer.undoManager.registerUndo(this,this._record);this._record=null;this._inTransaction=
false},_tryApplyingPatches:function(l){var h=this.editor.layoutManager.textStorage;l.forEach(function(d){h.replaceCharacters(d.oldRange,d.newCharacters)});return true},_undoOrRedo:function(l,h){if(this._inTransaction)throw new Error("UndoController._undoOrRedo() called while in a transaction");if(!this._tryApplyingPatches(l))return false;this.textView.setSelection(h,true);return true},redo:function(l){var h=l.patches.concat();h.reverse();return this._undoOrRedo(h,l.selectionAfter)},undo:function(l){return this._undoOrRedo(l.patches.map(function(h){return{oldCharacters:h.newCharacters,
oldRange:h.newRange,newCharacters:h.oldCharacters,newRange:h.oldRange}}),l.selectionBefore)}};s.undoManagerCommand=function(l,h){r.editor.buffer.undoManager[h.commandExt.name]()}});
bespin.tiki.module("text_editor:models/buffer",function(y,s){var v=y("environment").env,r=y("bespin:util/util"),l=y("bespin:promise").Promise,h=y("models/textstorage").TextStorage,d=y("controllers/layoutmanager").LayoutManager,f=y("undomanager").UndoManager;s.Buffer=function(m,i){this._file=m;this._model=new h(i);this._layoutManager=new d({textStorage:this._model});this.undoManager=new f;if(m)this.reload().then(function(){this._updateSyntaxManagerInitialContext()}.bind(this));else{this.loadPromise=
new l;this.loadPromise.resolve()}i=v.session?v.session.history:null;var g,j,q;if(i&&m&&(g=i.getHistoryForPath(m.path))){j=g.selection;q=g.scroll}this._selectedRange=j||{start:{row:0,col:0},end:{row:0,col:0}};this._scrollOffset=q||{x:0,y:0}};s.Buffer.prototype={undoManager:null,loadPromise:null,_scrollOffset:null,_selectedRange:null,_selectedRangeEndVirtual:null,_layoutManager:null,_file:null,_model:null,save:function(){return this._file.saveContents(this._model.value)},saveAs:function(m){var i=new l;
m.saveContents(this._model.value).then(function(){this._file=m;this._updateSyntaxManagerInitialContext();i.resolve()}.bind(this),function(g){i.reject(g)});return i},reload:function(){var m=this,i;return this.loadPromise=i=this._file.loadContents().then(function(g){m._model.value=g})},_updateSyntaxManagerInitialContext:function(){var m=this._file.extension();this._layoutManager.syntaxManager.setSyntaxFromFileExt(m===null?"":m)},untitled:function(){return r.none(this._file)}};Object.defineProperties(s.Buffer.prototype,
{layoutManager:{get:function(){return this._layoutManager}},syntaxManager:{get:function(){}},file:{get:function(){return this._file}},model:{get:function(){return this._model}}})});
bespin.tiki.module("text_editor:models/textstorage",function(y,s){var v=y("events").Event,r=y("bespin:util/util");y=function(l){this._lines=l!==null&&l!==undefined?l.split("\n"):[""];this.changed=new v;return this};y.prototype={_lines:null,readOnly:false,clampPosition:function(l){var h=this._lines,d=l.row;if(d<0)return{row:0,col:0};else if(d>=h.length)return this.range.end;l=Math.max(0,Math.min(l.col,h[d].length));return{row:d,col:l}},clampRange:function(l){var h=this.clampPosition(l.start);l=this.clampPosition(l.end);
return{start:h,end:l}},deleteCharacters:function(l){this.replaceCharacters(l,"")},displacePosition:function(l,h){var d=h>0,f=this._lines,m=f.length;for(h=Math.abs(h);h!==0;h--)if(d){var i=f[l.row].length;if(l.row===m-1&&l.col===i)return l;l=l.col===i?{row:l.row+1,col:0}:{row:l.row,col:l.col+1}}else{if(l.row===0&&l.col==0)return l;if(l.col===0){f=this._lines;l={row:l.row-1,col:f[l.row-1].length}}else l={row:l.row,col:l.col-1}}return l},getCharacters:function(l){var h=this._lines,d=l.start,f=l.end,
m=d.row;l=f.row;var i=d.col;d=f.col;if(m===l)return h[m].substring(i,d);f=h[m].substring(i);m=h.slice(m+1,l);h=h[l].substring(0,d);return[f].concat(m,h).join("\n")},getLines:function(){return this._lines},getRange:function(){var l=this._lines,h=l.length-1;return{start:{row:0,col:0},end:{row:h,col:l[h].length}}},getValue:function(){return this._lines.join("\n")},insertCharacters:function(l,h){this.replaceCharacters({start:l,end:l},h)},replaceCharacters:function(l,h){if(this.readOnly)throw new Error("Attempt to modify a read-only text storage object");
var d=h.split("\n"),f=d.length,m=this.resultingRangeForReplacement(l,d),i=l.start,g=l.end,j=i.row,q=g.row,t=this._lines;d[0]=t[j].substring(0,i.col)+d[0];d[f-1]+=t[q].substring(g.col);this._lines=r.replace(t,j,q-j+1,d);this.changed(l,m,h)},resultingRangeForReplacement:function(l,h){var d=h.length;l=l.start;return{start:l,end:{row:l.row+d-1,col:(d===1?l.col:0)+h[d-1].length}}},setLines:function(l){this.setValue(l.join("\n"))},setValue:function(l){this.replaceCharacters(this.range,l)}};s.TextStorage=
y;Object.defineProperties(s.TextStorage.prototype,{lines:{get:function(){return this.getLines()},set:function(l){return this.setLines(l)}},range:{get:function(){return this.getRange()}},value:{get:function(){return this.getValue()},set:function(l){this.setValue(l)}}})});
bespin.tiki.module("text_editor:utils/rect",function(y,s){s._distanceFromBounds=function(v,r,l){if(v<r)return v-r;if(v>=l)return v-l;return 0};s.merge=function(v){var r;do{r=false;for(var l=[],h=0;h<v.length;h++){var d=v[h];l.push(d);for(var f=h+1;f<v.length;f++){var m=v[f];if(s.rectsSideBySide(d,m)||s.rectsIntersect(d,m)){v.splice(f,1);l[l.length-1]=s.unionRects(d,m);r=true;break}}}v=l}while(r);return v};s.offsetFromRect=function(v,r){return{x:s._distanceFromBounds(r.x,v.x,s.maxX(v)),y:s._distanceFromBounds(r.y,
v.y,s.maxY(v))}};s.rectsIntersect=function(v,r){v=s.intersectRects(v,r);return v.width!==0&&v.height!==0};s.rectsSideBySide=function(v,r){if(v.x==r.x&&v.width==r.width)return v.y<r.y?v.y+v.height==r.y:r.y+r.height==v.y;else if(v.y==r.y&&v.height==r.height)return v.x<r.x?v.x+v.width==r.x:r.x+r.width==v.x;return false};s.intersectRects=function(v,r){v={x:Math.max(s.minX(v),s.minX(r)),y:Math.max(s.minY(v),s.minY(r)),width:Math.min(s.maxX(v),s.maxX(r)),height:Math.min(s.maxY(v),s.maxY(r))};v.width=Math.max(0,
v.width-v.x);v.height=Math.max(0,v.height-v.y);return v};s.minX=function(v){return v.x||0};s.maxX=function(v){return(v.x||0)+(v.width||0)};s.minY=function(v){return v.y||0};s.maxY=function(v){return(v.y||0)+(v.height||0)};s.pointInRect=function(v,r){return v.x>=s.minX(r)&&v.y>=s.minY(r)&&v.x<=s.maxX(r)&&v.y<=s.maxY(r)};s.unionRects=function(v,r){v={x:Math.min(s.minX(v),s.minX(r)),y:Math.min(s.minY(v),s.minY(r)),width:Math.max(s.maxX(v),s.maxX(r)),height:Math.max(s.maxY(v),s.maxY(r))};v.width=Math.max(0,
v.width-v.x);v.height=Math.max(0,v.height-v.y);return v};s.rectsEqual=function(v,r,l){if(!v||!r)return v==r;if(!l&&l!==0)l=0.1;if(v.y!=r.y&&Math.abs(v.y-r.y)>l)return false;if(v.x!=r.x&&Math.abs(v.x-r.x)>l)return false;if(v.width!=r.width&&Math.abs(v.width-r.width)>l)return false;if(v.height!=r.height&&Math.abs(v.height-r.height)>l)return false;return true}});
bespin.tiki.module("text_editor:views/canvas",function(y,s){var v=y("bespin:util/util"),r=y("utils/rect"),l=y("events").Event;s.CanvasView=function(h,d,f){if(h){this._preventDownsize=d||false;this._clearOnFullInvalid=f||false;this._clippingFrame=this._frame={x:0,y:0,width:0,height:0};this._invalidRects=[];d=document.createElement("canvas");d.setAttribute("style","position: absolute");d.innerHTML="canvas tag not supported by your browser";h.appendChild(d);this.domNode=d;this.clippingChanged=new l;
this.clippingChanged.add(this.clippingFrameChanged.bind(this))}};s.CanvasView.prototype={domNode:null,clippingChanged:null,_canvasContext:null,_canvasId:null,_invalidRects:null,_lastRedrawTime:null,_redrawTimer:null,_clippingFrame:null,_preventDownsize:false,_clearOnFullInvalid:false,_frame:null,_getContext:function(){if(this._canvasContext===null)this._canvasContext=this.domNode.getContext("2d");return this._canvasContext},computeWithClippingFrame:function(h,d){var f=this.clippingFrame;return{x:h+
f.x,y:d+f.y}},minimumRedrawDelay:1E3/30,clippingFrameChanged:function(){this.invalidate()},drawRect:function(){},render:function(){if(!(this._renderTimer||this._redrawTimer))this._renderTimer=setTimeout(this._tryRedraw.bind(this),0)},invalidate:function(){this._invalidRects="all";this.render()},invalidateRect:function(h){var d=this._invalidRects;if(d!=="all"){d.push(h);this.render()}},_tryRedraw:function(){this._renderTimer=null;var h=(new Date).getTime(),d=this._lastRedrawTime,f=this.minimumRedrawDelay;
if(d===null||h-d>=f)this._redraw();else if(this._redrawTimer===null)this._redrawTimer=window.setTimeout(this._redraw.bind(this),f)},_redraw:function(){var h=this.clippingFrame;h={x:Math.round(h.x),y:Math.round(h.y),width:h.width,height:h.height};var d=this._getContext();d.save();d.translate(-h.x,-h.y);var f=this._invalidRects;if(f==="all"){this._clearOnFullInvalid&&d.clearRect(0,0,this.domNode.width,this.domNode.height);this.drawRect(h,d)}else r.merge(f).forEach(function(m){m=r.intersectRects(m,h);
if(m.width!==0&&m.height!==0){d.save();var i=m.x,g=m.y,j=m.width,q=m.height;d.beginPath();d.moveTo(i,g);d.lineTo(i+j,g);d.lineTo(i+j,g+q);d.lineTo(i,g+q);d.closePath();d.clip();this.drawRect(m,d);d.restore()}},this);d.restore();this._invalidRects=[];this._redrawTimer=null;this._lastRedrawTime=(new Date).getTime()}};Object.defineProperties(s.CanvasView.prototype,{clippingFrame:{get:function(){return this._clippingFrame},set:function(h){h=v.mixin(v.clone(this._clippingFrame),h);if(this._clippingFrame===
null||!r.rectsEqual(h,this._clippingFrame)){this._clippingFrame=h;this.clippingChanged()}}},frame:{get:function(){return this._frame},set:function(h){var d=this.domNode,f=d.style,m=this._preventDownsize,i=d.width,g=d.height;f=d.style;f.left=h.x+"px";f.top=h.y+"px";var j,q;if(h.width!==i)if(h.width<i)m||(j=true);else j=true;if(h.height!==g)if(h.height<g)m||(q=true);else q=true;if(j)this.domNode.width=h.width;if(q)this.domNode.height=h.height;this._frame=h;this.clippingFrame={width:h.width,height:h.height}}}})});
bespin.tiki.module("text_editor:views/editor",function(y,s){function v(n){var w=C.plugins.text_editor.provides,D=w.length,J={};if(n){n=n.themestyles;if(n.currentThemeVariables&&n.currentThemeVariables.text_editor)J=n.currentThemeVariables.text_editor}for(;D--;)if(w[D].ep==="themevariable"){n=h.mixin(h.clone(w[D].defaultValue),J[w[D].name]);switch(w[D].name){case "gutter":case "editor":case "scroller":case "highlighter":L[w[D].name]=n}}}var r=y("rangeutils:utils/range"),l=y("views/scroller"),h=y("bespin:util/util"),
d=y("models/buffer").Buffer,f=y("completion:controller").CompletionController,m=y("controllers/search").EditorSearchController,i=y("controllers/undo").EditorUndoController,g=y("events").Event,j=y("views/gutter").GutterView;y("controllers/layoutmanager");var q=l.ScrollerCanvasView,t=y("views/text").TextView,B=y("underscore")._,C=y("bespin:plugins").catalog,e=y("keyboard:keyboard").keyboardManager,K=y("settings").settings,L={};v();C.registerExtension("themeChange",{pointer:v});s.EditorView=function(n){this.elementAppended=
new g;var w=this.element=this.container=document.createElement("div");w.style.overflow="visible";w.style.position="relative";this.scrollOffsetChanged=new g;this.willChangeBuffer=new g;this.selectionChanged=new g;this.textChanged=new g;this.gutterView=new j(w,this);this.textView=new t(w,this);var D=new q(this,l.LAYOUT_VERTICAL),J=new q(this,l.LAYOUT_HORIZONTAL);this.verticalScroller=D;this.horizontalScroller=J;this.completionController=new f(this);this.editorUndoController=new i(this);this.searchController=
new m(this);this._textViewSize=this._oldSize={width:0,height:0};this._themeData=L;this.buffer=new d(null,n);this.elementAppended.add(function(){var Q=K.get("fontsize"),Z=K.get("fontface");this._font=Q+"px "+Z;C.registerExtension("themeChange",{pointer:this._themeVariableChange.bind(this)});C.registerExtension("settingChange",{match:"font[size|face]",pointer:this._fontSettingChanged.bind(this)});C.registerExtension("dimensionsChanged",{pointer:this.dimensionsChanged.bind(this)});this._dontRecomputeLayout=
false;this._recomputeLayout();w.addEventListener(h.isMozilla?"DOMMouseScroll":"mousewheel",this._onMouseWheel.bind(this),false);D.valueChanged.add(function(T){this.scrollOffset={y:T}}.bind(this));J.valueChanged.add(function(T){this.scrollOffset={x:T}}.bind(this));this.scrollOffsetChanged.add(function(T){this._updateScrollOffsetChanged(T)}.bind(this))}.bind(this))};s.EditorView.prototype={elementAppended:null,textChanged:null,selectionChanged:null,scrollOffsetChanged:null,willChangeBuffer:null,_textViewSize:null,
_textLinesCount:0,_gutterViewWidth:0,_oldSize:null,_buffer:null,_dontRecomputeLayout:true,_themeData:null,_layoutManagerSizeChanged:function(n){var w=this.layoutManager.fontDimension;this._textViewSize={width:n.width*w.characterWidth,height:n.height*w.lineHeight};if(this._textLinesCount!==n.height){this.gutterView.computeWidth()!==this._gutterViewWidth?this._recomputeLayout(true):this.gutterView.invalidate();this._textLinesLength=n.height}this._updateScrollers();this.scrollOffset={}},_updateScrollers:function(){if(!this._dontRecomputeLayout){var n=
this.textViewPaddingFrame,w=this._textViewSize.width,D=this._textViewSize.height,J=this.scrollOffset,Q=this.verticalScroller,Z=this.horizontalScroller;if(D<n.height)Q.isVisible=false;else{Q.isVisible=true;Q.proportion=n.height/D;Q.maximum=D-n.height;Q.value=J.y}if(w<n.width)Z.isVisible=false;else{Z.isVisible=true;Z.proportion=n.width/w;Z.maximum=w-n.width;Z.value=J.x}}},_onMouseWheel:function(n){var w=0;if(n.wheelDelta)w=-n.wheelDelta;else if(n.detail)w=n.detail*40;var D=true;if(n.axis){if(n.axis==
n.HORIZONTAL_AXIS)D=false}else if(n.wheelDeltaY||n.wheelDeltaX){if(n.wheelDeltaX==n.wheelDelta)D=false}else if(n.shiftKey)D=false;D?this.scrollBy(0,w):this.scrollBy(w*5,0);h.stopEvent(n)},scrollTo:function(n){this.scrollOffset=n},scrollBy:function(n,w){this.scrollOffset={x:this.scrollOffset.x+n,y:this.scrollOffset.y+w}},_recomputeLayout:function(n){if(!this._dontRecomputeLayout){var w=this.container.offsetWidth,D=this.container.offsetHeight;if(!(!n&&w==this._oldSize.width&&D==this._oldSize.height)){this._oldSize=
{width:w,height:D};this._gutterViewWidth=n=this.gutterView.computeWidth();this.gutterView.frame={x:0,y:0,width:n,height:D};this.textView.frame={x:n,y:0,width:w-n,height:D};var J=this._themeData.scroller.padding,Q=this._themeData.scroller.thickness;this.horizontalScroller.frame={x:n+J,y:D-(Q+J),width:w-(n+2*J+Q),height:Q};this.verticalScroller.frame={x:w-(J+Q),y:J,width:Q,height:D-(2*J+Q)};this.scrollOffset={};this._updateScrollers();this.gutterView.invalidate();this.textView.invalidate();this.verticalScroller.invalidate();
this.horizontalScroller.invalidate()}}},dimensionsChanged:function(){this._recomputeLayout()},_font:null,_fontSettingChanged:function(){var n=K.get("fontsize"),w=K.get("fontface");this._font=n+"px "+w;this.layoutManager._recalculateMaximumWidth();this._layoutManagerSizeChanged(this.layoutManager.size);this.textView.invalidate()},_themeVariableChange:function(){this._recomputeLayout(true)},_updateScrollOffsetChanged:function(n){this.verticalScroller.value=n.y;this.horizontalScroller.value=n.x;this.textView.clippingFrame=
{x:n.x,y:n.y};this.gutterView.clippingFrame={y:n.y};this._updateScrollers();this.gutterView.invalidate();this.textView.invalidate()},processKeyEvent:function(n,w,D){D=B(D).clone();D.completing=this.completionController.isCompleting();return e.processKeyEvent(n,w,D)},convertTextViewPoint:function(n){var w=this.scrollOffset;return{x:n.x-w.x+this._gutterViewWidth,y:n.y-w.y}},replace:function(n,w,D){if(!r.isRange(n))throw new Error('replace(): expected range but found "'+n+"'");if(!h.isString(w))throw new Error('replace(): expected text string but found "'+
text+'"');var J=r.normalizeRange(n),Q=this.textView,Z=Q.getSelectedRange(false);return Q.groupChanges(function(){Q.replaceCharacters(J,w);if(D)Q.setSelection(Z);else{var T=w.split("\n");T=T.length>1?{row:n.start.row+T.length-1,col:T[T.length-1].length}:r.addPositions(n.start,{row:0,col:w.length});Q.moveCursorTo(T)}})},getText:function(n){if(!r.isRange(n))throw new Error('getText(): expected range but found "'+n+'"');return this.layoutManager.textStorage.getCharacters(r.normalizeRange(n))},setLineNumber:function(n){if(!h.isNumber(n))throw new Error("setLineNumber(): lineNumber must be a number");
this.textView.moveCursorTo({row:n-1,col:0})},setCursor:function(n){if(!r.isPosition(n))throw new Error('setCursor(): expected position but found "'+n+'"');this.textView.moveCursorTo(n)},changeGroup:function(n){return this.textView.groupChanges(function(){n(this)}.bind(this))},addTags:function(n){this.completionController.tags.add(n)}};Object.defineProperties(s.EditorView.prototype,{themeData:{get:function(){return this._themeData},set:function(){throw new Error("themeData can't be changed directly. Use themeManager.");
}},font:{get:function(){return this._font},set:function(){throw new Error("font can't be changed directly. Use settings fontsize and fontface.");}},buffer:{set:function(n){if(n!==this._buffer){if(!n.loadPromise.isResolved())throw new Error("buffer.set(): the new buffer must first be loaded!");if(this._buffer!==null){this.layoutManager.sizeChanged.remove(this);this.layoutManager.textStorage.changed.remove(this);this.textView.selectionChanged.remove(this)}this.willChangeBuffer(n);C.publish(this,"editorChange",
"buffer",n);this.layoutManager=n.layoutManager;this._buffer=n;var w=this.layoutManager,D=this.textView;w.sizeChanged.add(this,this._layoutManagerSizeChanged.bind(this));w.textStorage.changed.add(this,this.textChanged.bind(this));D.selectionChanged.add(this,this.selectionChanged.bind(this));this.textView.setSelection(n._selectedRange,false);this.scrollOffsetChanged(n._scrollOffset);this.layoutManager.sizeChanged(this.layoutManager.size);this._recomputeLayout()}},get:function(){return this._buffer}},
frame:{get:function(){return{width:this.container.offsetWidth,height:this.container.offsetHeight}}},textViewPaddingFrame:{get:function(){var n=h.clone(this.textView.frame),w=this.textView.padding;n.width-=w.left+w.right;n.height-=w.top+w.bottom;return n}},scrollOffset:{set:function(n){if(n.x===undefined)n.x=this.scrollOffset.x;if(n.y===undefined)n.y=this.scrollOffset.y;var w=this.textViewPaddingFrame;if(n.y<0)n.y=0;else if(this._textViewSize.height<w.height)n.y=0;else if(n.y+w.height>this._textViewSize.height)n.y=
this._textViewSize.height-w.height;if(n.x<0)n.x=0;else if(this._textViewSize.width<w.width)n.x=0;else if(n.x+w.width>this._textViewSize.width)n.x=this._textViewSize.width-w.width;if(!(n.x===this.scrollOffset.x&&n.y===this.scrollOffset.y)){this.buffer._scrollOffset=n;this.scrollOffsetChanged(n);C.publish(this,"editorChange","scrollOffset",n)}},get:function(){return this.buffer._scrollOffset}},readOnly:{get:function(){return this._buffer.model.readOnly},set:function(n){this._buffer.model.readOnly=n}},
focus:{get:function(){return this.textView.hasFocus},set:function(n){if(!h.isBoolean(n))throw new Error('set focus: expected boolean but found "'+n+'"');this.textView.hasFocus=n}},selection:{get:function(){return h.clone(this.textView.getSelectedRange(false))},set:function(n){if(!r.isRange(n))throw new Error("set selection: position/selection must be supplied");this.textView.setSelection(n)}},selectedText:{get:function(){return this.getText(this.selection)},set:function(n){if(!h.isString(n))throw new Error('set selectedText: expected string but found "'+
n+'"');return this.replace(this.selection,n)}},value:{get:function(){return this.layoutManager.textStorage.value},set:function(n){if(!h.isString(n))throw new Error('set value: expected string but found "'+n+'"');return this.replace(this.layoutManager.textStorage.range,n,false)}},syntax:{get:function(){return this.layoutManager.syntaxManager.getSyntax()},set:function(n){if(!h.isString(n))throw new Error('set syntax: expected string but found "'+newValue+'"');return this.layoutManager.syntaxManager.setSyntax(n)}}})});
bespin.tiki.module("text_editor:views/gutter",function(y,s){var v=y("bespin:util/util"),r=y("views/canvas").CanvasView;s.GutterView=function(l,h){r.call(this,l,true);this.editor=h};s.GutterView.prototype=new r;v.mixin(s.GutterView.prototype,{drawRect:function(l,h){var d=this.editor.themeData.gutter;h.fillStyle=d.backgroundColor;h.fillRect(l.x,l.y,l.width,l.height);h.save();h.translate(d.paddingLeft,0);var f=this.editor.layoutManager,m=f.characterRangeForBoundingRect(l);l=Math.min(m.end.row,f.textLines.length-
1);var i=f.fontDimension.lineAscent;h.fillStyle=d.color;h.font=this.editor.font;for(d=m.start.row;d<=l;d++)h.fillText(""+(d+1),-0.5,f.lineRectForRow(d).y+i-0.5);h.restore()},computeWidth:function(){var l=this.editor.themeData.gutter,h=this.editor.layoutManager;return h.fontDimension.characterWidth*(""+h.textLines.length).length+(l.paddingLeft+l.paddingRight)}})});
bespin.tiki.module("text_editor:views/scroller",function(y,s){var v=y("bespin:util/util"),r=y("events").Event,l=y("bespin:console").console,h=y("utils/rect"),d=y("views/canvas").CanvasView,f=s.LAYOUT_HORIZONTAL=0,m=s.LAYOUT_VERTICAL=1;s.ScrollerCanvasView=function(i,g){d.call(this,i.container,false,true);this.editor=i;this.layoutDirection=g;i=function(j,q,t){t=t||this.domNode;t.addEventListener(j,function(B){q.call(this,B);v.stopEvent(B)}.bind(this),false)}.bind(this);i("mouseover",this.mouseEntered);
i("mouseout",this.mouseExited);i("mousedown",this.mouseDown);i("mouseup",this.mouseUp,window);i("mousemove",this.mouseMove,window);this.valueChanged=new r};s.ScrollerCanvasView.prototype=new d;v.mixin(s.ScrollerCanvasView.prototype,{lineHeight:20,proportion:0,layoutDirection:m,_isVisible:false,_maximum:0,_value:0,valueChanged:null,padding:{left:0,bottom:0,top:0,right:0},_mouseDownScreenPoint:null,_mouseDownValue:null,_isMouseOver:false,_scrollTimer:null,_mouseEventPosition:null,_mouseOverHandle:false,
_drawNib:function(i){var g=this.editor.themeData.scroller,j,q;j=g.nibStyle;q=g.nibArrowStyle;g=g.nibStrokeStyle;var t=Math.floor(7.5);i.fillStyle=j;i.beginPath();i.arc(0,0,Math.floor(7.5),0,Math.PI*2,true);i.closePath();i.fill();i.strokeStyle=g;i.stroke();i.fillStyle=q;i.beginPath();i.moveTo(0,-t+3);i.lineTo(-t+3,t-5);i.lineTo(t-3,t-5);i.closePath();i.fill()},_drawNibs:function(i,g){var j=this._getClientThickness(),q=this._value,t=this._maximum,B=this._isHighlighted();if(B||q!==0){i.save();i.translate(8,
j/2);i.rotate(Math.PI*1.5);i.moveTo(0,0);this._drawNib(i,g);i.restore()}if(B||q!==t){i.save();i.translate(this._getClientLength()-8,j/2);i.rotate(Math.PI*0.5);i.moveTo(0,0);this._drawNib(i,g);i.restore()}},_getClientFrame:function(){var i=this.frame,g=this.padding;return{x:g.left,y:g.top,width:i.width-(g.left+g.right),height:i.height-(g.top+g.bottom)}},_getClientLength:function(){var i=this._getClientFrame();switch(this.layoutDirection){case f:return i.width;case m:return i.height;default:l.error("unknown layout direction");
return null}},_getClientThickness:function(){var i=this.padding,g=this.editor.themeData.scroller.thickness;switch(this.layoutDirection){case m:return g-(i.left+i.right);case f:return g-(i.top+i.bottom);default:l.error("unknown layout direction");return null}},_getFrameLength:function(){switch(this.layoutDirection){case f:return this.frame.width;case m:return this.frame.height;default:l.error("unknown layout direction");return null}},_getGutterFrame:function(){var i=this._getClientFrame(),g=this._getClientThickness();
switch(this.layoutDirection){case m:return{x:i.x,y:i.y+15,width:g,height:Math.max(0,i.height-30)};case f:return{x:i.x+15,y:i.y,width:Math.max(0,i.width-30),height:g};default:l.error("unknown layout direction");return null}},_getGutterLength:function(){var i=this._getGutterFrame(),g;switch(this.layoutDirection){case f:g=i.width;break;case m:g=i.height;break;default:l.error("unknown layout direction");break}return g},_getHandleFrame:function(){var i=this._getGutterFrame(),g=this._getHandleOffset(),
j=this._getHandleLength();switch(this.layoutDirection){case m:return{x:i.x,y:i.y+g,width:i.width,height:j};case f:return{x:i.x+g,y:i.y,width:j,height:i.height}}},_getHandleLength:function(){var i=this._getGutterLength();return Math.max(i*this.proportion,20)},_getHandleOffset:function(){var i=this._maximum;if(i===0)return 0;var g=this._getGutterLength(),j=this._getHandleLength();return(g-j)*this._value/i},_isHighlighted:function(){return this._isMouseOver===true||this._mouseDownScreenPoint!==null},
_segmentForMouseEvent:function(i){i={x:i.layerX,y:i.layerY};var g=this._getClientFrame(),j=this.padding;if(!h.pointInRect(i,g))return null;var q=this.layoutDirection;switch(q){case f:if(i.x-j.left<15)return"nib-start";else if(i.x>=g.width-15)return"nib-end";break;case m:if(i.y-j.top<15)return"nib-start";else if(i.y>=g.height-15)return"nib-end";break;default:l.error("unknown layout direction");break}j=this._getHandleFrame();if(h.pointInRect(i,j))return"handle";switch(q){case f:if(i.x<j.x)return"gutter-before";
else if(i.x>=j.x+j.width)return"gutter-after";break;case m:if(i.y<j.y)return"gutter-before";else if(i.y>=j.y+j.height)return"gutter-after";break;default:l.error("unknown layout direction");break}l.error("_segmentForMouseEvent: point ",i," outside view with handle frame ",j," and client frame ",g);return null},adjustFrame:function(){var i=this.frame;this.set("layout",{left:0,top:0,width:i.width,height:i.height})},drawRect:function(i,g){if(this._isVisible){var j=this._isHighlighted();i=this.editor.themeData.scroller;
var q=j?i.fullAlpha:i.particalAlpha,t=this.frame;g.clearRect(0,0,t.width,t.height);g.save();t=this.padding;g.translate(t.left,t.top);this._getHandleFrame();t=this._getGutterLength();var B=this._getClientThickness(),C=B/2,e=this.layoutDirection,K=this._getHandleOffset()+15,L=this._getHandleLength();if(e===m){g.translate(B+1,0);g.rotate(Math.PI*0.5)}if(!(t<=L)){g.globalAlpha=q;if(j){j=this._getClientLength();g.fillStyle=i.trackFillStyle;g.fillRect(8.5,0.5,j-16,B-1);g.strokeStyle=i.trackStrokeStyle;
g.strokeRect(8.5,0.5,j-16,B-1)}j=function(){g.beginPath();g.arc(K+C+0.5,C,C-0.5,Math.PI/2,3*Math.PI/2,false);g.arc(K+L-C-0.5,C,C-0.5,3*Math.PI/2,Math.PI/2,false);g.lineTo(K+C+0.5,B-0.5);g.closePath()};j();t=g.createLinearGradient(K,0,K,B);t.addColorStop(0,i.barFillGradientTopStart);t.addColorStop(0.4,i.barFillGradientTopStop);t.addColorStop(0.41,i.barFillStyle);t.addColorStop(0.8,i.barFillGradientBottomStart);t.addColorStop(1,i.barFillGradientBottomStop);g.fillStyle=t;g.fill();g.save();g.clip();g.fillStyle=
i.barFillStyle;g.beginPath();g.moveTo(K+C*0.4,C*0.6);g.lineTo(K+C*0.9,B*0.4);g.lineTo(K,B*0.4);g.closePath();g.fill();g.beginPath();g.moveTo(K+L-C*0.4,0+C*0.6);g.lineTo(K+L-C*0.9,0+B*0.4);g.lineTo(K+L,0+B*0.4);g.closePath();g.fill();g.restore();g.save();j();g.strokeStyle=i.trackStrokeStyle;g.stroke();g.restore();this._drawNibs(g,q);g.restore()}}},_repeatAction:function(i,g){if(i()!==false){var j=function(){this._repeatAction(i,100)}.bind(this);this._scrollTimer=setTimeout(j,g)}},_scrollByDelta:function(i){this.value=
this._value+i},_scrollUpOneLine:function(){this._scrollByDelta(-this.lineHeight);return true},_scrollDownOneLine:function(){this._scrollByDelta(this.lineHeight);return true},_scrollPage:function(){switch(this._segmentForMouseEvent(this._mouseEventPosition)){case "gutter-before":this._scrollByDelta(this._getGutterLength()*-1);break;case "gutter-after":this._scrollByDelta(this._getGutterLength());break;case null:break;default:return false}return true},mouseDown:function(i){this._mouseEventPosition=
i;this._mouseOverHandle=false;this._getGutterLength();switch(this._segmentForMouseEvent(i)){case "nib-start":this._repeatAction(this._scrollUpOneLine.bind(this),500);break;case "nib-end":this._repeatAction(this._scrollDownOneLine.bind(this),500);break;case "gutter-before":this._repeatAction(this._scrollPage.bind(this),500);break;case "gutter-after":this._repeatAction(this._scrollPage.bind(this),500);break;case "handle":break;default:l.error("_segmentForMouseEvent returned an unknown value");break}switch(this.layoutDirection){case f:this._mouseDownScreenPoint=
i.pageX;break;case m:this._mouseDownScreenPoint=i.pageY;break;default:l.error("unknown layout direction");break}},mouseMove:function(i){if(this._mouseDownScreenPoint!==null){if(this._segmentForMouseEvent(i)=="handle"||this._mouseOverHandle===true){this._mouseOverHandle=true;if(this._scrollTimer!==null){clearTimeout(this._scrollTimer);this._scrollTimer=null}var g;switch(this.layoutDirection){case f:g=i.pageX;break;case m:g=i.pageY;break;default:l.error("unknown layout direction");break}var j=g-this._mouseDownScreenPoint,
q=this._maximum,t=this._value,B=this._getGutterLength(),C=this._getHandleLength();this.value=t+q*j/(B-C);this._mouseDownScreenPoint=g}this._mouseEventPosition=i}},mouseEntered:function(){this._isMouseOver=true;this.invalidate()},mouseExited:function(){this._isMouseOver=false;this.invalidate()},mouseUp:function(){this._mouseDownValue=this._mouseDownScreenPoint=null;if(this._scrollTimer){clearTimeout(this._scrollTimer);this._scrollTimer=null}this.invalidate()}});Object.defineProperties(s.ScrollerCanvasView.prototype,
{isVisible:{set:function(i){if(this._isVisible!==i){this._isVisible=i;this.domNode.style.display=i?"block":"none";i&&this.invalidate()}}},maximum:{set:function(i){if(this._value>this._maximum)this._value=this._maximum;if(i!==this._maximum){this._maximum=i;this.invalidate()}}},value:{set:function(i){if(i<0)i=0;else if(i>this._maximum)i=this._maximum;if(i!==this._value){this._value=i;this.valueChanged(i);this.invalidate()}}}})});
bespin.tiki.module("text_editor:views/text",function(y,s){var v=y("bespin:plugins").catalog,r=y("bespin:util/util"),l=y("events").Event,h=y("views/canvas").CanvasView;y("controllers/layoutmanager");var d=y("rangeutils:utils/range"),f=y("utils/rect"),m=y("views/textinput").TextInput,i=y("bespin:console").console,g=y("settings").settings;s.TextView=function(j,q){h.call(this,j,true);this.editor=q;this.textInput=new m(j,this);this.padding={top:0,bottom:30,left:0,right:30};this.clippingChanged.add(this.clippingFrameChanged.bind(this));
j=this.domNode;j.style.cursor="text";j.addEventListener("mousedown",this.mouseDown.bind(this),false);j.addEventListener("mousemove",this.mouseMove.bind(this),false);window.addEventListener("mouseup",this.mouseUp.bind(this),false);q.willChangeBuffer.add(this.editorWillChangeBuffer.bind(this));this.selectionChanged=new l;this.beganChangeGroup=new l;this.endedChangeGroup=new l;this.willReplaceRange=new l;this.replacedCharacters=new l};s.TextView.prototype=new h;r.mixin(s.TextView.prototype,{_dragPoint:null,
_dragTimer:null,_enclosingScrollView:null,_inChangeGroup:false,_insertionPointBlinkTimer:null,_insertionPointVisible:true,_keyBuffer:"",_keyMetaBuffer:"",_keyState:"start",_hasFocus:false,_mouseIsDown:false,selectionChanged:null,beganChangeGroup:null,endedChangeGroup:null,willReplaceRange:null,replacedCharacters:null,editorWillChangeBuffer:function(j){if(this.editor.layoutManager){var q=this.editor.layoutManager;q.invalidatedRects.remove(this);q.changedTextAtRow.remove(this)}q=j.layoutManager;q.invalidatedRects.add(this,
this.layoutManagerInvalidatedRects.bind(this));q.changedTextAtRow.add(this,this.layoutManagerChangedTextAtRow.bind(this))},didFocus:function(){this._setFocus(true,true)},didBlur:function(){this._setFocus(false,true)},_drag:function(){var j=this._dragPoint,q=f.offsetFromRect(this.clippingFrame,j);this.moveCursorTo(this._selectionPositionForPoint({x:j.x-q.x,y:j.y-q.y}),true)},_drawInsertionPoint:function(j,q){if(this._insertionPointVisible){var t=this.editor.layoutManager.characterRectForPosition(this.editor.buffer._selectedRange.start);
j=Math.floor(t.x);var B=t.y,C=Math.ceil(t.width);t=t.height;q.save();var e=this.editor.themeData.editor;if(this._hasFocus){q.strokeStyle=e.cursorColor;q.beginPath();q.moveTo(j+0.5,B);q.lineTo(j+0.5,B+t);q.closePath();q.stroke()}else{q.fillStyle=e.unfocusedCursorBackgroundColor;q.fillRect(j+0.5,B,C-0.5,t);q.strokeStyle=e.unfocusedCursorColor;q.strokeRect(j+0.5,B+0.5,C-1,t-1)}q.restore()}},_drawLines:function(j,q){var t=this.editor.layoutManager,B=t.textLines,C=t.fontDimension.lineAscent,e=this.editor.themeData.highlighter;
q.save();q.font=this.editor.font;var K=t.characterRangeForBoundingRect(j),L=K.start;K=K.end;for(var n=K.row,w=L.row;w<=n;w++){var D=B[w];if(!r.none(D)){var J=D.characters,Q=J.length,Z=Math.min(K.col,Q),T=L.col;if(!(T>=Q)){D=D.colors;if(D==null)D=[];for(Q=0;Q<D.length&&T<D[Q].start;)Q++;for(var ca=Q<D.length?D[Q].start:T;ca<Z;){j=D[Q];T=j!=null?j.end:Z;j=j!=null?j.tag:"plain";j=e.hasOwnProperty(j)?e[j]:"red";q.fillStyle=j;j=t.characterRectForPosition({row:w,col:ca});ca=J.substring(ca,T);q.fillText(ca,
j.x,j.y+C);ca=T;Q++}}}}q.restore()},_drawSelectionHighlight:function(j,q){j=this.editor.themeData.editor;j=this._hasFocus?j.selectedTextBackgroundColor:j.unfocusedCursorBackgroundColor;var t=this.editor.layoutManager;q.save();var B=d.normalizeRange(this.editor.buffer._selectedRange);q.fillStyle=j;t.rectsForRange(B).forEach(function(C){q.fillRect(C.x,C.y,C.width,C.height)});q.restore()},_drawSelection:function(j,q){this._rangeIsInsertionPoint(this.editor.buffer._selectedRange)?this._drawInsertionPoint(j,
q):this._drawSelectionHighlight(j,q)},_getVirtualSelection:function(j){var q=this.editor.buffer._selectedRange,t=this.editor.buffer._selectedRangeEndVirtual;return{start:j&&t?t:q.start,end:t||q.end}},_invalidateSelection:function(){var j=function(B){return{x:B.x-1,y:B.y,width:B.width+2,height:B.height}},q=this.editor.layoutManager,t=d.normalizeRange(this.editor.buffer._selectedRange);if(this._rangeIsInsertionPoint(t)){q=q.characterRectForPosition(t.start);this.invalidateRect(j(q))}else q.rectsForRange(t).forEach(function(B){this.invalidateRect(j(B))},
this)},_isReadOnly:function(){return this.editor.layoutManager.textStorage.readOnly},_keymappingChanged:function(){this._keyBuffer="";this._keyState="start"},_performVerticalKeyboardSelection:function(j){var q=this.editor.buffer._selectedRangeEndVirtual;this.moveCursorTo(d.addPositions(q!==null?q:this.editor.buffer._selectedRange.end,{row:j,col:0}),true,true)},_rangeIsInsertionPoint:function(j){return d.isZeroLength(j)},_rearmInsertionPointBlinkTimer:function(){this._insertionPointVisible||this.blinkInsertionPoint();
this._insertionPointBlinkTimer!==null&&clearInterval(this._insertionPointBlinkTimer);this._insertionPointBlinkTimer=setInterval(this.blinkInsertionPoint.bind(this),750)},_repositionSelection:function(){var j=this.editor.layoutManager.textLines,q=j.length,t=this.editor.buffer._selectedRange,B=Math.min(t.start.row,q-1);q=Math.min(t.end.row,q-1);var C=j[q];this.setSelection({start:{row:B,col:Math.min(t.start.col,j[B].characters.length)},end:{row:q,col:Math.min(t.end.col,C.characters.length)}})},_scrollPage:function(j){this.editor.scrollBy(0,
(this.clippingFrame.height+this.editor.layoutManager.fontDimension.lineAscent)*(j?-1:1))},_scrollWhileDragging:function(){var j=this._dragPoint;j=this.computeWithClippingFrame(j.layerX,j.layerY);r.mixin(this._dragPoint,j);this._drag()},_selectionPositionForPoint:function(j){j=this.editor.layoutManager.characterAtPoint(j);return j.partialFraction<0.5?j:d.addPositions(j,{row:0,col:1})},_syntaxManagerUpdatedSyntaxForRows:function(j,q){if(j!==q){var t=this.editor.layoutManager;t.updateTextRows(j,q);t.rectsForRange({start:{row:j,
col:0},end:{row:q,col:0}}).forEach(this.invalidateRect,this)}},blinkInsertionPoint:function(){this._insertionPointVisible=!this._insertionPointVisible;this._invalidateSelection()},copy:function(){return this.getSelectedCharacters()},cut:function(){var j=this.getSelectedCharacters();j!=""&&this.performBackspaceOrDelete(false);return j},drawRect:function(j,q){q.fillStyle=this.editor.themeData.editor.backgroundColor;q.fillRect(j.x,j.y,j.width,j.height);this._drawSelection(j,q);this._drawLines(j,q)},
focus:function(){this.textInput.focus()},getInsertionPointPosition:function(){var j=this.editor;j=j.layoutManager.characterRectForPosition(j.buffer._selectedRange.start);return{x:j.x,y:j.y}},getSelectedCharacters:function(){return this._rangeIsInsertionPoint(this.editor.buffer._selectedRange)?"":this.editor.layoutManager.textStorage.getCharacters(d.normalizeRange(this.editor.buffer._selectedRange))},getSelectedRange:function(j){return j?this.editor.buffer._selectedRange:d.normalizeRange(this.editor.buffer._selectedRange)},
groupChanges:function(j){if(this._isReadOnly())return false;if(this._inChangeGroup){j();return true}this._inChangeGroup=true;this.beganChangeGroup(this,this.editor.buffer._selectedRange);try{j()}catch(q){i.error("Error in groupChanges(): "+q);this._inChangeGroup=false;this.endedChangeGroup(this,this.editor.buffer._selectedRange);return false}finally{this._inChangeGroup=false;this.endedChangeGroup(this,this.editor.buffer._selectedRange);return true}},insertText:function(j){if(this._isReadOnly())return false;
this.groupChanges(function(){var q=d.normalizeRange(this.editor.buffer._selectedRange);this.replaceCharacters(q,j);var t=j.split("\n");this.moveCursorTo(t.length>1?{row:q.start.row+t.length-1,col:t[t.length-1].length}:d.addPositions(q.start,{row:0,col:j.length}))}.bind(this));return true},isDelimiter:function(j){return"\"',;.!~@#$%^&*?[]<>():/\\-+ \t".indexOf(j)!==-1},keyDown:function(j){if(j.charCode===0||j._charCode===0)return this.editor.processKeyEvent(j,this,{isTextView:true});else if(j.keyCode===
9)j.preventDefault();else return false},layoutManagerChangedTextAtRow:function(){this._repositionSelection()},layoutManagerInvalidatedRects:function(j,q){q.forEach(this.invalidateRect,this)},mouseDown:function(j){r.stopEvent(j);this._mouseIsDown=this.hasFocus=true;var q=this.computeWithClippingFrame(j.layerX,j.layerY);r.mixin(q,{layerX:j.layerX,layerY:j.layerY});switch(j.detail){case 1:var t=this._selectionPositionForPoint(q);this.moveCursorTo(t,j.shiftKey);break;case 2:t=this._selectionPositionForPoint(q);
var B=this.editor.layoutManager.textStorage.lines[t.row];if(B.length===0)return true;t.col-=t.col==B.length?1:0;var C=!this.isDelimiter(B[t.col]),e=this,K=function(L,n){for(;L>-1&&L<B.length;L+=n)if(e.isDelimiter(B[L])===C)break;return L+(n==1?0:1)};j=K(t.col,-1);K=K(t.col,1);this.moveCursorTo({row:t.row,col:j});this.moveCursorTo({row:t.row,col:K},true);break;case 3:j=this.editor.layoutManager.textStorage.lines;t=this._selectionPositionForPoint(q);this.setSelection({start:{row:t.row,col:0},end:{row:t.row,
col:j[t.row].length}});break}this._dragPoint=q;this._dragTimer=setInterval(this._scrollWhileDragging.bind(this),100)},mouseMove:function(j){if(this._mouseIsDown){this._dragPoint=this.computeWithClippingFrame(j.layerX,j.layerY);r.mixin(this._dragPoint,{layerX:j.layerX,layerY:j.layerY});this._drag()}},mouseUp:function(){this._mouseIsDown=false;if(this._dragTimer!==null){clearInterval(this._dragTimer);this._dragTimer=null}},moveCursorTo:function(j,q,t){var B=this.editor.layoutManager.textStorage,C=B.clampPosition(j);
this.setSelection({start:q?this.editor.buffer._selectedRange.start:C,end:C});if(t){q=B.lines.length;t=j.row;B=j.col;this.editor.buffer._selectedRangeEndVirtual=t>0&&t<q?j:{row:t<1?0:q-1,col:B}}else this.editor.buffer._selectedRangeEndVirtual=null;this.scrollToPosition(this.editor.buffer._selectedRange.end)},moveDown:function(){var j=this._getVirtualSelection();j=d.normalizeRange(j);j=this._rangeIsInsertionPoint(this.editor.buffer._selectedRange)?j.end:{row:j.end.row,col:j.start.col};j=d.addPositions(j,
{row:1,col:0});this.moveCursorTo(j,false,true)},moveLeft:function(){var j=d.normalizeRange(this.editor.buffer._selectedRange);this._rangeIsInsertionPoint(j)?this.moveCursorTo(this.editor.layoutManager.textStorage.displacePosition(j.start,-1)):this.moveCursorTo(j.start)},moveRight:function(){var j=d.normalizeRange(this.editor.buffer._selectedRange);this._rangeIsInsertionPoint(j)?this.moveCursorTo(this.editor.layoutManager.textStorage.displacePosition(j.end,1)):this.moveCursorTo(j.end)},moveUp:function(){var j=
d.normalizeRange(this._getVirtualSelection(true));position=d.addPositions({row:j.start.row,col:this._getVirtualSelection().end.col},{row:-1,col:0});this.moveCursorTo(position,false,true)},parentViewFrameChanged:function(){arguments.callee.base.apply(this,arguments);this._resize()},replaceCharacters:function(j,q){if(this._isReadOnly())return false;this.groupChanges(function(){j=d.normalizeRange(j);this.willReplaceRange(this,j);this.editor.layoutManager.textStorage.replaceCharacters(j,q);this.replacedCharacters(this,
j,q)}.bind(this));return true},performBackspaceOrDelete:function(j){if(this._isReadOnly())return false;var q=this.editor.layoutManager.textStorage,t=q.lines,B="";B=0;var C=g.get("tabstop"),e=this.getSelectedRange();if(d.isZeroLength(e))if(j){j=e.start;B=t[j.row];B=B.substring(0,j.col).match(/\s*$/)[0].length<C||(j.col-C)%C!=0?1:C;e={start:q.displacePosition(j,B*-1),end:e.end}}else{j=e.end;B=t[j.row];B=B.substring(j.col).match(/^\s*/)[0].length<C?1:C;e={start:e.start,end:q.displacePosition(e.end,B)}}this.groupChanges(function(){this.replaceCharacters(e,
"");this.moveCursorTo(e.start)}.bind(this));return true},resetKeyBuffers:function(){this._keyMetaBuffer=this._keyBuffer=""},scrollPageDown:function(){this._scrollPage(false)},scrollPageUp:function(){this._scrollPage(true)},scrollToPosition:function(j){var q=this.editor.layoutManager.characterRectForPosition(j);j=q.x;var t=q.y,B=q.width;q=q.height;var C=this.clippingFrame,e=C.x,K=C.y,L=this.padding,n=C.width-L.right;C=C.height-L.bottom;this.editor.scrollTo({x:j>=e+30&&j+B<e+n?e:j-n/2+B/2,y:t>=K&&t+
q<K+C?K:t-C/2+q/2})},selectAll:function(){var j=this.editor.layoutManager.textStorage.lines,q=j.length-1;this.setSelection({start:{row:0,col:0},end:{row:q,col:j[q].length}})},selectDown:function(){this._performVerticalKeyboardSelection(1)},selectLeft:function(){this.moveCursorTo(this.editor.layoutManager.textStorage.displacePosition(this.editor.buffer._selectedRange.end,-1),true)},selectRight:function(){this.moveCursorTo(this.editor.layoutManager.textStorage.displacePosition(this.editor.buffer._selectedRange.end,
1),true)},selectUp:function(){this._performVerticalKeyboardSelection(-1)},setSelection:function(j,q){var t=this.editor.layoutManager.textStorage;j=t.clampRange(j);if(!d.equal(j,this.editor.buffer._selectedRange)){this._invalidateSelection();this.editor.buffer._selectedRange=j=t.clampRange(j);this._invalidateSelection();this._hasFocus&&this._rearmInsertionPointBlinkTimer();q&&this.scrollToPosition(j.end);this.selectionChanged(j);v.publish(this.editor,"editorChange","selection",j)}},textInserted:function(j){if(j!==
"\n")if(!this.editor.processKeyEvent(j,this,{isTextView:true,isCommandKey:false})){this.insertText(j);this.resetKeyBuffers()}},_setFocus:function(j,q){if(j!=this._hasFocus)if(this._hasFocus=j){this._rearmInsertionPointBlinkTimer();this._invalidateSelection();q||this.textInput.focus()}else{if(this._insertionPointBlinkTimer){clearInterval(this._insertionPointBlinkTimer);this._insertionPointBlinkTimer=null}this._insertionPointVisible=true;this._invalidateSelection();q||this.textInput.blur()}}});Object.defineProperties(s.TextView.prototype,
{hasFocus:{get:function(){return this._hasFocus},set:function(j){this._setFocus(j,false)}}})});
bespin.tiki.module("text_editor:views/textinput",function(y,s){var v=y("bespin:util/util");y("events");var r=y("keyboard:keyutil");s.TextInput=function(l,h){var d=this.domNode=document.createElement("textarea");d.setAttribute("style","position: absolute; z-index: -99999; width: 0px; height: 0px; margin: 0px; outline: none; border: 0;");l.appendChild(d);this.delegate=h;this._attachEvents()};s.TextInput.prototype={_composing:false,domNode:null,delegate:null,_textFieldChanged:function(){if(!(this._composing||
this._ignore)){var l=this.domNode,h=l.value;if(h!=""){l.value="";this._textInserted(h)}}},_copy:function(){var l=false,h=this.delegate;if(h&&h.copy)l=h.copy();return l},_cut:function(){var l=false,h=this.delegate;if(h&&h.cut)l=h.cut();return l},_textInserted:function(l){var h=this.delegate;h&&h.textInserted&&h.textInserted(l)},_setValueAndSelect:function(l){var h=this.domNode;h.value=l;h.select()},focus:function(){this.domNode.focus()},blur:function(){this.domNode.blur()},_attachEvents:function(){var l=
this.domNode,h=this;l.addEventListener("focus",function(){h.delegate&&h.delegate.didFocus&&h.delegate.didFocus()},false);l.addEventListener("blur",function(){h.delegate&&h.delegate.didBlur&&h.delegate.didBlur()},false);r.addKeyDownListener(l,function(g){return h.delegate&&h.delegate.keyDown?h.delegate.keyDown(g):false});if(v.isWebKit){v.isChrome||l.addEventListener("compositionend",function(g){h._textInserted(g.data)},false);l.addEventListener("textInput",function(g){h._textInserted(g.data)},false);
l.addEventListener("paste",function(g){h._textInserted(g.clipboardData.getData("text/plain"));g.preventDefault()},false)}else{var d=h._textFieldChanged.bind(h);l.addEventListener("keydown",function(){window.setTimeout(d,0)},false);l.addEventListener("keypress",d,false);l.addEventListener("keyup",d,false);l.addEventListener("compositionstart",function(){h._composing=true},false);l.addEventListener("compositionend",function(){h._composing=false;h._textFieldChanged()},false);l.addEventListener("paste",
function(){h._setValueAndSelect("");window.setTimeout(function(){h._textFieldChanged()},0)},false)}var f=function(g){g=g.type.indexOf("copy")!=-1?h._copy():h._cut();h._setValueAndSelect(g)};if(v.isWebKit&&!v.isChrome&&v.isMac){var m=(new Date).getTime(),i=function(g){var j=g.type.indexOf("cut")!=-1;if(!(j&&(new Date).getTime()-m<10)){f(g);if(j)m=(new Date).getTime()}};l.addEventListener("beforecopy",i,false);l.addEventListener("beforecut",i,false)}else{i=false;if(v.isMozilla)i=function(g){f(g);h._ignore=
true;window.setTimeout(function(){h._setValueAndSelect("");h._ignore=false},0)};l.addEventListener("copy",i||f,false);l.addEventListener("cut",i||f,false)}}}});bespin.tiki.module("text_editor:index",function(){});bespin.tiki.register("::less",{name:"less",dependencies:{}});
bespin.tiki.module("less:index",function(y,s){function v(d){if(d instanceof h.Dimension)return parseFloat(d.unit=="%"?d.value/100:d.value);else if(typeof d==="number")return d;else throw{error:"RuntimeError",message:"color functions take numbers as parameters"};}function r(d){return Math.min(1,Math.max(0,d))}if(!Array.isArray)Array.isArray=function(d){return Object.prototype.toString.call(d)==="[object Array]"||d instanceof Array};if(!Array.prototype.forEach)Array.prototype.forEach=function(d,f){for(var m=
this.length>>>0,i=0;i<m;i++)i in this&&d.call(f,this[i],i,this)};if(!Array.prototype.map)Array.prototype.map=function(d,f){for(var m=this.length>>>0,i=new Array(m),g=0;g<m;g++)if(g in this)i[g]=d.call(f,this[g],g,this);return i};if(!Array.prototype.filter)Array.prototype.filter=function(d,f){for(var m=[],i=0;i<this.length;i++)d.call(f,this[i])&&m.push(this[i]);return m};if(!Array.prototype.reduce)Array.prototype.reduce=function(d){var f=this.length>>>0,m=0;if(f===0&&arguments.length===1)throw new TypeError;
if(arguments.length>=2)var i=arguments[1];else{do{if(m in this){i=this[m++];break}if(++m>=f)throw new TypeError;}while(1)}for(;m<f;m++)if(m in this)i=d.call(null,i,this[m],m,this);return i};if(!Array.prototype.indexOf)Array.prototype.indexOf=function(d,f){var m=this.length;f=f||0;if(!m)return-1;if(f>=m)return-1;if(f<0)f+=m;for(;f<m;f++)if(Object.prototype.hasOwnProperty.call(this,f))if(d===this[f])return f;return-1};if(!Object.keys)Object.keys=function(d){var f=[];for(var m in d)Object.prototype.hasOwnProperty.call(d,
m)&&f.push(m);return f};if(!String.prototype.trim)String.prototype.trim=function(){return String(this).replace(/^\s\s*/,"").replace(/\s\s*$/,"")};if(typeof y!=="undefined")var l=s,h={};else l=h={};l.Parser=function(d){function f(n){var w,D,J;if(n instanceof Function)return n.call(C.parsers);else if(typeof n==="string"){w=i.charAt(g)===n?n:null;D=1}else{if(g>=B+t[j].length&&j<t.length-1)B+=t[j++].length;n.lastIndex=J=g-B;if(w=n.exec(t[j])){D=w[0].length;if(n.lastIndex-D!==J)return}}if(w){g+=D;for(D=
B+t[j].length;g<=D;){n=i.charCodeAt(g);if(!(n===32||n===10||n===9))break;g++}return typeof w==="string"?w:w.length===1?w[0]:w}}function m(n){var w;if(typeof n==="string")return i.charAt(g)===n;else{n.lastIndex=g;if((w=n.exec(i))&&n.lastIndex-w[0].length===g)return w}}var i,g,j,q,t,B,C,e=this,K=function(){},L=this.imports={paths:d&&d.paths||[],queue:[],files:{},push:function(n,w){var D=this;this.queue.push(n);l.Parser.importer(n,this.paths,function(J){D.queue.splice(D.queue.indexOf(n),1);D.files[n]=
J;w(J);D.queue.length===0&&K()})}};this.env=d||{};this.optimization="optimization"in this.env?this.env.optimization:1;return C={imports:L,parse:function(n,w){var D,J,Q=null;g=j=B=q=0;t=[];i=n.replace(/\r\n/g,"\n");if(e.optimization>0){i=i.replace(/\/\*(?:[^*]|\*+[^\/*])*\*+\//g,function(ca){return e.optimization>1?"":ca.replace(/\n(\s*\n)+/g,"\n")});t=i.split(/^(?=\n)/mg)}else t=[i];D=new h.Ruleset([],f(this.parsers.primary));D.root=true;D.toCSS=function(ca){var ha,ga;return function(){try{return ca.call(this)}catch(la){ga=
i.split("\n");ha=(i.slice(0,la.index).match(/\n/g)||"").length+1;for(var ma=la.index,na=-1;ma>=0&&i.charAt(ma)!=="\n";ma--)na++;throw{name:"NameError",message:la.message,line:ha,column:na,extract:[ga[ha-2],ga[ha-1],ga[ha]]};}}}(D.toCSS);if(g<i.length-1){g=q;J=i.split("\n");n=(i.slice(0,g).match(/\n/g)||"").length+1;for(var Z=g,T=-1;Z>=0&&i.charAt(Z)!=="\n";Z--)T++;Q={name:"ParseError",message:"Syntax Error on line "+n,filename:d.filename,line:n,column:T,extract:[J[n-2],J[n-1],J[n]]}}if(this.imports.queue.length>
0)K=function(){w(Q,D)};else w(Q,D)},parsers:{primary:function(){for(var n,w=[];n=f(this.mixin.definition)||f(this.rule)||f(this.ruleset)||f(this.mixin.call)||f(this.comment)||f(/[\n\s]+/g)||f(this.directive);)w.push(n);return w},comment:function(){var n;if(i.charAt(g)==="/")return(n=f(/\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/g))?new h.Comment(n):f(/\/\/.*/g)},entities:{quoted:function(){var n;if(!(i.charAt(g)!=='"'&&i.charAt(g)!=="'"))if(n=f(/"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/g))return new h.Quoted(n[0],
n[1]||n[2])},keyword:function(){var n;if(n=f(/[A-Za-z-]+/g))return new h.Keyword(n)},call:function(){var n,w;if(n=f(/([a-zA-Z0-9_-]+|%)\(/g)){if(n[1].toLowerCase()==="alpha")return f(this.alpha);w=f(this.entities.arguments);if(f(")"))if(n)return new h.Call(n[1],w)}},arguments:function(){for(var n=[],w;w=f(this.expression);){n.push(w);if(!f(","))break}return n},literal:function(){return f(this.entities.dimension)||f(this.entities.color)||f(this.entities.quoted)},url:function(){var n;if(!(i.charAt(g)!==
"u"||!f(/url\(/g))){n=f(this.entities.quoted)||f(/[-a-zA-Z0-9_%@$\/.&=:;#+?]+/g);if(!f(")"))throw new Error("missing closing ) for url()");return new h.URL(n.value?n:new h.Anonymous(n))}},variable:function(){var n,w=g;if(i.charAt(g)==="@"&&(n=f(/@[a-zA-Z0-9_-]+/g)))return new h.Variable(n,w)},color:function(){var n;if(i.charAt(g)==="#"&&(n=f(/#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/g)))return new h.Color(n[1])},dimension:function(){var n;n=i.charCodeAt(g);if(!(n>57||n<45||n===47))if(n=f(/(-?[0-9]*\.?[0-9]+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm)?/g))return new h.Dimension(n[1],
n[2])}},variable:function(){var n;if(i.charAt(g)==="@"&&(n=f(/(@[a-zA-Z0-9_-]+)\s*:/g)))return n[1]},shorthand:function(){var n,w;if(m(/[@\w.-]+\/[@\w.-]+/g))if((n=f(this.entity))&&f("/")&&(w=f(this.entity)))return new h.Shorthand(n,w)},mixin:{call:function(){for(var n=[],w,D,J,Q=g;w=f(/[#.][a-zA-Z0-9_-]+/g);){n.push(new h.Element(D,w));D=f(">")}f("(")&&(J=f(this.entities.arguments))&&f(")");if(n.length>0&&(f(";")||m("}")))return new h.mixin.Call(n,J,Q)},definition:function(){var n,w=[],D,J;if(!(i.charAt(g)!==
"."||m(/[^{]*(;|})/g)))if(n=f(/([#.][a-zA-Z0-9_-]+)\s*\(/g)){for(n=n[1];D=f(/@[\w-]+/g)||f(this.entities.literal)||f(this.entities.keyword);){if(D[0]==="@")if(f(":"))if(J=f(this.expression))w.push({name:D,value:J});else throw new Error("Expected value");else w.push({name:D});else w.push({value:D});if(!f(","))break}if(!f(")"))throw new Error("Expected )");if(D=f(this.block))return new h.mixin.Definition(n,w,D)}}},entity:function(){return f(this.entities.literal)||f(this.entities.variable)||f(this.entities.url)||
f(this.entities.call)||f(this.entities.keyword)},end:function(){return f(";")||m("}")},alpha:function(){var n;if(f(/opacity=/gi))if(n=f(/[0-9]+/g)||f(this.entities.variable)){if(!f(")"))throw new Error("missing closing ) for alpha()");return new h.Alpha(n)}},element:function(){var n;c=f(this.combinator);if(n=f(/[.#:]?[a-zA-Z0-9_-]+/g)||f("*")||f(this.attribute)||f(/\([^)@]+\)/g))return new h.Element(c,n)},combinator:function(){var n;return(n=f(/[+>~]/g)||f("&")||f(/::/g))?new h.Combinator(n):new h.Combinator(i.charAt(g-
1)===" "?" ":null)},selector:function(){for(var n,w=[];n=f(this.element);)w.push(n);if(w.length>0)return new h.Selector(w)},tag:function(){return f(/[a-zA-Z][a-zA-Z-]*[0-9]?/g)||f("*")},attribute:function(){var n="",w,D,J;if(f("[")){if(w=f(/[a-z-]+/g)||f(this.entities.quoted))n=(J=f(/[|~*$^]?=/g))&&(D=f(this.entities.quoted)||f(/[\w-]+/g))?[w,J,D.toCSS?D.toCSS():D].join(""):w;if(f("]"))if(n)return"["+n+"]"}},block:function(){var n;if(f("{")&&(n=f(this.primary))&&f("}"))return n},ruleset:function(){var n=
[],w,D,J=g;if(w=m(/([a-z.#: _-]+)[\s\n]*\{/g)){g+=w[0].length-1;n=[new h.Selector([new h.Element(null,w[1])])]}else{for(;w=f(this.selector);){n.push(w);if(!f(","))break}w&&f(this.comment)}if(n.length>0&&(D=f(this.block)))return new h.Ruleset(n,D);else{q=g;g=J}},rule:function(){var n,w=g;if(name=f(this.property)||f(this.variable)){if(name.charAt(0)!="@"&&(match=m(/([^@+\/*(;{}-]*);/g))){g+=match[0].length-1;n=new h.Anonymous(match[1])}else n=name==="font"?f(this.font):f(this.value);if(f(this.end))return new h.Rule(name,
n,w);else{q=g;g=w}}},"import":function(){var n;if(f(/@import\s+/g)&&(n=f(this.entities.quoted)||f(this.entities.url))&&f(";"))return new h.Import(n,L)},directive:function(){var n,w,D;if(i.charAt(g)==="@")if(w=f(this["import"]))return w;else if(n=f(/@media|@page/g)){D=f(/[^{]+/g).trim();if(w=f(this.block))return new h.Directive(n+" "+D,w)}else if(n=f(/@[-a-z]+/g))if(n==="@font-face"){if(w=f(this.block))return new h.Directive(n,w)}else if((w=f(this.entity))&&f(";"))return new h.Directive(n,w)},font:function(){for(var n=
[],w=[],D;D=f(this.shorthand)||f(this.entity);)w.push(D);n.push(new h.Expression(w));if(f(","))for(;D=f(this.expression);){n.push(D);if(!f(","))break}return new h.Value(n,f(this.important))},value:function(){for(var n,w=[];n=f(this.expression);){w.push(n);if(!f(","))break}n=f(this.important);if(w.length>0)return new h.Value(w,n)},important:function(){return f(/!\s*important/g)},sub:function(){var n;if(f("(")&&(n=f(this.expression))&&f(")"))return n},multiplication:function(){var n,w,D,J;if(n=f(this.operand)){for(;(D=
f(/[\/*]/g))&&(w=f(this.operand));)J=new h.Operation(D,[J||n,w]);return J||n}},addition:function(){var n,w,D,J;if(n=f(this.multiplication)){for(;(D=f(/[-+]\s+/g)||i.charAt(g-1)!=" "&&f(/[-+]/g))&&(w=f(this.multiplication));)J=new h.Operation(D,[J||n,w]);return J||n}},operand:function(){return f(this.sub)||f(this.entities.dimension)||f(this.entities.color)||f(this.entities.variable)},expression:function(){for(var n,w=[];n=f(this.addition)||f(this.entity);)w.push(n);if(w.length>0)return new h.Expression(w)},
property:function(){var n;if(n=f(/(\*?-?[-a-z_0-9]+)\s*:/g))return n[1]}}}};l.Parser.importer=null;h.functions={rgb:function(d,f,m){return this.rgba(d,f,m,1)},rgba:function(d,f,m,i){d=[d,f,m].map(function(g){return v(g)});i=v(i);return new h.Color(d,i)},hsl:function(d,f,m){return this.hsla(d,f,m,1)},hsla:function(d,f,m,i){function g(t){t=t<0?t+1:t>1?t-1:t;return t*6<1?q+(j-q)*t*6:t*2<1?j:t*3<2?q+(j-q)*(2/3-t)*6:q}d=(v(d)%360+360)%360/360;f=v(f);m=v(m);i=v(i);var j=m<=0.5?m*(f+1):m+f-m*f,q=m*2-j;return this.rgba(g(d+
1/3)*255,g(d)*255,g(d-1/3)*255,i)},opacity:function(d,f){v(f);return new h.Color(d.rgb,v(f))},saturate:function(d,f){d=d.toHSL();d.s+=f.value/100;d.s=r(d.s);return this.hsl(d.h,d.s,d.l)},desaturate:function(d,f){d=d.toHSL();d.s-=f.value/100;d.s=r(d.s);return this.hsl(d.h,d.s,d.l)},lighten:function(d,f){d=d.toHSL();d.l*=1+f.value/100;d.l=r(d.l);return this.hsl(d.h,d.s,d.l)},darken:function(d,f){d=d.toHSL();d.l*=1-f.value/100;d.l=r(d.l);return this.hsl(d.h,d.s,d.l)},greyscale:function(d){return this.desaturate(d,
new h.Dimension(100))},e:function(d){return new h.Anonymous(d)},"%":function(d){for(var f=Array.prototype.slice.call(arguments,1),m=d.content,i=0;i<f.length;i++)m=m.replace(/%s/,f[i].content).replace(/%[da]/,f[i].toCSS());m=m.replace(/%%/g,"%");return new h.Quoted('"'+m+'"',m)}};h.Alpha=function(d){this.value=d};h.Alpha.prototype={toCSS:function(){return"alpha(opacity="+this.value.toCSS()+")"},eval:function(){return this}};h.Anonymous=function(d){this.value=d.content||d};h.Anonymous.prototype={toCSS:function(){return this.value},
eval:function(){return this}};h.Call=function(d,f){this.name=d;this.args=f};h.Call.prototype={eval:function(d){var f=this.args.map(function(m){return m.eval(d)});return this.name in h.functions?h.functions[this.name].apply(h.functions,f):new h.Anonymous(this.name+"("+f.map(function(m){return m.toCSS()}).join(", ")+")")},toCSS:function(d){return this.eval(d).toCSS()}};h.Color=function(d,f){if(Array.isArray(d)){this.rgb=d;this.alpha=f}else this.rgb=d.length==6?d.match(/.{2}/g).map(function(m){return parseInt(m,
16)}):d.split("").map(function(m){return parseInt(m+m,16)})};h.Color.prototype={eval:function(){return this},toCSS:function(){return this.alpha&&this.alpha<1?"rgba("+this.rgb.concat(this.alpha).join(", ")+")":"#"+this.rgb.map(function(d){d=Math.round(d);d=(d>255?255:d<0?0:d).toString(16);return d.length===1?"0"+d:d}).join("")},operate:function(d,f){var m=[];f instanceof h.Color||(f=f.toColor());for(var i=0;i<3;i++)m[i]=h.operate(d,this.rgb[i],f.rgb[i]);return new h.Color(m)},toHSL:function(){var d=
this.rgb[0]/255,f=this.rgb[1]/255,m=this.rgb[2]/255,i=Math.max(d,f,m),g=Math.min(d,f,m),j,q=(i+g)/2,t=i-g;if(i===g)j=g=0;else{g=q>0.5?t/(2-i-g):t/(i+g);switch(i){case d:j=(f-m)/t+(f<m?6:0);break;case f:j=(m-d)/t+2;break;case m:j=(d-f)/t+4;break}j/=6}return{h:j*360,s:g,l:q}}};h.Comment=function(d){this.value=d};h.Comment.prototype={toCSS:function(){return this.value}};h.Dimension=function(d,f){this.value=parseFloat(d);this.unit=f||null};h.Dimension.prototype={eval:function(){return this},toColor:function(){return new h.Color([this.value,
this.value,this.value])},toCSS:function(){return this.value+this.unit},operate:function(d,f){return new h.Dimension(h.operate(d,this.value,f.value),this.unit||f.unit)}};h.Directive=function(d,f){this.name=d;if(Array.isArray(f))this.ruleset=new h.Ruleset([],f);else this.value=f};h.Directive.prototype={toCSS:function(d,f){if(this.ruleset){this.ruleset.root=true;return this.name+" {\n "+this.ruleset.toCSS(d,f).trim().replace(/\n/g,"\n ")+"\n}\n"}else return this.name+" "+this.value.toCSS()+";\n"},
eval:function(d){d.frames.unshift(this);this.ruleset&&this.ruleset.evalRules(d);d.frames.shift();return this},variable:function(d){return h.Ruleset.prototype.variable.call(this.ruleset,d)},find:function(){return h.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return h.Ruleset.prototype.rulesets.apply(this.ruleset)}};h.Element=function(d,f){this.combinator=d instanceof h.Combinator?d:new h.Combinator(d);this.value=f.trim()};h.Element.prototype.toCSS=function(){return this.combinator.toCSS()+
this.value};h.Combinator=function(d){this.value=d===" "?" ":d?d.trim():""};h.Combinator.prototype.toCSS=function(){switch(this.value){case "":return"";case " ":return" ";case "&":return"";case ":":return" :";case "::":return"::";case "+":return" + ";case "~":return" ~ ";case ">":return" > "}};h.Expression=function(d){this.value=d};h.Expression.prototype={eval:function(d){return this.value.length>1?new h.Expression(this.value.map(function(f){return f.eval(d)})):this.value[0].eval(d)},toCSS:function(){return this.value.map(function(d){return d.toCSS()}).join(" ")}};
h.Import=function(d,f){var m=this;this._path=d;this.path=d instanceof h.Quoted?/\.(le?|c)ss$/.test(d.content)?d.content:d.content+".less":d.value.content||d.value;(this.css=/css$/.test(this.path))||f.push(this.path,function(i){m.root=i})};h.Import.prototype={toCSS:function(){return this.css?"@import "+this._path.toCSS()+";\n":""},eval:function(){if(this.css)return this;else{for(var d=0;d<this.root.rules.length;d++)this.root.rules[d]instanceof h.Import&&Array.prototype.splice.apply(this.root.rules,
[d,1].concat(this.root.rules[d].eval()));return this.root.rules}}};h.Keyword=function(d){this.value=d};h.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value}};h.mixin={};h.mixin.Call=function(d,f,m){this.selector=new h.Selector(d);this.arguments=f;this.index=m};h.mixin.Call.prototype={eval:function(d){for(var f,m=[],i=false,g=0;g<d.frames.length;g++)if((f=d.frames[g].find(this.selector)).length>0){for(g=0;g<f.length;g++)if(f[g].match(this.arguments,d))try{Array.prototype.push.apply(m,
f[g].eval(this.arguments,d).rules);i=true}catch(j){throw{message:j.message,index:this.index};}if(i)return m;else throw{message:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+this.arguments.map(function(q){return q.toCSS()}).join(", ")+")`",index:this.index};}throw{message:this.selector.toCSS().trim()+" is undefined",index:this.index};}};h.mixin.Definition=function(d,f,m){this.name=d;this.selectors=[new h.Selector([new h.Element(null,d)])];this.params=f;this.arity=f.length;
this.rules=m;this._lookups={};this.required=f.reduce(function(i,g){return g.name&&!g.value?i+1:i},0)};h.mixin.Definition.prototype={toCSS:function(){return""},variable:function(d){return h.Ruleset.prototype.variable.call(this,d)},find:function(){return h.Ruleset.prototype.find.apply(this,arguments)},rulesets:function(){return h.Ruleset.prototype.rulesets.apply(this)},eval:function(d,f){for(var m=new h.Ruleset(null,[]),i=0,g;i<this.params.length;i++)if(this.params[i].name)if(g=d&&d[i]||this.params[i].value)m.rules.unshift(new h.Rule(this.params[i].name,
g.eval(f)));else throw{message:"wrong number of arguments for "+this.name+" ("+d.length+" for "+this.arity+")"};return(new h.Ruleset(null,this.rules)).evalRules({frames:[this,m].concat(f.frames)})},match:function(d,f){var m=d&&d.length||0;if(m<this.required)return false;for(var i=0;i<Math.min(m,this.arity);i++)if(!this.params[i].name)if(!d[i].wildcard)if(d[i].eval(f).toCSS()!=this.params[i].value.eval(f).toCSS())return false;return true}};h.Operation=function(d,f){this.op=d.trim();this.operands=f};
h.Operation.prototype.eval=function(d){var f=this.operands[0].eval(d);d=this.operands[1].eval(d);var m;if(f instanceof h.Dimension&&d instanceof h.Color)if(this.op==="*"||this.op==="+"){m=d;d=f;f=m}else throw{name:"OperationError",message:"Can't substract or divide a color from a number"};return f.operate(this.op,d)};h.operate=function(d,f,m){switch(d){case "+":return f+m;case "-":return f-m;case "*":return f*m;case "/":return f/m}};h.Quoted=function(d,f){this.value=d;this.content=f};h.Quoted.prototype=
{toCSS:function(){return this.value},eval:function(){return this}};h.Rule=function(d,f,m){this.name=d;this.value=f instanceof h.Value?f:new h.Value([f]);this.index=m;this.variable=d.charAt(0)==="@"?true:false};h.Rule.prototype.toCSS=function(){return this.variable?"":this.name+": "+this.value.toCSS()+";"};h.Rule.prototype.eval=function(d){return new h.Rule(this.name,this.value.eval(d))};h.Value=function(d){this.value=d;this.is="value"};h.Value.prototype={eval:function(d){return this.value.length===
1?this.value[0].eval(d):new h.Value(this.value.map(function(f){return f.eval(d)}))},toCSS:function(){return this.value.map(function(d){return d.toCSS()}).join(", ")}};h.Shorthand=function(d,f){this.a=d;this.b=f};h.Shorthand.prototype={toCSS:function(d){return this.a.toCSS(d)+"/"+this.b.toCSS(d)},eval:function(){return this}};h.Ruleset=function(d,f){this.selectors=d;this.rules=f;this._lookups={}};h.Ruleset.prototype={eval:function(){return this},evalRules:function(d){var f=[];this.rules.forEach(function(m){if(m.evalRules)f.push(m.evalRules(d));
else m instanceof h.mixin.Call?Array.prototype.push.apply(f,m.eval(d)):f.push(m.eval(d))});this.rules=f;return this},match:function(d){return!d||d.length===0},variable:function(d){return this._variables?this._variables[d]:(this._variables=this.rules.reduce(function(f,m){if(m instanceof h.Rule&&m.variable===true)f[m.name]=m;return f},{}))[d]},rulesets:function(){return this._rulesets?this._rulesets:(this._rulesets=this.rules.filter(function(d){if(d instanceof h.Ruleset||d instanceof h.mixin.Definition)return d}))},
find:function(d,f){f=f||this;var m=[],i=d.toCSS();if(i in this._lookups)return this._lookups[i];this.rulesets().forEach(function(g){if(g!==f)for(var j=0;j<g.selectors.length;j++)if(d.match(g.selectors[j])){d.elements.length>1?Array.prototype.push.apply(m,g.find(new h.Selector(d.elements.slice(1)),f)):m.push(g);break}});return this._lookups[i]=m},toCSS:function(d,f){var m=[],i=[],g=[],j=[];if(this.root){d=[];f={frames:[]};for(var q=0;q<this.rules.length;q++)this.rules[q]instanceof h.Import&&Array.prototype.splice.apply(this.rules,
[q,1].concat(this.rules[q].eval(f)))}else if(d.length===0)j=this.selectors.map(function(B){return[B]});else for(q=0;q<this.selectors.length;q++)for(var t=0;t<d.length;t++)j.push(d[t].concat([this.selectors[q]]));f.frames.unshift(this);for(q=0;q<this.rules.length;q++)this.rules[q]instanceof h.mixin.Call&&Array.prototype.splice.apply(this.rules,[q,1].concat(this.rules[q].eval(f)));for(q=0;q<this.rules.length;q++){d=this.rules[q];if(d instanceof h.Directive)g.push(d.eval(f).toCSS(j,f));else if(d.rules)g.push(d.toCSS(j,
f));else if(d instanceof h.Comment)this.root?g.push(d.toCSS()):i.push(d.toCSS());else if(d.toCSS&&!d.variable)i.push(d.eval(f).toCSS());else d.value&&!d.variable&&i.push(d.value.toString())}g=g.join("");if(this.root)m.push(i.join("\n"));else if(i.length>0){j=j.map(function(B){return B.map(function(C){return C.toCSS()}).join("").trim()}).join(j.length>3?",\n":", ");m.push(j," {\n "+i.join("\n ")+"\n}\n")}m.push(g);f.frames.shift();return m.join("")}};h.Selector=function(d){this.elements=d;if(this.elements[0].combinator.value===
"")this.elements[0].combinator.value=" "};h.Selector.prototype.match=function(d){return this.elements[0].value===d.elements[0].value?true:false};h.Selector.prototype.toCSS=function(){if(this._css)return this._css;return this._css=this.elements.map(function(d){return typeof d==="string"?" "+d.trim():d.toCSS()}).join("")};h.URL=function(d){this.value=d};h.URL.prototype={toCSS:function(){return"url("+this.value.toCSS()+")"},eval:function(){return this}};h.Variable=function(d,f){this.name=d;this.index=
f};h.Variable.prototype={eval:function(d){var f,m,i=this.name;if(f=h.find(d.frames,function(g){if(m=g.variable(i))return m.value.eval(d)}))return f;else throw{message:"variable "+this.name+" is undefined",index:this.index};}};h.find=function(d,f){for(var m=0,i;m<d.length;m++)if(i=f.call(d,d[m]))return i;return null};(function(){function d(C){for(var e=0;e<t.length;e++)f(t[e],C)}function f(C,e){var K=typeof localStorage!=="undefined"&&localStorage.getItem(C.href),L=K&&JSON.parse(K);i(C.href,function(n,
w){if(L&&(new Date(w)).valueOf()===(new Date(L.timestamp)).valueOf()){m(L.css,C);e(null,C,{local:true})}else(new l.Parser({optimization:3})).parse(n,function(D,J){if(D)return q(D,C.href);try{e(J,C,{local:false,lastModified:w})}catch(Q){q(Q,C.href)}})},function(n){throw new Error("Couldn't load "+C.href+" ("+n+")");})}function m(C,e,K){var L=document.createElement("style");L.type="text/css";L.media="screen";L.title="less-sheet";if(e){L.title=e.title||e.href.match(/(?:^|\/)([-\w]+)\.[a-z]+$/i)[1];K&&
typeof localStorage!=="undefined"&&localStorage.setItem(e.href,JSON.stringify({timestamp:K,css:C}))}if(L.styleSheet)L.styleSheet.cssText=C;else L.appendChild(document.createTextNode(C));document.getElementsByTagName("head")[0].appendChild(L)}function i(C,e,K){var L=g();if(window.location.protocol==="file:"){L.open("GET",C,false);L.send(null);L.status===0?e(L.responseText):K(L.status)}else{L.open("GET",C,true);L.onreadystatechange=function(){if(L.readyState==4)if(L.status>=200&&L.status<300)e(L.responseText,
L.getResponseHeader("Last-Modified"));else typeof K==="function"&&K(L.status)};L.send(null)}}function g(){if(window.XMLHttpRequest)return new XMLHttpRequest;else try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(C){j("less: browser doesn't support AJAX.");return null}}function j(C){l.env=="development"&&typeof console!=="undefined"&&console.log(C)}function q(C,e){var K=document.createElement("div"),L;K.id="less-error-message";K.innerHTML="<h3>"+(C.message||"There is an error in your .less file")+
'</h3><p><a href="'+e+'">'+e+"</a> on line "+C.line+", column "+(C.column+1)+":</p>"+'<div>\n<pre class="ctx"><span>[-1]</span>{0}</pre>\n<pre><span>[0]</span>{current}</pre>\n<pre class="ctx"><span>[1]</span>{2}</pre>\n</div>'.replace(/\[(-?\d)\]/g,function(n,w){return C.line+parseInt(w)}).replace(/\{(\d)\}/g,function(n,w){return C.extract[parseInt(w)]}).replace(/\{current\}/,C.extract[1].slice(0,C.column)+'<span class="error">'+C.extract[1].slice(C.column)+"</span>");m("#less-error-message span {margin-right: 15px;}#less-error-message pre {color: #ee4444;padding: 4px 0;margin: 0;}#less-error-message pre.ctx {color: #dd7777;}#less-error-message h3 {padding: 15px 0 5px 0;margin: 0;}#less-error-message a {color: #10a}#less-error-message .error {color: red;font-weight: bold;padding-bottom: 2px;border-bottom: 1px dashed red;}");
K.style.cssText="font-family: Arial, sans-serif;border: 1px solid #e00;background-color: #eee;border-radius: 5px;color: #e00;padding: 15px;margin-bottom: 15px";if(l.env=="development")L=setInterval(function(){if(document.body){document.body.insertBefore(K,document.body.childNodes[0]);clearInterval(L)}},10)}var t=[];l.env=location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.protocol=="file:"?"development":"production";var B=setInterval(function(){if(document.body){if(!document.querySelectorAll&&
typeof jQuery==="undefined")j("No selector method found");else t=(document.querySelectorAll||jQuery).call(document,'link[rel="stylesheet/less"]');clearInterval(B);d(function(C,e,K){m(C.toCSS(),e,K.lastModified);K.local?j("less: loading "+e.href+" from local storage."):j("less: parsed "+e.href+" successfully.")})}},10);if(l.env==="development")refreshTimer=setInterval(function(){/!refresh/.test(location.hash)&&d(function(C,e,K){m(C.toCSS(),e,K)})},1E3);l.Parser.importer=function(C,e,K){f({href:C,title:C},
function(L){K(L)})}})()});bespin.tiki.register("::theme_manager_base",{name:"theme_manager_base",dependencies:{}});bespin.tiki.module("theme_manager_base:index",function(){});bespin.tiki.register("::canon",{name:"canon",dependencies:{environment:"0.0.0",events:"0.0.0",settings:"0.0.0"}});
bespin.tiki.module("canon:history",function(y,s){var v=y("bespin:util/stacktrace").Trace,r=y("bespin:plugins").catalog;s.requests=[];s.addRequestOutput=function(l){for(s.requests.push(l);s.requests.length>100;)s.requests.shiftObject();r.publish(this,"addedRequestOutput",null,l)};s.execute=function(l,h){if(h.command)try{h.command(l,h)}catch(d){var f=new v(d,true);console.group("Error executing command '"+h.typed+"'");console.log("command=",h.commandExt);console.log("args=",l);console.error(d);f.log(3);
console.groupEnd();h.doneWithError(d)}else h.doneWithError("Command not found.")}});
bespin.tiki.module("canon:request",function(y,s){var v=y("events").Event,r=y("canon:history");s.Request=function(l){l=l||{};this.command=l.command;this.commandExt=l.commandExt;this.args=l.args;this.typed=l.typed;this._begunOutput=false;this.start=new Date;this.end=null;this.error=this.completed=false;this.changed=new v};s.Request.prototype._beginOutput=function(){this._begunOutput=true;this.outputs=[];r.addRequestOutput(this)};s.Request.prototype.doneWithError=function(l){this.error=true;this.done(l)};
s.Request.prototype.async=function(){this._begunOutput||this._beginOutput()};s.Request.prototype.output=function(l){this._begunOutput||this._beginOutput();if(typeof l!=="string"&&!(l instanceof Node))l=l.toString();this.outputs.push(l);this.changed();return this};s.Request.prototype.done=function(l){this.completed=true;this.end=new Date;this.duration=this.end.getTime()-this.start.getTime();l?this.output(l):this.changed()}});bespin.tiki.module("canon:index",function(){});
bespin.tiki.register("::traits",{name:"traits",dependencies:{}});
bespin.tiki.module("traits:index",function(y,s){s.Trait=function(){function v(O){var P=function(){throw new Error("Conflicting property: "+O);};T(P.prototype);return T(P)}function r(){return T({value:undefined,enumerable:false,required:true})}function l(O){O=v(O);return n?T({get:O,set:O,enumerable:false,conflict:true}):T({value:O,enumerable:false,conflict:true})}function h(O,P){return O===P?O!==0||1/O===1/P:O!==O&&P!==P}function d(O,P){return O.conflict&&P.conflict?true:O.get===P.get&&O.set===P.set&&
h(O.value,P.value)&&O.enumerable===P.enumerable&&O.required===P.required&&O.conflict===P.conflict}function f(O,P){return T(D(O,P))}function m(O){var P={};Z(O,function(S){P[S]=true});return T(P)}function i(O){var P={};Z(ca(O),function(S){var U=ha(O,S);if(U.value===na)U=r(S);else if(typeof U.value==="function"){U.method=true;"prototype"in U.value&&T(U.value.prototype)}else{U.get&&U.get.prototype&&T(U.get.prototype);U.set&&U.set.prototype&&T(U.set.prototype)}P[S]=U});return P}function g(){var O=Q(arguments,
0),P={};Z(O,function(S){Z(ca(S),function(U){var aa=S[U];if(J(P,U)&&!P[U].required)aa.required||d(P[U],aa)||(P[U]=l(U));else P[U]=aa})});return T(P)}function j(O,P){var S=m(O),U={};Z(ca(P),function(aa){U[aa]=!J(S,aa)||P[aa].required?P[aa]:r(aa)});return T(U)}function q(){var O=Q(arguments,0),P={};Z(O,function(S){Z(ca(S),function(U){var aa=S[U];if(!J(P,U)||P[U].required)P[U]=aa})});return T(P)}function t(O,P){var S={};Z(ca(P),function(U){if(J(O,U)&&!P[U].required){var aa=O[U];S[aa]=J(S,aa)&&!S[aa].required?
l(aa):P[U];J(S,U)||(S[U]=r(U))}else if(J(S,U))P[U].required||(S[U]=l(U));else S[U]=P[U]});return T(S)}function B(O,P){var S={},U=[];for(var aa in O)if(J(O,aa))if(O[aa])S[aa]=O[aa];else U.push(aa);return t(S,j(U,P))}function C(O,P){var S=ma(O),U={};Z(ca(P),function(aa){var fa=P[aa];if(fa.required&&!(aa in O))throw new Error("Missing required property: "+aa);else if(fa.conflict)throw new Error("Remaining conflicting property: "+aa);else U[aa]="value"in fa?fa.method?{value:f(fa.value,S),enumerable:fa.enumerable,
configurable:fa.configurable,writable:fa.writable}:fa:{get:fa.get?f(fa.get,S):undefined,set:fa.set?f(fa.set,S):undefined,enumerable:fa.enumerable,configurable:fa.configurable,writable:fa.writable}});la(S,U);return T(S)}function e(O,P){return C(Object.prototype,i(O),P)}function K(O,P){var S=ca(O),U=ca(P);if(S.length!==U.length)return false;for(var aa=0;aa<S.length;aa++){U=S[aa];if(!P[U]||!d(O[U],P[U]))return false}return true}function L(O){return i(O)}var n=!!Object.defineProperty,w=Function.prototype.call,
D=Function.prototype.bind?function(O,P){return Function.prototype.bind.call(O,P)}:function(O,P){function S(){return O.apply(P,arguments)}return S},J=D(w,Object.prototype.hasOwnProperty),Q=D(w,Array.prototype.slice),Z=Array.prototype.forEach?D(w,Array.prototype.forEach):function(O,P){for(var S=0,U=O.length;S<U;S++)P(O[S])},T=Object.freeze||function(O){return O},ca=Object.getOwnPropertyNames||function(O){var P=[];for(var S in O)J(O,S)&&P.push(S);return P},ha=Object.getOwnPropertyDescriptor||function(O,
P){return{value:O[P],enumerable:true,writable:true,configurable:true}},ga=Object.defineProperty||function(O,P,S){O[P]=S.value},la=Object.defineProperties||function(O,P){for(var S in P)J(P,S)&&ga(O,S,P[S])},ma=Object.create||function(O,P){function S(){}S.prototype=O||Object.prototype;O=new S;P&&la(O,P);return O};w=Object.getOwnProperties||function(O){var P={};Z(ca(O),function(S){P[S]=ha(O,S)});return P};var na=T({toString:function(){return"<Trait.required>"}});if(!Object.create)Object.create=ma;if(!Object.getOwnProperties)Object.getOwnProperties=
w;L.required=T(na);L.compose=T(g);L.resolve=T(B);L.override=T(q);L.create=T(C);L.eqv=T(K);L.object=T(e);return T(L)}()});bespin.tiki.register("::keyboard",{name:"keyboard",dependencies:{canon:"0.0.0",settings:"0.0.0"}});
bespin.tiki.module("keyboard:keyboard",function(y,s){var v=y("bespin:plugins").catalog;y("bespin:console");y("bespin:util/stacktrace");var r=y("bespin:util/util"),l=y("settings").settings,h=y("keyboard:keyutil"),d=y("canon:history"),f=y("canon:request").Request,m=y("environment").env;s.buildFlags=function(i){i.context=m.contexts[0];return i};y=function(){};r.mixin(y.prototype,{_customKeymappingCache:{states:{}},processKeyEvent:function(i,g,j){i=h.commandCodes(i,true)[0];if(r.none(i))return false;
s.buildFlags(j);j.isCommandKey=true;return this._matchCommand(i,g,j)},_matchCommand:function(i,g,j){var q=this._findCommandExtension(i,g,j);if(q&&q.commandExt!=="no command"){j.isTextView&&g.resetKeyBuffers();var t=q.commandExt;t.load(function(B){B=new f({command:B,commandExt:t});d.execute(q.args,B)});return true}return q&&q.commandExt==="no command"?true:false},_buildBindingsRegex:function(i){i.forEach(function(g){if(r.none(g.key))if(Array.isArray(g.regex)){g.key=new RegExp("^"+g.regex[1]+"$");g.regex=
new RegExp(g.regex.join("")+"$")}else g.regex=new RegExp(g.regex+"$");else g.key=new RegExp("^"+g.key+"$")})},_buildKeymappingRegex:function(i){for(state in i.states)this._buildBindingsRegex(i.states[state]);i._convertedRegExp=true},_findCommandExtension:function(i,g,j){if(j.isTextView){var q=g._keyState;if(!j.isCommandKey||i.indexOf("alt_")===-1){g._keyBuffer+=i.replace(/ctrl_meta|meta/,"ctrl");g._keyMetaBuffer+=i}var t=[this._customKeymappingCache];t=t.concat(v.getExtensions("keymapping"));for(var B=
0;B<t.length;B++)if(!r.none(t[B].states[q])){r.none(t[B]._convertedRegExp)&&this._buildKeymappingRegex(t[B]);var C=this._bindingsMatch(i,j,g,t[B]);if(!r.none(C))return C}}g=v.getExtensions("command");var e=null;q={};i=i.replace(/ctrl_meta|meta/,"ctrl");g.some(function(K){if(this._commandMatches(K,i,j)){e=K;return true}return false}.bind(this));return r.none(e)?null:{commandExt:e,args:q}},_bindingsMatch:function(i,g,j,q){var t,B=null,C={},e;e=r.none(q.hasMetaKey)?j._keyMetaBuffer:j._keyBuffer;if(i.indexOf("alt_")===
0&&g.isCommandKey)e+=i;q.states[j._keyState].some(function(K){if(K.key&&!K.key.test(i))return false;if(K.regex&&!(t=K.regex.exec(e)))return false;if(K.disallowMatches)for(var L=0;L<K.disallowMatches.length;L++)if(t[K.disallowMatches[L]])return true;if(!s.flagsMatch(K.predicates,g))return false;if(K.exec){B=v.getExtensionByKey("command",K.exec);if(r.none(B))throw new Error("Can't find command "+K.exec+" in state="+j._keyState+", symbolicName="+i);if(K.params){var n;K.params.forEach(function(w){n=!r.none(w.match)&&
!r.none(t)?t[w.match]||w.defaultValue:w.defaultValue;if(w.type==="number")n=parseInt(n);C[w.name]=n})}j.resetKeyBuffers()}if(K.then){j._keyState=K.then;j.resetKeyBuffers()}if(r.none(B))B="no command";return true});if(r.none(B))return null;return{commandExt:B,args:C}},_commandMatches:function(i,g,j){var q=i.key;if(!q)return false;if(!s.flagsMatch(i.predicates,j))return false;if(typeof q==="string"){if(q!=g)return false;return true}if(!Array.isArray(q)){q=[q];i.key=q}for(i=0;i<q.length;i++){var t=q[i];
if(typeof t==="string"){if(t==g)return true}else if(t.key==g)return s.flagsMatch(t.predicates,j)}return false},_customKeymappingChanged:function(){var i=this._customKeymappingCache=JSON.parse(l.get("customKeymapping"));i.states=i.states||{};for(state in i.states)this._buildBindingsRegex(i.states[state]);i._convertedRegExp=true}});s.flagsMatch=function(i,g){if(r.none(i))return true;if(!g)return false;for(var j in i)if(g[j]!==i[j])return false;return true};s.keyboardManager=new y;v.registerExtension("settingChange",
{match:"customKeymapping",pointer:s.keyboardManager._customKeymappingChanged.bind(s.keyboardManager)})});
bespin.tiki.module("keyboard:keyutil",function(y,s){var v=y("bespin:util/util");s.KeyHelper=function(){var l={MODIFIER_KEYS:{16:"shift",17:"ctrl",18:"alt",224:"meta"},FUNCTION_KEYS:{8:"backspace",9:"tab",13:"return",19:"pause",27:"escape",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",44:"printscreen",45:"insert",46:"delete",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scrolllock"},PRINTABLE_KEYS:{32:" ",
48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",61:"=",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",107:"+",109:"-",110:".",188:",",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:'"'},PRINTABLE_KEYS_CHARCODE:{},KEY:{}};for(var h in l.PRINTABLE_KEYS){var d=l.PRINTABLE_KEYS[h];l.PRINTABLE_KEYS_CHARCODE[d.charCodeAt(0)]=h;if(d.toUpperCase()!=
d)l.PRINTABLE_KEYS_CHARCODE[d.toUpperCase().charCodeAt(0)]=h}for(h in l.FUNCTION_KEYS){d=l.FUNCTION_KEYS[h].toUpperCase();l.KEY[d]=parseInt(h,10)}return l}();var r=function(l){return!!(l.altKey||l.ctrlKey||l.metaKey||l.charCode!==l.which&&s.KeyHelper.FUNCTION_KEYS[l.which])};s.commandCodes=function(l,h){var d=l._keyCode||l.keyCode,f=l._charCode===undefined?l.charCode:l._charCode,m=null,i=null,g="",j=true;if(d===0&&l.which===0)return false;if(f!==0)return false;if(s.KeyHelper.MODIFIER_KEYS[f])return[s.KeyHelper.MODIFIER_KEYS[f],
null];if(d){m=s.KeyHelper.FUNCTION_KEYS[d];if(!m&&(l.altKey||l.ctrlKey||l.metaKey)){m=s.KeyHelper.PRINTABLE_KEYS[d];if(d>47&&d<58)j=l.altKey}if(m){if(l.altKey)g+="alt_";if(l.ctrlKey)g+="ctrl_";if(l.metaKey)g+="meta_"}else if(l.ctrlKey||l.metaKey)return false}if(!m){d=l.which;i=m=String.fromCharCode(d);d=m.toLowerCase();if(l.metaKey){g="meta_";m=d}else m=null}if(l.shiftKey&&m&&j)g+="shift_";if(m)m=g+m;if(!h&&m)m=m.replace(/ctrl_meta|meta/,"ctrl");return[m,i]};s.addKeyDownListener=function(l,h){var d=
function(f){var m=h(f);m&&v.stopEvent(f);return m};l.addEventListener("keydown",function(f){if(v.isMozilla)if(s.KeyHelper.FUNCTION_KEYS[f.keyCode])return true;else if((f.ctrlKey||f.metaKey)&&s.KeyHelper.PRINTABLE_KEYS[f.keyCode])return true;if(r(f))return d(f);return true},false);l.addEventListener("keypress",function(f){if(v.isMozilla)if(s.KeyHelper.FUNCTION_KEYS[f.keyCode])return d(f);else if((f.ctrlKey||f.metaKey)&&s.KeyHelper.PRINTABLE_KEYS_CHARCODE[f.charCode]){f._keyCode=s.KeyHelper.PRINTABLE_KEYS_CHARCODE[f.charCode];
f._charCode=0;return d(f)}if(f.charCode!==undefined&&f.charCode===0)return true;return d(f)},false)}});bespin.tiki.module("keyboard:index",function(){});bespin.tiki.register("::worker_manager",{name:"worker_manager",dependencies:{canon:"0.0.0",events:"0.0.0",underscore:"0.0.0"}});
bespin.tiki.module("worker_manager:index",function(y,s){function v(g){var j=/^([^#:]+)(?::([^#:]+))?#([^#:]+)$/.exec(g);if(j==null)throw new Error('WorkerSupervisor: invalid pointer specification: "'+g+'"');g=j[1];var q=j[3];j=g+":"+(j[2]!=null?j[2]:"index");var t=bespin!=null&&bespin.base!=null?bespin.base:"";this._packageId=g;this._moduleId=j;this._base=t;this._target=q;this._worker=null;this._currentId=0;this.started=new f}function r(){i.restartAll()}if(window==null)throw new Error('The "worker_manager" plugin can only be loaded in the browser, not a web worker. Use "worker" instead.');
var l=y("bespin:proxy");y("bespin:plugins");var h=y("bespin:console").console,d=y("underscore")._,f=y("events").Event,m=y("bespin:promise").Promise;y("environment");var i={_workers:[],add:function(g){this._workers.push(g)},remove:function(g){this._workers=d(this._workers).without(g)},restartAll:function(){var g=this._workers;d(g).invoke("kill");d(g).invoke("start")}};v.prototype={_onError:function(g){this._worker=null;i.remove(this);h.error("WorkerSupervisor: worker failed at file "+g.filename+":"+
g.lineno+"; fix the worker and use 'worker restart' to restart it")},_onMessage:function(g){g=JSON.parse(g.data);switch(g.op){case "finish":if(g.id===this._currentId){var j=this._promise;this._promise=null;j.resolve(g.result)}break;case "log":h[g.method].apply(h,g.args);break}},_promise:null,started:null,kill:function(){var g=this._promise;if(g!=null){g.reject("killed");this._promise=null}this._worker.terminate();this._worker=null;i.remove(this)},send:function(g,j){var q=this._promise;if(q!=null){q.reject("interrupted");
this._currentId++}q=this._currentId;var t=new m;this._promise=t;this._worker.postMessage(JSON.stringify({op:"invoke",id:q,method:g,args:j}));return t},start:function(){if(this._worker!=null)throw new Error("WorkerSupervisor: worker already started");var g=this._base,j=this._target,q=this._packageId,t=this._moduleId,B=new l.Worker(g+"BespinEmbedded.js");B.onmessage=this._onMessage.bind(this);B.onerror=this._onError.bind(this);B.postMessage(JSON.stringify({op:"load",base:g,pkg:q,module:t,target:j}));
this._worker=B;this._currentId=0;i.add(this);this.started()}};s.WorkerSupervisor=v;s.workerManager=i;s.workerRestartCommand=r});bespin.tiki.register("::edit_session",{name:"edit_session",dependencies:{events:"0.0.0"}});
bespin.tiki.module("edit_session:index",function(y,s){y("bespin:promise");y("bespin:plugins");y("bespin:util/util");y("events");s.EditSession=function(){};s.EditSession.prototype={_currentView:null,currentUser:null,history:null,getCompletePath:function(v){if(v==null)v="";if(v==null||v.substring(0,1)!="/"){var r;if(this._currentView&&this._currentView.buffer)r=this._currentView.buffer;var l;if(r)l=r.file;v=l?l.parentdir()+v:"/"+v}return v}};Object.defineProperties(s.EditSession.prototype,{currentView:{set:function(v){if(v!==
this._currentView)this._currentView=v},get:function(){return this._currentView}}});s.createSession=function(v,r){var l=new s.EditSession;if(v)l.currentView=v.textView;if(r)l.currentUser=r;return l}});bespin.tiki.register("::syntax_manager",{name:"syntax_manager",dependencies:{worker_manager:"0.0.0",events:"0.0.0",underscore:"0.0.0",syntax_directory:"0.0.0"}});
bespin.tiki.module("syntax_manager:index",function(y,s){function v(g,j,q,t){for(;g.length<j;)g.push(d(t).clone());j=[j,q.length].concat(q);Array.prototype.splice.apply(g,j);return g}function r(){this._lines=[];this._syms={}}function l(g,j){this._syntaxInfo=g;this._syntaxManager=j;this._invalidRow=0;this._states=[];this._active=false;this.symbols=new r}function h(g){this.layoutManager=g;this.attrsChanged=new f;this.syntaxChanged=new f;this._contextRanges=this._invalidRows=this._context=null;this._attrs=
[];this._symbols=new r;this._syntax="plain";this._reset()}var d=y("underscore")._,f=y("events").Event,m=y("worker_manager").WorkerSupervisor;y("bespin:console");y("rangeutils:utils/range");var i=y("syntax_directory").syntaxDirectory;r.prototype={get:function(g){return this._syms["-"+g]},replaceLine:function(g,j){function q(C){return C.substring(1)}var t=this._lines,B=this._syms;g<t.length&&d(t[g]).isArray()&&d(t[g]).each(function(C){delete B["-"+C]});t[g]=d(j).keys().map(q);d(B).extend(j)}};l.prototype=
{_annotate:function(){if(this._invalidRow==null)throw new Error("syntax_manager.Context: attempt to annotate without any invalid row");if(!this._active)throw new Error("syntax_manager.Context: attempt to annotate while inactive");if(this._worker==null)this._createWorker();else{var g=this._syntaxManager.getTextLines(),j=this._invalidRow,q=j===0?this.getName()+":start":this._states[j],t=Math.min(g.length,j+100);g=g.slice(j,t);var B={start:{row:j,col:0},end:{row:t-1,col:d(g).last().length}};this._worker.send("annotate",
[q,g,B]).then(d(this._annotationFinished).bind(this,j,t))}},_annotationFinished:function(g,j,q){if(this._active){var t=this._syntaxManager;t.mergeAttrs(g,q.attrs);t.mergeSymbols(g,q.symbols);v(this._states,g,q.states);if(j>=this._getRowCount()){this._invalidRow=null;this._active=false}else{this._invalidRow=j;this._annotate()}}},_createWorker:function(){if(this._syntaxInfo==null)return false;var g=new m("syntax_worker#syntaxWorker");this._worker=g;g.started.add(this._workerStarted.bind(this));g.start();
return true},_getRowCount:function(){return this._syntaxManager.getTextLines().length},_workerStarted:function(){this._worker.send("loadSyntax",[this._syntaxInfo.name]);this._active&&this._annotate()},activateAndAnnotate:function(){this._active=true;this._annotate()},contextsAtPosition:function(){var g=this._syntaxInfo;if(g==null)return["plain"];return[g.name]},cut:function(g){var j=this._getRowCount();if(g<0||g>=j)throw new Error("Attempt to cut the context at an invalid row");if(!(this._invalidRow!=
null&&this._invalidRow<g)){this._invalidRow=g;this._active=false}},getName:function(){return this._syntaxInfo.name},kill:function(){var g=this._worker;if(g!=null){g.kill();this._worker=null}}};h.prototype={_getTextStorage:function(){return this.layoutManager.textStorage},_reset:function(){var g=this._context;if(g!=null){g.kill();this._context=null}g=this._syntax;g=g==="plain"?null:i.get(g);this._context=g=new l(g,this);g.activateAndAnnotate()},attrsChanged:null,syntaxChanged:null,contextsAtPosition:function(g){return this._context.contextsAtPosition(g)},
getAttrsForRows:function(g,j){return this._attrs.slice(g,j)},getSymbol:function(g){return this._symbols.get(g)},getSyntax:function(){return this._syntax},getTextLines:function(){return this._getTextStorage().lines},invalidateRow:function(g){var j=this._context;j.cut(g);j.activateAndAnnotate()},mergeAttrs:function(g,j){v(this._attrs,g,j,[]);this.attrsChanged(g,g+j.length)},mergeSymbols:function(g,j){var q=this._symbols;d(j).each(function(t,B){q.replaceLine(g+B,t)})},setSyntax:function(g){this._syntax=
i.hasSyntax(g)?g:"plain";this.syntaxChanged(g);this._reset()},setSyntaxFromFileExt:function(g){return this.setSyntax(i.syntaxForFileExt(g))}};s.SyntaxManager=h});bespin.tiki.register("::completion",{name:"completion",dependencies:{jquery:"0.0.0",ctags:"0.0.0",rangeutils:"0.0.0",canon:"0.0.0",underscore:"0.0.0"}});
bespin.tiki.module("completion:controller",function(y,s){function v(i){this._editorView=i;i.selectionChanged.add(this._selectionChanged.bind(this));i.willChangeBuffer.add(this._willChangeBuffer.bind(this));this._syntaxChanged=this._syntaxChanged.bind(this);this.tags=new l.Tags;this.ui=new d(i.element)}function r(i){return function(){return m.editor.completionController[i](m)}}var l=y("ctags"),h=y("rangeutils:utils/range"),d=y("completion:ui").CompletionUI,f=y("bespin:plugins").catalog,m=y("environment").env;
v.prototype={_buffer:null,_completionEngine:null,_completions:null,_stem:null,_hideCompletions:function(){this.ui.hide()},_selectionChanged:function(i){var g=this._completionEngine;if(!(g==null||!h.isZeroLength(i))){var j=this._buffer.layoutManager,q=j.syntaxManager,t=i.start;i=t.col;t=j.textStorage.lines[t.row];j=t.substring(0,i);i=t.substring(i);g=g.getCompletions(j,i,q);if(g==null)this._hideCompletions();else{q=g.tags;this._stem=g.stem;this._showCompletions(q)}}},_showCompletions:function(i){var g=
this._editorView,j=g.textView.getInsertionPointPosition();j=g.convertTextViewPoint(j);this.ui.show(i,j,g.layoutManager.fontDimension.lineHeight)},_syntaxChanged:function(i){i=f.getExtensionByKey("completion",i);if(i==null)this._completionEngine=null;else i.load().then(function(g){this._completionEngine=new g(this.tags)}.bind(this))},_willChangeBuffer:function(i){var g=this._buffer;g!=null&&g.layoutManager.syntaxManager.syntaxChanged.remove(this._syntaxChanged);i.layoutManager.syntaxManager.syntaxChanged.add(this._syntaxChanged);
this._buffer=i},cancel:function(){this.ui.hide()},complete:function(i){var g=this.ui,j=g.getCompletion().name;i.view.insertText(j.substring(this._stem.length));g.hide()},isCompleting:function(){return this.ui.visible},moveDown:function(){this.ui.move("down")},moveUp:function(){this.ui.move("up")},tags:null};s.CompletionController=v;s.completeCommand=r("complete");s.completeCancelCommand=r("cancel");s.completeDownCommand=r("moveDown");s.completeUpCommand=r("moveUp")});
bespin.tiki.module("completion:ui",function(y,s){function v(m){var i=l.uniqueId("bespin-completion-panel"),g=document.createElement("div");g.id=i;g.className="bespin-completion-panel";g.style.display="none";g.innerHTML='<div class="bespin-completion-pointer"></div><div class="bespin-completion-bubble-outer"><div class="bespin-completion-bubble-inner"><div class="bespin-completion-highlight"></div><ul></ul></div></div>';r(m).append(g);this.panel=r(g);this.parent=r(m)}var r=y("jquery").$,l=y("underscore")._,
h=l.template('<span class="bespin-completion-container"> &mdash; <%= container %></span>'),d=l.template('<div class="bespin-completion-second-row"><%= type %></div>'),f=l.template('<li><div class="bespin-completion-top-row"><span class="bespin-completion-kind bespin-completion-kind-<%= kind %>"><%= kind %></span><span class="bespin-completion-ident"><%= ident %></span><%= container %></div><%= second_row %></li>');v.prototype={_fromBottom:false,_index:0,_tags:null,_getHighlightDimensions:function(m){var i=
m.position(),g=m.outerHeight()-2;m=m.outerWidth()-2;return{left:i.left,top:i.top,height:g,width:m}},_listItemForIndex:function(m){return this.panel.find("li:eq("+m+")")},_populate:function(){var m=l(this._tags).map(function(i){var g=i["class"],j=i.module,q=i.namespace;g=g!=null?g:q!=null?q:"";if(j!=null)g=j+(g!=""?"#"+g:"");j=g==""?"":h({container:g});g=i.type;g=g==null?"":d({type:g});return f({kind:i.kind,ident:i.name,container:j,second_row:g})});this.panel.find("ul").html(m.join("\n"))},panel:null,
visible:false,getCompletion:function(){return this.visible?this._tags[this._index]:null},hide:function(){if(this.visible){this.panel.fadeOut(100);this.visible=false}},move:function(m){var i=this._index,g=this._listItemForIndex(i),j=m==="up"?g.prev():g.next();if(j.length!==0){this._index=i=m==="up"?i-1:i+1;i=r(g).find(".bespin-completion-top-row");var q=r(g).find(".bespin-completion-second-row");g=r(j).find(".bespin-completion-top-row");var t=r(j).find(".bespin-completion-second-row");q.hide();t.show();
var B=this.panel.find(".bespin-completion-highlight");B.stop(true,true);j=this._getHighlightDimensions(j);B.animate(j,100);t.hide();if(m==="down"){m=q.height();g.css("top",m);g.animate({top:0},100)}else{m=t.height();i.css("top",-m);i.animate({top:0},100)}t.fadeIn()}},show:function(m,i,g){this._tags=m=l(m).clone();this._populate();var j=this.visible,q=this.panel;q.stop(true,true);j||q.show();var t=this.parent.offset(),B=t.left,C=B+i.x,e=t.top+i.y;t=q.outerWidth();var K=q.outerHeight(),L=r(window).width(),
n=r(window).height();this._fromBottom=e=e+K+g>n;if(this._index>=m.length)this._index=m.length-1;if(e){e=q.find(".bespin-completion-pointer");e.removeClass("bespin-completion-pointer-up");e.addClass("bespin-completion-pointer-down");q.css({bottom:-i.y,top:""});this._tags.reverse();this._populate();if(!j)this._index=m.length-1}else{e=q.find(".bespin-completion-pointer");e.removeClass("bespin-completion-pointer-down");e.addClass("bespin-completion-pointer-up");q.css({top:i.y+g,bottom:""});if(!j)this._index=
0}if(!j){if(C+i.x+t>L){e.css({left:"",right:32});q.css("left",Math.min(L-t-B,i.x-t+43))}else{e.css({left:32,right:""});q.css("left",Math.max(B,i.x-43))}q.hide().animate({opacity:"show"},100)}m=q.find(".bespin-completion-highlight");m.stop(true,true);i=this._listItemForIndex(this._index);i.find(".bespin-completion-second-row").show();i=this._getHighlightDimensions(i);m.css(i);this.visible=true}};s.CompletionUI=v});bespin.tiki.module("completion:index",function(){});
bespin.tiki.register("::rangeutils",{name:"rangeutils",dependencies:{}});
bespin.tiki.module("rangeutils:utils/range",function(y,s){var v=y("bespin:util/util");s.addPositions=function(r,l){return{row:r.row+l.row,col:r.col+l.col}};s.cloneRange=function(r){var l=r.start;r=r.end;return{start:{row:l.row,col:l.col},end:{row:r.row,col:r.col}}};s.comparePositions=function(r,l){var h=r.row-l.row;return h===0?r.col-l.col:h};s.equal=function(r,l){return s.comparePositions(r.start,l.start)===0&&s.comparePositions(r.end,l.end)===0};s.extendRange=function(r,l){var h=r.end;return{start:r.start,
end:{row:h.row+l.row,col:h.col+l.col}}};s.intersectRangeSets=function(r,l){r=v.clone(r);l=v.clone(l);for(var h=[];r.length>0&&l.length>0;){var d=r.shift(),f=l.shift(),m=s.comparePositions(d.start,f.start),i=s.comparePositions(d.end,f.end);if(s.comparePositions(d.end,f.start)<0){h.push(d);l.unshift(f)}else if(s.comparePositions(f.end,d.start)<0){h.push(f);r.unshift(d)}else if(m<0){h.push({start:d.start,end:f.start});r.unshift({start:f.start,end:d.end});l.unshift(f)}else if(m===0)if(i<0)l.unshift({start:d.end,
end:f.end});else i>0&&r.unshift({start:f.end,end:d.end});else if(m>0){h.push({start:f.start,end:d.start});r.unshift(d);l.unshift({start:d.start,end:f.end})}}return h.concat(r,l)};s.isZeroLength=function(r){return r.start.row===r.end.row&&r.start.col===r.end.col};s.maxPosition=function(r,l){return s.comparePositions(r,l)>0?r:l};s.normalizeRange=function(r){return this.comparePositions(r.start,r.end)<0?r:{start:r.end,end:r.start}};s.rangeSetBoundaries=function(r){return{start:r[0].start,end:r[r.length-
1].end}};s.toString=function(r){var l=r.start;r=r.end;return"[ "+l.row+", "+l.col+" "+r.row+","+ +r.col+" ]"};s.unionRanges=function(r,l){return{start:r.start.row<l.start.row||r.start.row===l.start.row&&r.start.col<l.start.col?r.start:l.start,end:r.end.row>l.end.row||r.end.row===l.end.row&&r.end.col>l.end.col?r.end:l.end}};s.isPosition=function(r){return!v.none(r)&&!v.none(r.row)&&!v.none(r.col)};s.isRange=function(r){return!v.none(r)&&s.isPosition(r.start)&&s.isPosition(r.end)}});
bespin.tiki.module("rangeutils:index",function(){});bespin.tiki.register("::undomanager",{name:"undomanager",dependencies:{}});
bespin.tiki.module("undomanager:index",function(y,s){var v=y("bespin:util/util");y("environment");s.UndoManager=function(){};v.mixin(s.UndoManager.prototype,{_redoStack:[],_undoStack:[],_undoOrRedo:function(r,l,h){if(l.length===0)return false;l=l.pop();if(!l.target[r](l.context)){this._redoStack=[];this._undoStack=[];return false}h.push(l);return true},redo:function(){return this._undoOrRedo("redo",this._redoStack,this._undoStack)},registerUndo:function(r,l){this._redoStack=[];this._undoStack.push({target:r,
context:l})},undo:function(){return this._undoOrRedo("undo",this._undoStack,this._redoStack)}});s.global=new s.UndoManager;s.undoManagerCommand=function(r,l){s.global[l.commandExt.name]()}});bespin.tiki.register("::environment",{name:"environment",dependencies:{settings:"0.0.0"}});
bespin.tiki.module("environment:index",function(y,s){var v=y("bespin:util/util"),r=y("bespin:console").console,l=y("bespin:plugins").catalog,h=y("settings").settings;s.Environment=function(){this.commandLine=null;window.addEventListener("resize",this.dimensionsChanged.bind(this),false)};Object.defineProperties(s.Environment.prototype,{settings:{value:{set:function(d,f){if(v.none(d))throw new Error("setSetting(): key must be supplied");if(v.none(f))throw new Error("setSetting(): value must be supplied");
h.set(d,f)},get:function(d){if(v.none(d))throw new Error("getSetting(): key must be supplied");return h.get(d)}}},dimensionsChanged:{value:function(){l.publish(this,"dimensionsChanged")}},session:{get:function(){return l.getObject("session")}},view:{get:function(){if(!this.session)return null;return this.session.currentView}},editor:{get:function(){if(!this.session)return null;return this.session.currentView.editor}},contexts:{get:function(){if(!this.view)return[];var d=this.view.editor.layoutManager.syntaxManager,
f=this.view.getSelectedRange().start;return d.contextsAtPosition(f)}},buffer:{get:function(){if(this.session)return this.view.editor.buffer;else r.error("command attempted to get buffer but there's no session")}},model:{get:function(){if(this.buffer)return this.view.editor.layoutManager.textStorage;else r.error("Session has no current buffer")}},file:{get:function(){if(this.buffer)return this.buffer.file;else r.error("Session has no current buffer")}},files:{get:function(){return l.getObject("files")}}});
s.env=new s.Environment});bespin.tiki.register("::ctags",{name:"ctags",dependencies:{traits:"0.0.0",underscore:"0.0.0"}});
bespin.tiki.module("ctags:index",function(y,s){var v=y("underscore")._,r=y("./reader").TagReader;y=y("traits").Trait;s.Tags=function(){this.tags=[]};s.Tags.prototype=Object.create(Object.prototype,y.compose(y({_search:function(l,h){var d={name:l};l=this.tags;var f=v(l).sortedIndex(d,function(m){return m.name});for(f=d=f;d>=0&&d<l.length&&h(l[d]);)d--;for(;f>=0&&f<l.length&&h(l[f]);)f++;return l.slice(d+1,f)},add:function(l){var h=this.tags;Array.prototype.push.apply(h,l);h.sort(function(d,f){d=d.name;
f=f.name;if(d<f)return-1;if(d===f)return 0;return 1})},get:function(l){return this._search(l,function(h){return h.name===l})},scan:function(l,h,d){if(d===null||d===undefined)d={};var f=l.split("\n");l=parse(l,h,1);h=new Interpreter(l,h,f,d);h.interpret();this.add(h.tags)},stem:function(l){var h=l.length;return this._search(l,function(d){return d.name.substring(0,h)===l})}}),r))});
bespin.tiki.module("ctags:reader",function(y,s){var v=y("underscore")._;y=y("traits").Trait;s.TagReader=y({readLines:function(r){var l=[];v(r).each(function(h){h=h.split("\t");if(!(h.length<3)){var d=h[0];if(!/^!_TAG_/.test(d)){d={name:d,tagfile:h[1],addr:h[2]};var f;if(h.length>3&&h[3].indexOf(":")===-1){d.kind=h[3];f=4}else f=3;var m={};v(h.slice(f)).each(function(i){i=/^([^:]+):(.*)/.exec(i);m[i[1]]=i[2]});d.fields=m;l.push(d)}}});this.add(l)},readString:function(r){this.readLines(r.split("\n"))}})});
bespin.tiki.register("::theme_manager",{name:"theme_manager",dependencies:{theme_manager_base:"0.0.0",settings:"0.0.0",events:"0.0.0",less:"0.0.0"}});
bespin.tiki.module("theme_manager:index",function(y,s){y("bespin:promise");var v=y("bespin:plugins").catalog;y("events");var r=y("themestyles"),l=y("settings").settings,h=null,d=null;s.themestyles=r;s.themeSettingChanged=function(f,m,i){var g=v.getExtensionByKey("theme",i);if(i==="standard"||!i||!g){g=null;if(d!==null)g=v.getExtensionByKey("theme",d)}if(g)g.load().then(function(j){h&&r.unregisterThemeStyles(h);r.currentThemeVariables=j();h=g;r.parseGlobalVariables();r.reparse();g.url&&r.registerThemeStyles(g);
v.publish(s,"themeChange")});else if(h){r.unregisterThemeStyles(h);h=null;r.currentThemeVariables=null;r.parseGlobalVariables();r.reparse();v.publish(this,"themeChange")}};v.registerExtension("settingChange",{match:"theme",pointer:s.themeSettingChanged.bind(s)});s.setStandardTheme=function(f){d=f;f!==l.get("theme")&&s.themeSettingChanged(this)};s.setBasePlugin=function(f){r.basePluginName=f};s.startParsing=function(){r.preventParsing=false;return r.reparse()};s.registerTheme=function(f){var m=l.get("theme");
f.name===m&&s.themeSettingChanged(this,"theme",f.name)};s.unregisterTheme=function(f){f.name===l.get("theme")&&s.themeSettingChanged(this)};s.appLaunched=function(){v.publish(s,"themeChange")}});
bespin.tiki.module("theme_manager:themestyles",function(y,s){var v=y("bespin:util/util"),r=y("bespin:plugins").catalog,l=y("bespin:console").console,h=y("bespin:promise").Promise,d=y("bespin:promise").group,f=y("bespin:proxy"),m=new (y("less").Parser)({optimization:3}),i=1;s.currentThemeVariables=null;s.basePluginName=null;s.preventParsing=true;var g="";s.globalThemeVariables={};var j={},q={},t=function(w){var D={},J=[],Q=function(Z,T){J.push(Z);if(typeof T!="object")D[J.join("_")]=T;else for(prop in T)Q(prop,
T[prop]);J.pop()};Q("global",w);return D},B={},C={font:"arial, lucida, helvetica, sans-serif",font_size:"14px",line_height:"1.8em",color:"#DAD4BA",text_shadow:"1px 1px rgba(0, 0, 0, 0.4)",error_color:"#F99",header_color:"white",link_color:"#ACF",control:{color:"#E1B41F",border:"1px solid rgba(0, 0, 0, 0.2)",border_radius:"0.25em",background:"rgba(0, 0, 0, 0.2)",active:{color:"#FF9600",border:"1px solid #E1B41F",inset_color:"#ff9600",background:"rgba(0, 0, 0, 0.2)"}},pane:{h1:{font:"'MuseoSans', Helvetica",
font_size:"2.8em",color:"white"},color:"#DAD4BA",text_shadow:"1px 1px rgba(0, 0, 0, 0.4)",link_color:"white",background:"#45443C",border_radius:".5em"},form:{color:"white",text_shadow:"1px 1px rgba(0, 0, 0, 0.4)",font:"'Lucida Sans','Lucida Grande',Verdana,Arial,sans-serif",font_size:"@global_font_size",line_height:"@global_line_height"},button:{color:"white",background:"#3E6CB9"},container:{background:"#1E1916",border:"1px solid black"},selectable:{color:"white",border:"0px solid transparent",background:"transparent",
active:{color:"black",border:"0px solid transparent",background:"#FF8E00"},hover:{color:"black",border:"0px solid transparent",background:"#FF8E00"}},hint:{color:"#AAA",active:{color:"black"},hover:{color:"black"}},accelerator:{color:"#996633",active:{color:"black"},hover:{color:"black"}},menu:{border_color:"black",inset_color_right:"#1E1916",inset_color_top_left:"#3E3936",background:"transparent"}};C=t(C);s.getPluginThemeVariables=function(w){var D=r.plugins[w];if(!D)return null;var J={};if(s.currentThemeVariables&&
s.currentThemeVariables[w])J=s.currentThemeVariables[w];D.provides.forEach(function(Q){if(Q.ep==="themevariable"){var Z=Q.name;J[Z]=J[Z]||Q.defaultValue}});return J};s.parseGlobalVariables=function(){var w={},D="",J=s.currentThemeVariables;v.mixin(w,C);J&&J.global&&v.mixin(w,t(J.global));s.globalThemeVariables=w;for(prop in w)D+="@"+prop+":"+w[prop]+";";g=D};s.parseGlobalVariables();var e=function(w,D,J){if(j[D])styleElem=document.getElementById("_bespin_theme_style_"+j[D]);else{styleElem=document.createElement("style");
styleElem.setAttribute("id","_bespin_theme_style_"+i);j[D]=i;i++;document.body.appendChild(styleElem)}m.parse(g+J+q[D],function(Q,Z){if(Q){Q="Error less parsing "+D+" "+Q.message;l.error(Q);w.reject(Q)}else{try{var T=Z.toCSS()}catch(ca){Q="Error less parsing "+D+" "+ca;l.error(Q);w.reject(Q);return}if(styleElem&&styleElem.firstChild)styleElem.firstChild.textContent=T;else{Q=document.createTextNode(T);styleElem.appendChild(Q)}w.resolve()}})},K={};s.parsePlugin=function(w){if(s.preventParsing)return(new h).resolve();
var D=r.plugins[w];if(!D)throw"reparsePlugin: plugin "+w+" is not defined!";if(!K[w]){K[w]=new h;setTimeout(function(){var J=s.getPluginThemeVariables(w),Q="";for(prop in J)Q+="@"+prop+":"+J[prop]+";";J=new h;J.then(function(Z){K[this.name].resolve(Z);K[this.name]=null}.bind(this),function(){K[this.name].reject(data);K[this.name]=null}.bind(this));e(J,w,Q)}.bind(D),0)}return K[w]};var L=function(w,D,J,Q){J=J.replace(/url\(['"]*([^'")]*)(['"]*)\)/g,"url("+w+"$1)");q[D]+=J;Q&&Q.resolve()},n=null;s.registerThemeStyles=
function(w){var D=w.getPluginName(),J=r.getResourceURL(D);if(!(w.url instanceof Array))w.url=[w.url];q[D]="";var Q=[],Z=s.preventParsing;w.url.forEach(function(T){if(B[D]&&B[D][T])L(J,D,B[D][T]);else{var ca=new h;Q.push(ca);var ha=J+T+"?"+(new Date).getTime();f.xhr("GET",ha,true,function(ga){ga.overrideMimeType("text/plain")}).then(function(ga){L(J,D,ga,ca)},function(){l.error("registerLessFile: Could not load "+J+T);ca.resolve()})}});if(Q.length===0)s.parsePlugin(D);else{Z||d(Q).then(function(){s.parsePlugin(D)});
if(n!==null)Q=Q.concat(n);n=d(Q)}};s.reparse=function(){var w=new h;if(s.preventParsing)return w.resolve();n?n.then(function(){var D=[],J=s.basePluginName;J!==null&&q[J]&&D.push(s.parsePlugin(J));for(var Q in q)Q!==J&&D.push(s.parsePlugin(Q));d(D).then(w.resolve.bind(w),w.reject.bind(w))},function(D){w.reject(D)}):w.resolve();return w};s.unregisterThemeStyles=function(w){w=w.getPluginName();if(j[w]){var D=document.getElementById("_bespin_theme_style_"+j[w]);D.parentNode.removeChild(D);delete j[w];
delete q[w]}}});bespin.tiki.register("::types",{name:"types",dependencies:{}});
bespin.tiki.module("types:basic",function(y,s){var v=y("bespin:plugins").catalog,r=y("bespin:console").console,l=y("bespin:promise").Promise;s.text={isValid:function(h){return typeof h=="string"},toString:function(h){return h},fromString:function(h){return h}};s.number={isValid:function(h){if(isNaN(h))return false;if(h===null)return false;if(h===undefined)return false;if(h===Infinity)return false;return typeof h=="number"},toString:function(h){if(!h)return null;return""+h},fromString:function(h){if(!h)return null;
var d=parseInt(h,10);if(isNaN(d))throw new Error("Can't convert \""+h+'" to a number.');return d}};s.bool={isValid:function(h){return typeof h=="boolean"},toString:function(h){return""+h},fromString:function(h){if(h===null)return null;if(!h.toLowerCase)return!!h;var d=h.toLowerCase();if(d=="true")return true;else if(d=="false")return false;return!!h}};s.object={isValid:function(h){return typeof h=="object"},toString:function(h){return JSON.stringify(h)},fromString:function(h){return JSON.parse(h)}};
s.selection={isValid:function(h,d){if(typeof h!="string")return false;if(!d.data){r.error("Missing data on selection type extension. Skipping");return true}var f=false;d.data.forEach(function(m){if(h==m)f=true});return f},toString:function(h){return h},fromString:function(h){return h},resolveTypeSpec:function(h,d){var f=new l;if(d.data){h.data=d.data;f.resolve()}else if(d.pointer)v.loadObjectForPropertyPath(d.pointer).then(function(m){m=m(d);if(typeof m.then==="function")m.then(function(i){h.data=
i;f.resolve()});else{h.data=m;f.resolve()}},function(m){f.reject(m)});else{r.warn("Missing data/pointer for selection",d);f.resolve()}return f}}});
bespin.tiki.module("types:types",function(y,s){function v(d){var f=new h,m=l.getExtensionByKey("type",d.name);m?f.resolve({ext:m,typeSpec:d}):f.reject(new Error("Unknown type: "+d.name));return f}function r(d){if(typeof d==="string")return v({name:d});if(typeof d==="object")if(d.name==="deferred"){var f=new h;s.undeferTypeSpec(d).then(function(m){r(m).then(function(i){f.resolve(i)},function(i){f.reject(i)})});return f}else return v(d);throw new Error("Unknown typeSpec type: "+typeof d);}var l=y("bespin:plugins").catalog;
y("bespin:console");var h=y("bespin:promise").Promise;s.getSimpleName=function(d){if(!d)throw new Error("null|undefined is not a valid typeSpec");if(typeof d=="string")return d;if(typeof d=="object"){if(!d.name)throw new Error("Missing name member to typeSpec");return d.name}throw new Error("Not a typeSpec: "+d);};s.equals=function(d,f){return s.getSimpleName(d)==s.getSimpleName(f)};s.undeferTypeSpec=function(d){var f=new h;if(!d.pointer){f.reject(new Error("Missing deferred pointer"));return f}l.loadObjectForPropertyPath(d.pointer).then(function(m){m=
m(d);typeof m.then==="function"?m.then(function(i){f.resolve(i)},function(i){f.reject(i)}):f.resolve(m)},function(m){f.reject(m)});return f};s.resolveType=function(d){var f=new h;r(d).then(function(m){m.ext.load(function(i){typeof i.resolveTypeSpec==="function"?i.resolveTypeSpec(m.ext,m.typeSpec).then(function(){f.resolve({type:i,ext:m.ext})},function(g){f.reject(g)}):f.resolve({type:i,ext:m.ext})})},function(m){f.reject(m)});return f};s.fromString=function(d,f){var m=new h;s.resolveType(f).then(function(i){m.resolve(i.type.fromString(d,
i.ext))});return m};s.toString=function(d,f){var m=new h;s.resolveType(f).then(function(i){m.resolve(i.type.toString(d,i.ext))});return m};s.isValid=function(d,f){var m=new h;s.resolveType(f).then(function(i){m.resolve(i.type.isValid(d,i.ext))});return m}});bespin.tiki.module("types:index",function(){});bespin.tiki.register("::jquery",{name:"jquery",dependencies:{}});
bespin.tiki.module("jquery:index",function(y,s){function v(){if(!e.isReady){try{n.documentElement.doScroll("left")}catch(a){setTimeout(v,1);return}e.ready()}}function r(a,b){b.src?e.ajax({url:b.src,async:false,dataType:"script"}):e.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function l(a,b,k,p,o,z){var A=a.length;if(typeof b==="object"){for(var I in b)l(a,I,b[I],p,o,k);return a}if(k!==undefined){p=!z&&p&&e.isFunction(k);for(I=0;I<A;I++)o(a[I],b,p?k.call(a[I],
I,o(a[I],b)):k,z);return a}return A?o(a[0],b):undefined}function h(){return(new Date).getTime()}function d(){return false}function f(){return true}function m(a,b,k){k[0].type=a;return e.event.handle.apply(b,k)}function i(a){var b,k=[],p=[],o=arguments,z,A,I,E,H,R;A=e.data(this,"events");if(!(a.liveFired===this||!A||!A.live||a.button&&a.type==="click")){a.liveFired=this;var W=A.live.slice(0);for(E=0;E<W.length;E++){A=W[E];A.origType.replace(sa,"")===a.type?p.push(A.selector):W.splice(E--,1)}z=e(a.target).closest(p,
a.currentTarget);H=0;for(R=z.length;H<R;H++)for(E=0;E<W.length;E++){A=W[E];if(z[H].selector===A.selector){I=z[H].elem;p=null;if(A.preType==="mouseenter"||A.preType==="mouseleave")p=e(a.relatedTarget).closest(A.selector)[0];if(!p||p!==I)k.push({elem:I,handleObj:A})}}H=0;for(R=k.length;H<R;H++){z=k[H];a.currentTarget=z.elem;a.data=z.handleObj.data;a.handleObj=z.handleObj;if(z.handleObj.origHandler.apply(z.elem,o)===false){b=false;break}}return b}}function g(a,b){return"live."+(a&&a!=="*"?a+".":"")+
b.replace(/\./g,"`").replace(/ /g,"&")}function j(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function q(a,b){var k=0;b.each(function(){if(this.nodeName===(a[k]&&a[k].nodeName)){var p=e.data(a[k++]),o=e.data(this,p);if(p=p&&p.events){delete o.handle;o.events={};for(var z in p)for(var A in p[z])e.event.add(this,z,p[z][A],p[z][A].data)}}})}function t(a,b,k){var p,o,z;b=b&&b[0]?b[0].ownerDocument||b[0]:n;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===n&&!Ha.test(a[0])&&(e.support.checkClone||
!Ia.test(a[0]))){o=true;if(z=e.fragments[a[0]])if(z!==1)p=z}if(!p){p=b.createDocumentFragment();e.clean(a,b,p,k)}if(o)e.fragments[a[0]]=z?p:1;return{fragment:p,cacheable:o}}function B(a,b){var k={};e.each(Ja.concat.apply([],Ja.slice(0,b)),function(){k[this]=a});return k}function C(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var e=function(a,b){return new e.fn.init(a,b)},K=window.jQuery,L=window.$,n=window.document,w,D=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
J=/^.[^:#\[\.,]*$/,Q=/\S/,Z=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,T=/^<(\w+)\s*\/?>(?:<\/\1>)?$/;y=navigator.userAgent;var ca=false,ha=[],ga,la=Object.prototype.toString,ma=Object.prototype.hasOwnProperty,na=Array.prototype.push,O=Array.prototype.slice,P=Array.prototype.indexOf;e.fn=e.prototype={init:function(a,b){var k,p;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=n;this[0]=n.body;this.selector="body";this.length=1;return this}if(typeof a===
"string")if((k=D.exec(a))&&(k[1]||!b))if(k[1]){p=b?b.ownerDocument||b:n;if(a=T.exec(a))if(e.isPlainObject(b)){a=[n.createElement(a[1])];e.fn.attr.call(a,b,true)}else a=[p.createElement(a[1])];else{a=t([k[1]],[p]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return e.merge(this,a)}else{if(b=n.getElementById(k[2])){if(b.id!==k[2])return w.find(a);this.length=1;this[0]=b}this.context=n;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=n;a=n.getElementsByTagName(a);
return e.merge(this,a)}else return!b||b.jquery?(b||w).find(a):e(b).find(a);else if(e.isFunction(a))return w.ready(a);if(a.selector!==undefined){this.selector=a.selector;this.context=a.context}return e.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return O.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,k){var p=e();e.isArray(a)?na.apply(p,a):e.merge(p,a);p.prevObject=this;
p.context=this.context;if(b==="find")p.selector=this.selector+(this.selector?" ":"")+k;else if(b)p.selector=this.selector+"."+b+"("+k+")";return p},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady();if(e.isReady)a.call(n,e);else ha&&ha.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(O.apply(this,arguments),"slice",O.call(arguments).join(","))},
map:function(a){return this.pushStack(e.map(this,function(b,k){return a.call(b,k,b)}))},end:function(){return this.prevObject||e(null)},push:na,sort:[].sort,splice:[].splice};e.fn.init.prototype=e.fn;e.extend=e.fn.extend=function(){var a=arguments[0]||{},b=1,k=arguments.length,p=false,o,z,A,I;if(typeof a==="boolean"){p=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!e.isFunction(a))a={};if(k===b){a=this;--b}for(;b<k;b++)if((o=arguments[b])!=null)for(z in o){A=a[z];I=o[z];if(a!==I)if(p&&I&&(e.isPlainObject(I)||
e.isArray(I))){A=A&&(e.isPlainObject(A)||e.isArray(A))?A:e.isArray(I)?[]:{};a[z]=e.extend(p,A,I)}else if(I!==undefined)a[z]=I}return a};e.extend({noConflict:function(a){window.$=L;if(a)window.jQuery=K;return e},isReady:false,ready:function(){if(!e.isReady){if(!n.body)return setTimeout(e.ready,13);e.isReady=true;if(ha){for(var a,b=0;a=ha[b++];)a.call(n,e);ha=null}e.fn.triggerHandler&&e(n).triggerHandler("ready")}},bindReady:function(){if(!ca){ca=true;if(n.readyState==="complete")return e.ready();if(n.addEventListener){n.addEventListener("DOMContentLoaded",
ga,false);window.addEventListener("load",e.ready,false)}else if(n.attachEvent){n.attachEvent("onreadystatechange",ga);window.attachEvent("onload",e.ready);var a=false;try{a=window.frameElement==null}catch(b){}n.documentElement.doScroll&&a&&v()}}},isFunction:function(a){return la.call(a)==="[object Function]"},isArray:function(a){return la.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||la.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!ma.call(a,
"constructor")&&!ma.call(a.constructor.prototype,"isPrototypeOf"))return false;var b;for(b in a);return b===undefined||ma.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=e.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return window.JSON&&
window.JSON.parse?window.JSON.parse(a):(new Function("return "+a))();else e.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Q.test(a)){var b=n.getElementsByTagName("head")[0]||n.documentElement,k=n.createElement("script");k.type="text/javascript";if(e.support.scriptEval)k.appendChild(n.createTextNode(a));else k.text=a;b.insertBefore(k,b.firstChild);b.removeChild(k)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,k){var p,
o=0,z=a.length,A=z===undefined||e.isFunction(a);if(k)if(A)for(p in a){if(b.apply(a[p],k)===false)break}else for(;o<z;){if(b.apply(a[o++],k)===false)break}else if(A)for(p in a){if(b.call(a[p],p,a[p])===false)break}else for(k=a[0];o<z&&b.call(k,o,k)!==false;k=a[++o]);return a},trim:function(a){return(a||"").replace(Z,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||e.isFunction(a)||typeof a!=="function"&&a.setInterval?na.call(b,a):e.merge(b,a);return b},inArray:function(a,
b){if(b.indexOf)return b.indexOf(a);for(var k=0,p=b.length;k<p;k++)if(b[k]===a)return k;return-1},merge:function(a,b){var k=a.length,p=0;if(typeof b.length==="number")for(var o=b.length;p<o;p++)a[k++]=b[p];else for(;b[p]!==undefined;)a[k++]=b[p++];a.length=k;return a},grep:function(a,b,k){for(var p=[],o=0,z=a.length;o<z;o++)!k!==!b(a[o],o)&&p.push(a[o]);return p},map:function(a,b,k){for(var p=[],o,z=0,A=a.length;z<A;z++){o=b(a[z],z,k);if(o!=null)p[p.length]=o}return p.concat.apply([],p)},guid:1,proxy:function(a,
b,k){if(arguments.length===2)if(typeof b==="string"){k=a;a=k[b];b=undefined}else if(b&&!e.isFunction(b)){k=b;b=undefined}if(!b&&a)b=function(){return a.apply(k||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||e.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});
y=e.uaMatch(y);if(y.browser){e.browser[y.browser]=true;e.browser.version=y.version}if(e.browser.webkit)e.browser.safari=true;if(P)e.inArray=function(a,b){return P.call(b,a)};w=e(n);if(n.addEventListener)ga=function(){n.removeEventListener("DOMContentLoaded",ga,false);e.ready()};else if(n.attachEvent)ga=function(){if(n.readyState==="complete"){n.detachEvent("onreadystatechange",ga);e.ready()}};(function(){e.support={};var a=n.documentElement,b=n.createElement("script"),k=n.createElement("div"),p="script"+
h();k.style.display="none";k.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var o=k.getElementsByTagName("*"),z=k.getElementsByTagName("a")[0];if(!(!o||!o.length||!z)){e.support={leadingWhitespace:k.firstChild.nodeType===3,tbody:!k.getElementsByTagName("tbody").length,htmlSerialize:!!k.getElementsByTagName("link").length,style:/red/.test(z.getAttribute("style")),hrefNormalized:z.getAttribute("href")==="/a",opacity:/^0.55$/.test(z.style.opacity),
cssFloat:!!z.style.cssFloat,checkOn:k.getElementsByTagName("input")[0].value==="on",optSelected:n.createElement("select").appendChild(n.createElement("option")).selected,parentNode:k.removeChild(k.appendChild(n.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(n.createTextNode("window."+p+"=1;"))}catch(A){}a.insertBefore(b,a.firstChild);if(window[p]){e.support.scriptEval=true;delete window[p]}try{delete b.test}catch(I){e.support.deleteExpando=
false}a.removeChild(b);if(k.attachEvent&&k.fireEvent){k.attachEvent("onclick",function E(){e.support.noCloneEvent=false;k.detachEvent("onclick",E)});k.cloneNode(true).fireEvent("onclick")}k=n.createElement("div");k.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=n.createDocumentFragment();a.appendChild(k.firstChild);e.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;e(function(){var E=n.createElement("div");E.style.width=E.style.paddingLeft="1px";n.body.appendChild(E);
e.boxModel=e.support.boxModel=E.offsetWidth===2;n.body.removeChild(E).style.display="none"});a=function(E){var H=n.createElement("div");E="on"+E;var R=E in H;if(!R){H.setAttribute(E,"return;");R=typeof H[E]==="function"}return R};e.support.submitBubbles=a("submit");e.support.changeBubbles=a("change");a=b=k=o=z=null}})();e.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",
frameborder:"frameBorder"};var S="jQuery"+h(),U=0,aa={};e.extend({cache:{},expando:S,noData:{embed:true,object:true,applet:true},data:function(a,b,k){if(!(a.nodeName&&e.noData[a.nodeName.toLowerCase()])){a=a==window?aa:a;var p=a[S],o=e.cache;if(!p&&typeof b==="string"&&k===undefined)return null;p||(p=++U);if(typeof b==="object"){a[S]=p;o[p]=e.extend(true,{},b)}else if(!o[p]){a[S]=p;o[p]={}}a=o[p];if(k!==undefined)a[b]=k;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&
e.noData[a.nodeName.toLowerCase()])){a=a==window?aa:a;var k=a[S],p=e.cache,o=p[k];if(b){if(o){delete o[b];e.isEmptyObject(o)&&e.removeData(a)}}else{if(e.support.deleteExpando)delete a[e.expando];else a.removeAttribute&&a.removeAttribute(e.expando);delete p[k]}}}});e.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return e.data(this[0]);else if(typeof a==="object")return this.each(function(){e.data(this,a)});var k=a.split(".");k[1]=k[1]?"."+k[1]:"";if(b===undefined){var p=this.triggerHandler("getData"+
k[1]+"!",[k[0]]);if(p===undefined&&this.length)p=e.data(this[0],a);return p===undefined&&k[1]?this.data(k[0]):p}else return this.trigger("setData"+k[1]+"!",[k[0],b]).each(function(){e.data(this,a,b)})},removeData:function(a){return this.each(function(){e.removeData(this,a)})}});e.extend({queue:function(a,b,k){if(a){b=(b||"fx")+"queue";var p=e.data(a,b);if(!k)return p||[];if(!p||e.isArray(k))p=e.data(a,b,e.makeArray(k));else p.push(k);return p}},dequeue:function(a,b){b=b||"fx";var k=e.queue(a,b),p=
k.shift();if(p==="inprogress")p=k.shift();if(p){b==="fx"&&k.unshift("inprogress");p.call(a,function(){e.dequeue(a,b)})}}});e.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===undefined)return e.queue(this[0],a);return this.each(function(){var k=e.queue(this,a,b);a==="fx"&&k[0]!=="inprogress"&&e.dequeue(this,a)})},dequeue:function(a){return this.each(function(){e.dequeue(this,a)})},delay:function(a,b){a=e.fx?e.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var k=
this;setTimeout(function(){e.dequeue(k,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var fa=/[\n\t]/g,xa=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,cb=/^(a|area)$/i,Ka=/radio|checkbox/;e.fn.extend({attr:function(a,b){return l(this,a,b,true,e.attr)},removeAttr:function(a){return this.each(function(){e.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(e.isFunction(a))return this.each(function(H){var R=
e(this);R.addClass(a.call(this,H,R.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(xa),k=0,p=this.length;k<p;k++){var o=this[k];if(o.nodeType===1)if(o.className){for(var z=" "+o.className+" ",A=o.className,I=0,E=b.length;I<E;I++)if(z.indexOf(" "+b[I]+" ")<0)A+=" "+b[I];o.className=e.trim(A)}else o.className=a}return this},removeClass:function(a){if(e.isFunction(a))return this.each(function(E){var H=e(this);H.removeClass(a.call(this,E,H.attr("class")))});if(a&&typeof a==="string"||
a===undefined)for(var b=(a||"").split(xa),k=0,p=this.length;k<p;k++){var o=this[k];if(o.nodeType===1&&o.className)if(a){for(var z=(" "+o.className+" ").replace(fa," "),A=0,I=b.length;A<I;A++)z=z.replace(" "+b[A]+" "," ");o.className=e.trim(z)}else o.className=""}return this},toggleClass:function(a,b){var k=typeof a,p=typeof b==="boolean";if(e.isFunction(a))return this.each(function(o){var z=e(this);z.toggleClass(a.call(this,o,z.attr("class"),b),b)});return this.each(function(){if(k==="string")for(var o,
z=0,A=e(this),I=b,E=a.split(xa);o=E[z++];){I=p?I:!A.hasClass(o);A[I?"addClass":"removeClass"](o)}else if(k==="undefined"||k==="boolean"){this.className&&e.data(this,"__className__",this.className);this.className=this.className||a===false?"":e.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,k=this.length;b<k;b++)if((" "+this[b].className+" ").replace(fa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===undefined){var b=this[0];if(b){if(e.nodeName(b,
"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(e.nodeName(b,"select")){var k=b.selectedIndex,p=[],o=b.options;b=b.type==="select-one";if(k<0)return null;var z=b?k:0;for(k=b?k+1:o.length;z<k;z++){var A=o[z];if(A.selected){a=e(A).val();if(b)return a;p.push(a)}}return p}if(Ka.test(b.type)&&!e.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}}else{var I=e.isFunction(a);return this.each(function(E){var H=e(this),R=a;if(this.nodeType===
1){if(I)R=a.call(this,E,H.val());if(typeof R==="number")R+="";if(e.isArray(R)&&Ka.test(this.type))this.checked=e.inArray(H.val(),R)>=0;else if(e.nodeName(this,"select")){var W=e.makeArray(R);e("option",this).each(function(){this.selected=e.inArray(e(this).val(),W)>=0});if(!W.length)this.selectedIndex=-1}else this.value=R}})}}});e.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,k,p){if(!(!a||a.nodeType===3||a.nodeType===8)){if(p&&
b in e.attrFn)return e(a)[b](k);p=a.nodeType!==1||!e.isXMLDoc(a);var o=k!==undefined;b=p&&e.props[b]||b;if(a.nodeType===1){var z=$a.test(b);if(b in a&&p&&!z){if(o){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&e.error("type property can't be changed");a[b]=k}if(e.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:undefined;return a[b]}if(!e.support.style&&
p&&b==="style"){if(o)a.style.cssText=""+k;return a.style.cssText}o&&a.setAttribute(b,""+k);a=!e.support.hrefNormalized&&p&&z?a.getAttribute(b,2):a.getAttribute(b);return a===null?undefined:a}return e.style(a,b,k)}}});var sa=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};e.event={add:function(a,b,k,p){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==window&&!a.frameElement)a=window;var o,z;if(k.handler){o=k;k=o.handler}if(!k.guid)k.guid=e.guid++;if(z=
e.data(a)){var A=z.events=z.events||{},I=z.handle;if(!I)z.handle=I=function(){return typeof e!=="undefined"&&!e.event.triggered?e.event.handle.apply(I.elem,arguments):undefined};I.elem=a;b=b.split(" ");for(var E,H=0,R;E=b[H++];){z=o?e.extend({},o):{handler:k,data:p};if(E.indexOf(".")>-1){R=E.split(".");E=R.shift();z.namespace=R.slice(0).sort().join(".")}else{R=[];z.namespace=""}z.type=E;z.guid=k.guid;var W=A[E],ba=e.event.special[E]||{};if(!W){W=A[E]=[];if(!ba.setup||ba.setup.call(a,p,R,I)===false)if(a.addEventListener)a.addEventListener(E,
I,false);else a.attachEvent&&a.attachEvent("on"+E,I)}if(ba.add){ba.add.call(a,z);if(!z.handler.guid)z.handler.guid=k.guid}W.push(z);e.event.global[E]=true}a=null}}},global:{},remove:function(a,b,k,p){if(!(a.nodeType===3||a.nodeType===8)){var o,z=0,A,I,E,H,R,W,ba=e.data(a),ea=ba&&ba.events;if(ba&&ea){if(b&&b.type){k=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(o in ea)e.event.remove(a,o+b)}else{for(b=b.split(" ");o=b[z++];){H=o;A=o.indexOf(".")<0;I=[];if(!A){I=o.split(".");
o=I.shift();E=new RegExp("(^|\\.)"+e.map(I.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(R=ea[o])if(k){H=e.event.special[o]||{};for(da=p||0;da<R.length;da++){W=R[da];if(k.guid===W.guid){if(A||E.test(W.namespace)){p==null&&R.splice(da--,1);H.remove&&H.remove.call(a,W)}if(p!=null)break}}if(R.length===0||p!=null&&R.length===1){if(!H.teardown||H.teardown.call(a,I)===false)La(a,o,ba.handle);delete ea[o]}}else for(var da=0;da<R.length;da++){W=R[da];if(A||E.test(W.namespace)){e.event.remove(a,
H,W.handler,da);R.splice(da--,1)}}}if(e.isEmptyObject(ea)){if(b=ba.handle)b.elem=null;delete ba.events;delete ba.handle;e.isEmptyObject(ba)&&e.removeData(a)}}}}},trigger:function(a,b,k,p){var o=a.type||a;if(!p){a=typeof a==="object"?a[S]?a:e.extend(e.Event(o),a):e.Event(o);if(o.indexOf("!")>=0){a.type=o=o.slice(0,-1);a.exclusive=true}if(!k){a.stopPropagation();e.event.global[o]&&e.each(e.cache,function(){this.events&&this.events[o]&&e.event.trigger(a,b,this.handle.elem)})}if(!k||k.nodeType===3||k.nodeType===
8)return;a.result=undefined;a.target=k;b=e.makeArray(b);b.unshift(a)}a.currentTarget=k;(p=e.data(k,"handle"))&&p.apply(k,b);p=k.parentNode||k.ownerDocument;try{if(!(k&&k.nodeName&&e.noData[k.nodeName.toLowerCase()]))if(k["on"+o]&&k["on"+o].apply(k,b)===false)a.result=false}catch(z){}if(!a.isPropagationStopped()&&p)e.event.trigger(a,b,p,true);else if(!a.isDefaultPrevented()){p=a.target;var A,I=e.nodeName(p,"a")&&o==="click",E=e.event.special[o]||{};if((!E._default||E._default.call(k,a)===false)&&!I&&
!(p&&p.nodeName&&e.noData[p.nodeName.toLowerCase()])){try{if(p[o]){if(A=p["on"+o])p["on"+o]=null;e.event.triggered=true;p[o]()}}catch(H){}if(A)p["on"+o]=A;e.event.triggered=false}}},handle:function(a){var b,k,p,o;a=arguments[0]=e.event.fix(a||window.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;if(!b){k=a.type.split(".");a.type=k.shift();p=new RegExp("(^|\\.)"+k.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}o=e.data(this,"events");k=o[a.type];if(o&&k){k=k.slice(0);o=0;for(var z=
k.length;o<z;o++){var A=k[o];if(b||p.test(A.namespace)){a.handler=A.handler;a.data=A.data;a.handleObj=A;A=A.handler.apply(this,arguments);if(A!==undefined){a.result=A;if(A===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[S])return a;var b=a;a=e.Event(b);for(var k=this.props.length,p;k;){p=this.props[--k];a[p]=b[p]}if(!a.target)a.target=a.srcElement||n;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=n.documentElement;k=n.body;a.pageX=a.clientX+(b&&b.scrollLeft||k&&k.scrollLeft||0)-(b&&b.clientLeft||k&&k.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
k&&k.scrollTop||0)-(b&&b.clientTop||k&&k.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==undefined)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:e.proxy,special:{ready:{setup:e.bindReady,teardown:e.noop},live:{add:function(a){e.event.add(this,a.origType,e.extend({},a,{handler:i}))},remove:function(a){var b=true,k=a.origType.replace(sa,"");e.each(e.data(this,
"events").live||[],function(){if(k===this.origType.replace(sa,""))return b=false});b&&e.event.remove(this,a.origType,i)}},beforeunload:{setup:function(a,b,k){if(this.setInterval)this.onbeforeunload=k;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var La=n.removeEventListener?function(a,b,k){a.removeEventListener(b,k,false)}:function(a,b,k){a.detachEvent("on"+b,k)};e.Event=function(a){if(!this.preventDefault)return new e.Event(a);if(a&&a.type){this.originalEvent=
a;this.type=a.type}else this.type=a;this.timeStamp=h();this[S]=true};e.Event.prototype={preventDefault:function(){this.isDefaultPrevented=f;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=f;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=f;this.stopPropagation()},isDefaultPrevented:d,isPropagationStopped:d,
isImmediatePropagationStopped:d};var Ma=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;e.event.handle.apply(this,arguments)}}catch(k){}},Na=function(a){a.type=a.data;e.event.handle.apply(this,arguments)};e.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){e.event.special[a]={setup:function(k){e.event.add(this,b,k&&k.selector?Na:Ma,a)},teardown:function(k){e.event.remove(this,b,k&&k.selector?Na:Ma)}}});if(!e.support.submitBubbles)e.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){e.event.add(this,"click.specialSubmit",function(a){var b=a.target,k=b.type;if((k==="submit"||k==="image")&&e(b).closest("form").length)return m("submit",this,arguments)});e.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,k=b.type;if((k==="text"||k==="password")&&e(b).closest("form").length&&a.keyCode===13)return m("submit",this,arguments)})}else return false},teardown:function(){e.event.remove(this,".specialSubmit")}};if(!e.support.changeBubbles){var ya=
/textarea|input|select/i,za,Oa=function(a){var b=a.type,k=a.value;if(b==="radio"||b==="checkbox")k=a.checked;else if(b==="select-multiple")k=a.selectedIndex>-1?e.map(a.options,function(p){return p.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")k=a.selectedIndex;return k},Aa=function(a,b){var k=a.target,p,o;if(!(!ya.test(k.nodeName)||k.readOnly)){p=e.data(k,"_change_data");o=Oa(k);if(a.type!=="focusout"||k.type!=="radio")e.data(k,"_change_data",o);if(!(p===undefined||o===p))if(p!=
null||o){a.type="change";return e.event.trigger(a,b,k)}}};e.event.special.change={filters:{focusout:Aa,click:function(a){var b=a.target,k=b.type;if(k==="radio"||k==="checkbox"||b.nodeName.toLowerCase()==="select")return Aa.call(this,a)},keydown:function(a){var b=a.target,k=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(k==="checkbox"||k==="radio")||k==="select-multiple")return Aa.call(this,a)},beforeactivate:function(a){a=a.target;e.data(a,"_change_data",Oa(a))}},
setup:function(){if(this.type==="file")return false;for(var a in za)e.event.add(this,a+".specialChange",za[a]);return ya.test(this.nodeName)},teardown:function(){e.event.remove(this,".specialChange");return ya.test(this.nodeName)}};za=e.event.special.change.filters}n.addEventListener&&e.each({focus:"focusin",blur:"focusout"},function(a,b){function k(p){p=e.event.fix(p);p.type=b;return e.event.handle.call(this,p)}e.event.special[b]={setup:function(){this.addEventListener(a,k,true)},teardown:function(){this.removeEventListener(a,
k,true)}}});e.each(["bind","one"],function(a,b){e.fn[b]=function(k,p,o){if(typeof k==="object"){for(var z in k)this[b](z,p,k[z],o);return this}if(e.isFunction(p)){o=p;p=undefined}var A=b==="one"?e.proxy(o,function(E){e(this).unbind(E,A);return o.apply(this,arguments)}):o;if(k==="unload"&&b!=="one")this.one(k,p,o);else{z=0;for(var I=this.length;z<I;z++)e.event.add(this[z],k,A,p)}return this}});e.fn.extend({unbind:function(a,b){if(typeof a==="object"&&!a.preventDefault)for(var k in a)this.unbind(k,
a[k]);else{k=0;for(var p=this.length;k<p;k++)e.event.remove(this[k],a,b)}return this},delegate:function(a,b,k,p){return this.live(b,k,p,a)},undelegate:function(a,b,k){return arguments.length===0?this.unbind("live"):this.die(b,null,k,a)},trigger:function(a,b){return this.each(function(){e.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=e.Event(a);a.preventDefault();a.stopPropagation();e.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,k=1;k<
b.length;)e.proxy(a,b[k++]);return this.click(e.proxy(a,function(p){var o=(e.data(this,"lastToggle"+a.guid)||0)%k;e.data(this,"lastToggle"+a.guid,o+1);p.preventDefault();return b[o].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Pa={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};e.each(["live","die"],function(a,b){e.fn[b]=function(k,p,o,z){var A,I=0,E,H,R=z||this.selector,W=z?this:e(this.context);if(e.isFunction(p)){o=
p;p=undefined}for(k=(k||"").split(" ");(A=k[I++])!=null;){z=sa.exec(A);E="";if(z){E=z[0];A=A.replace(sa,"")}if(A==="hover")k.push("mouseenter"+E,"mouseleave"+E);else{H=A;if(A==="focus"||A==="blur"){k.push(Pa[A]+E);A+=E}else A=(Pa[A]||A)+E;b==="live"?W.each(function(){e.event.add(this,g(A,R),{data:p,selector:R,handler:o,origType:A,origHandler:o,preType:H})}):W.unbind(g(A,R),o)}}return this}});e.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
function(a,b){e.fn[b]=function(k){return k?this.bind(b,k):this.trigger(b)};if(e.attrFn)e.attrFn[b]=true});window.attachEvent&&!window.addEventListener&&window.attachEvent("onunload",function(){for(var a in e.cache)if(e.cache[a].handle)try{e.event.remove(e.cache[a].handle.elem)}catch(b){}});(function(){function a(u){for(var x="",F,G=0;u[G];G++){F=u[G];if(F.nodeType===3||F.nodeType===4)x+=F.nodeValue;else if(F.nodeType!==8)x+=a(F.childNodes)}return x}function b(u,x,F,G,N,M){N=0;for(var X=G.length;N<
X;N++){var V=G[N];if(V){V=V[u];for(var $=false;V;){if(V.sizcache===F){$=G[V.sizset];break}if(V.nodeType===1&&!M){V.sizcache=F;V.sizset=N}if(V.nodeName.toLowerCase()===x){$=V;break}V=V[u]}G[N]=$}}}function k(u,x,F,G,N,M){N=0;for(var X=G.length;N<X;N++){var V=G[N];if(V){V=V[u];for(var $=false;V;){if(V.sizcache===F){$=G[V.sizset];break}if(V.nodeType===1){if(!M){V.sizcache=F;V.sizset=N}if(typeof x!=="string"){if(V===x){$=true;break}}else if(E.filter(x,[V]).length>0){$=V;break}}V=V[u]}G[N]=$}}}var p=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
o=0,z=Object.prototype.toString,A=false,I=true;[0,0].sort(function(){I=false;return 0});var E=function(u,x,F,G){F=F||[];var N=x=x||n;if(x.nodeType!==1&&x.nodeType!==9)return[];if(!u||typeof u!=="string")return F;for(var M=[],X,V,$,ta,oa=true,qa=Y(x),pa=u;(p.exec(""),X=p.exec(pa))!==null;){pa=X[3];M.push(X[1]);if(X[2]){ta=X[3];break}}if(M.length>1&&R.exec(u))if(M.length===2&&H.relative[M[0]])V=Ba(M[0]+M[1],x);else for(V=H.relative[M[0]]?[x]:E(M.shift(),x);M.length;){u=M.shift();if(H.relative[u])u+=
M.shift();V=Ba(u,V)}else{if(!G&&M.length>1&&x.nodeType===9&&!qa&&H.match.ID.test(M[0])&&!H.match.ID.test(M[M.length-1])){X=E.find(M.shift(),x,qa);x=X.expr?E.filter(X.expr,X.set)[0]:X.set[0]}if(x){X=G?{expr:M.pop(),set:ba(G)}:E.find(M.pop(),M.length===1&&(M[0]==="~"||M[0]==="+")&&x.parentNode?x.parentNode:x,qa);V=X.expr?E.filter(X.expr,X.set):X.set;if(M.length>0)$=ba(V);else oa=false;for(;M.length;){var ia=M.pop();X=ia;if(H.relative[ia])X=M.pop();else ia="";if(X==null)X=x;H.relative[ia]($,X,qa)}}else $=
[]}$||($=V);$||E.error(ia||u);if(z.call($)==="[object Array]")if(oa)if(x&&x.nodeType===1)for(u=0;$[u]!=null;u++){if($[u]&&($[u]===true||$[u].nodeType===1&&ja(x,$[u])))F.push(V[u])}else for(u=0;$[u]!=null;u++)$[u]&&$[u].nodeType===1&&F.push(V[u]);else F.push.apply(F,$);else ba($,F);if(ta){E(ta,N,F,G);E.uniqueSort(F)}return F};E.uniqueSort=function(u){if(da){A=I;u.sort(da);if(A)for(var x=1;x<u.length;x++)u[x]===u[x-1]&&u.splice(x--,1)}return u};E.matches=function(u,x){return E(u,null,null,x)};E.find=
function(u,x,F){var G,N;if(!u)return[];for(var M=0,X=H.order.length;M<X;M++){var V=H.order[M];if(N=H.leftMatch[V].exec(u)){var $=N[1];N.splice(1,1);if($.substr($.length-1)!=="\\"){N[1]=(N[1]||"").replace(/\\/g,"");G=H.find[V](N,x,F);if(G!=null){u=u.replace(H.match[V],"");break}}}}G||(G=x.getElementsByTagName("*"));return{set:G,expr:u}};E.filter=function(u,x,F,G){for(var N=u,M=[],X=x,V,$,ta=x&&x[0]&&Y(x[0]);u&&x.length;){for(var oa in H.filter)if((V=H.leftMatch[oa].exec(u))!=null&&V[2]){var qa=H.filter[oa],
pa,ia;ia=V[1];$=false;V.splice(1,1);if(ia.substr(ia.length-1)!=="\\"){if(X===M)M=[];if(H.preFilter[oa])if(V=H.preFilter[oa](V,X,F,M,G,ta)){if(V===true)continue}else $=pa=true;if(V)for(var ua=0;(ia=X[ua])!=null;ua++)if(ia){pa=qa(ia,V,ua,X);var Qa=G^!!pa;if(F&&pa!=null)if(Qa)$=true;else X[ua]=false;else if(Qa){M.push(ia);$=true}}if(pa!==undefined){F||(X=M);u=u.replace(H.match[oa],"");if(!$)return[];break}}}if(u===N)if($==null)E.error(u);else break;N=u}return X};E.error=function(u){throw"Syntax error, unrecognized expression: "+
u;};var H=E.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},
leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(u){return u.getAttribute("href")}},relative:{"+":function(u,x){var F=typeof x==="string",G=F&&!/\W/.test(x);F=F&&!G;if(G)x=x.toLowerCase();G=0;for(var N=u.length,M;G<N;G++)if(M=u[G]){for(;(M=M.previousSibling)&&M.nodeType!==1;);u[G]=F||M&&M.nodeName.toLowerCase()===x?M||false:M===x}F&&E.filter(x,u,true)},">":function(u,x){var F=typeof x==="string";if(F&&!/\W/.test(x)){x=x.toLowerCase();for(var G=0,N=u.length;G<N;G++){var M=
u[G];if(M){F=M.parentNode;u[G]=F.nodeName.toLowerCase()===x?F:false}}}else{G=0;for(N=u.length;G<N;G++)if(M=u[G])u[G]=F?M.parentNode:M.parentNode===x;F&&E.filter(x,u,true)}},"":function(u,x,F){var G=o++,N=k;if(typeof x==="string"&&!/\W/.test(x)){var M=x=x.toLowerCase();N=b}N("parentNode",x,G,u,M,F)},"~":function(u,x,F){var G=o++,N=k;if(typeof x==="string"&&!/\W/.test(x)){var M=x=x.toLowerCase();N=b}N("previousSibling",x,G,u,M,F)}},find:{ID:function(u,x,F){if(typeof x.getElementById!=="undefined"&&
!F)return(u=x.getElementById(u[1]))?[u]:[]},NAME:function(u,x){if(typeof x.getElementsByName!=="undefined"){var F=[];x=x.getElementsByName(u[1]);for(var G=0,N=x.length;G<N;G++)x[G].getAttribute("name")===u[1]&&F.push(x[G]);return F.length===0?null:F}},TAG:function(u,x){return x.getElementsByTagName(u[1])}},preFilter:{CLASS:function(u,x,F,G,N,M){u=" "+u[1].replace(/\\/g,"")+" ";if(M)return u;M=0;for(var X;(X=x[M])!=null;M++)if(X)if(N^(X.className&&(" "+X.className+" ").replace(/[\t\n]/g," ").indexOf(u)>=
0))F||G.push(X);else if(F)x[M]=false;return false},ID:function(u){return u[1].replace(/\\/g,"")},TAG:function(u){return u[1].toLowerCase()},CHILD:function(u){if(u[1]==="nth"){var x=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(u[2]==="even"&&"2n"||u[2]==="odd"&&"2n+1"||!/\D/.test(u[2])&&"0n+"+u[2]||u[2]);u[2]=x[1]+(x[2]||1)-0;u[3]=x[3]-0}u[0]=o++;return u},ATTR:function(u,x,F,G,N,M){x=u[1].replace(/\\/g,"");if(!M&&H.attrMap[x])u[1]=H.attrMap[x];if(u[2]==="~=")u[4]=" "+u[4]+" ";return u},PSEUDO:function(u,x,F,G,
N){if(u[1]==="not")if((p.exec(u[3])||"").length>1||/^\w/.test(u[3]))u[3]=E(u[3],null,null,x);else{u=E.filter(u[3],x,F,true^N);F||G.push.apply(G,u);return false}else if(H.match.POS.test(u[0])||H.match.CHILD.test(u[0]))return true;return u},POS:function(u){u.unshift(true);return u}},filters:{enabled:function(u){return u.disabled===false&&u.type!=="hidden"},disabled:function(u){return u.disabled===true},checked:function(u){return u.checked===true},selected:function(u){return u.selected===true},parent:function(u){return!!u.firstChild},
empty:function(u){return!u.firstChild},has:function(u,x,F){return!!E(F[3],u).length},header:function(u){return/h\d/i.test(u.nodeName)},text:function(u){return"text"===u.type},radio:function(u){return"radio"===u.type},checkbox:function(u){return"checkbox"===u.type},file:function(u){return"file"===u.type},password:function(u){return"password"===u.type},submit:function(u){return"submit"===u.type},image:function(u){return"image"===u.type},reset:function(u){return"reset"===u.type},button:function(u){return"button"===
u.type||u.nodeName.toLowerCase()==="button"},input:function(u){return/input|select|textarea|button/i.test(u.nodeName)}},setFilters:{first:function(u,x){return x===0},last:function(u,x,F,G){return x===G.length-1},even:function(u,x){return x%2===0},odd:function(u,x){return x%2===1},lt:function(u,x,F){return x<F[3]-0},gt:function(u,x,F){return x>F[3]-0},nth:function(u,x,F){return F[3]-0===x},eq:function(u,x,F){return F[3]-0===x}},filter:{PSEUDO:function(u,x,F,G){var N=x[1],M=H.filters[N];if(M)return M(u,
F,x,G);else if(N==="contains")return(u.textContent||u.innerText||a([u])||"").indexOf(x[3])>=0;else if(N==="not"){x=x[3];F=0;for(G=x.length;F<G;F++)if(x[F]===u)return false;return true}else E.error("Syntax error, unrecognized expression: "+N)},CHILD:function(u,x){var F=x[1],G=u;switch(F){case "only":case "first":for(;G=G.previousSibling;)if(G.nodeType===1)return false;if(F==="first")return true;G=u;case "last":for(;G=G.nextSibling;)if(G.nodeType===1)return false;return true;case "nth":F=x[2];var N=
x[3];if(F===1&&N===0)return true;x=x[0];var M=u.parentNode;if(M&&(M.sizcache!==x||!u.nodeIndex)){var X=0;for(G=M.firstChild;G;G=G.nextSibling)if(G.nodeType===1)G.nodeIndex=++X;M.sizcache=x}u=u.nodeIndex-N;return F===0?u===0:u%F===0&&u/F>=0}},ID:function(u,x){return u.nodeType===1&&u.getAttribute("id")===x},TAG:function(u,x){return x==="*"&&u.nodeType===1||u.nodeName.toLowerCase()===x},CLASS:function(u,x){return(" "+(u.className||u.getAttribute("class"))+" ").indexOf(x)>-1},ATTR:function(u,x){var F=
x[1];u=H.attrHandle[F]?H.attrHandle[F](u):u[F]!=null?u[F]:u.getAttribute(F);F=u+"";var G=x[2];x=x[4];return u==null?G==="!=":G==="="?F===x:G==="*="?F.indexOf(x)>=0:G==="~="?(" "+F+" ").indexOf(x)>=0:!x?F&&u!==false:G==="!="?F!==x:G==="^="?F.indexOf(x)===0:G==="$="?F.substr(F.length-x.length)===x:G==="|="?F===x||F.substr(0,x.length+1)===x+"-":false},POS:function(u,x,F,G){var N=H.setFilters[x[2]];if(N)return N(u,F,x,G)}}},R=H.match.POS;for(var W in H.match){H.match[W]=new RegExp(H.match[W].source+/(?![^\[]*\])(?![^\(]*\))/.source);
H.leftMatch[W]=new RegExp(/(^(?:.|\r|\n)*?)/.source+H.match[W].source.replace(/\\(\d+)/g,function(u,x){return"\\"+(x-0+1)}))}var ba=function(u,x){u=Array.prototype.slice.call(u,0);if(x){x.push.apply(x,u);return x}return u};try{Array.prototype.slice.call(n.documentElement.childNodes,0)}catch(ea){ba=function(u,x){x=x||[];if(z.call(u)==="[object Array]")Array.prototype.push.apply(x,u);else if(typeof u.length==="number")for(var F=0,G=u.length;F<G;F++)x.push(u[F]);else for(F=0;u[F];F++)x.push(u[F]);return x}}var da;
if(n.documentElement.compareDocumentPosition)da=function(u,x){if(!u.compareDocumentPosition||!x.compareDocumentPosition){if(u==x)A=true;return u.compareDocumentPosition?-1:1}u=u.compareDocumentPosition(x)&4?-1:u===x?0:1;if(u===0)A=true;return u};else if("sourceIndex"in n.documentElement)da=function(u,x){if(!u.sourceIndex||!x.sourceIndex){if(u==x)A=true;return u.sourceIndex?-1:1}u=u.sourceIndex-x.sourceIndex;if(u===0)A=true;return u};else if(n.createRange)da=function(u,x){if(!u.ownerDocument||!x.ownerDocument){if(u==
x)A=true;return u.ownerDocument?-1:1}var F=u.ownerDocument.createRange(),G=x.ownerDocument.createRange();F.setStart(u,0);F.setEnd(u,0);G.setStart(x,0);G.setEnd(x,0);u=F.compareBoundaryPoints(Range.START_TO_END,G);if(u===0)A=true;return u};(function(){var u=n.createElement("div"),x="script"+(new Date).getTime();u.innerHTML="<a name='"+x+"'/>";var F=n.documentElement;F.insertBefore(u,F.firstChild);if(n.getElementById(x)){H.find.ID=function(G,N,M){if(typeof N.getElementById!=="undefined"&&!M)return(N=
N.getElementById(G[1]))?N.id===G[1]||typeof N.getAttributeNode!=="undefined"&&N.getAttributeNode("id").nodeValue===G[1]?[N]:undefined:[]};H.filter.ID=function(G,N){var M=typeof G.getAttributeNode!=="undefined"&&G.getAttributeNode("id");return G.nodeType===1&&M&&M.nodeValue===N}}F.removeChild(u);F=u=null})();(function(){var u=n.createElement("div");u.appendChild(n.createComment(""));if(u.getElementsByTagName("*").length>0)H.find.TAG=function(x,F){F=F.getElementsByTagName(x[1]);if(x[1]==="*"){x=[];
for(var G=0;F[G];G++)F[G].nodeType===1&&x.push(F[G]);F=x}return F};u.innerHTML="<a href='#'></a>";if(u.firstChild&&typeof u.firstChild.getAttribute!=="undefined"&&u.firstChild.getAttribute("href")!=="#")H.attrHandle.href=function(x){return x.getAttribute("href",2)};u=null})();n.querySelectorAll&&function(){var u=E,x=n.createElement("div");x.innerHTML="<p class='TEST'></p>";if(!(x.querySelectorAll&&x.querySelectorAll(".TEST").length===0)){E=function(G,N,M,X){N=N||n;if(!X&&N.nodeType===9&&!Y(N))try{return ba(N.querySelectorAll(G),
M)}catch(V){}return u(G,N,M,X)};for(var F in u)E[F]=u[F];x=null}}();(function(){var u=n.createElement("div");u.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!u.getElementsByClassName||u.getElementsByClassName("e").length===0)){u.lastChild.className="e";if(u.getElementsByClassName("e").length!==1){H.order.splice(1,0,"CLASS");H.find.CLASS=function(x,F,G){if(typeof F.getElementsByClassName!=="undefined"&&!G)return F.getElementsByClassName(x[1])};u=null}}})();var ja=n.compareDocumentPosition?
function(u,x){return!!(u.compareDocumentPosition(x)&16)}:function(u,x){return u!==x&&(u.contains?u.contains(x):true)},Y=function(u){return(u=(u?u.ownerDocument||u:0).documentElement)?u.nodeName!=="HTML":false},Ba=function(u,x){var F=[],G="",N;for(x=x.nodeType?[x]:x;N=H.match.PSEUDO.exec(u);){G+=N[0];u=u.replace(H.match.PSEUDO,"")}u=H.relative[u]?u+"*":u;N=0;for(var M=x.length;N<M;N++)E(u,x[N],F);return E.filter(G,F)};e.find=E;e.expr=E.selectors;e.expr[":"]=e.expr.filters;e.unique=E.uniqueSort;e.text=
a;e.isXMLDoc=Y;e.contains=ja})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,gb=/,/;O=Array.prototype.slice;var Ra=function(a,b,k){if(e.isFunction(b))return e.grep(a,function(o,z){return!!b.call(o,z,o)===k});else if(b.nodeType)return e.grep(a,function(o){return o===b===k});else if(typeof b==="string"){var p=e.grep(a,function(o){return o.nodeType===1});if(J.test(b))return e.filter(b,p,!k);else b=e.filter(b,p)}return e.grep(a,function(o){return e.inArray(o,b)>=0===k})};e.fn.extend({find:function(a){for(var b=
this.pushStack("","find",a),k=0,p=0,o=this.length;p<o;p++){k=b.length;e.find(a,this[p],b);if(p>0)for(var z=k;z<b.length;z++)for(var A=0;A<k;A++)if(b[A]===b[z]){b.splice(z--,1);break}}return b},has:function(a){var b=e(a);return this.filter(function(){for(var k=0,p=b.length;k<p;k++)if(e.contains(this,b[k]))return true})},not:function(a){return this.pushStack(Ra(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ra(this,a,true),"filter",a)},is:function(a){return!!a&&e.filter(a,this).length>
0},closest:function(a,b){if(e.isArray(a)){var k=[],p=this[0],o,z={},A;if(p&&a.length){o=0;for(var I=a.length;o<I;o++){A=a[o];z[A]||(z[A]=e.expr.match.POS.test(A)?e(A,b||this.context):A)}for(;p&&p.ownerDocument&&p!==b;){for(A in z){o=z[A];if(o.jquery?o.index(p)>-1:e(p).is(o)){k.push({selector:A,elem:p});delete z[A]}}p=p.parentNode}}return k}var E=e.expr.match.POS.test(a)?e(a,b||this.context):null;return this.map(function(H,R){for(;R&&R.ownerDocument&&R!==b;){if(E?E.index(R)>-1:e(R).is(a))return R;
R=R.parentNode}return null})},index:function(a){if(!a||typeof a==="string")return e.inArray(this[0],a?e(a):this.parent().children());return e.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?e(a,b||this.context):e.makeArray(a);b=e.merge(this.get(),a);return this.pushStack(j(a[0])||j(b[0])?b:e.unique(b))},andSelf:function(){return this.add(this.prevObject)}});e.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return e.dir(a,"parentNode")},
parentsUntil:function(a,b,k){return e.dir(a,"parentNode",k)},next:function(a){return e.nth(a,2,"nextSibling")},prev:function(a){return e.nth(a,2,"previousSibling")},nextAll:function(a){return e.dir(a,"nextSibling")},prevAll:function(a){return e.dir(a,"previousSibling")},nextUntil:function(a,b,k){return e.dir(a,"nextSibling",k)},prevUntil:function(a,b,k){return e.dir(a,"previousSibling",k)},siblings:function(a){return e.sibling(a.parentNode.firstChild,a)},children:function(a){return e.sibling(a.firstChild)},
contents:function(a){return e.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:e.makeArray(a.childNodes)}},function(a,b){e.fn[a]=function(k,p){var o=e.map(this,b,k);eb.test(a)||(p=k);if(p&&typeof p==="string")o=e.filter(p,o);o=this.length>1?e.unique(o):o;if((this.length>1||gb.test(p))&&fb.test(a))o=o.reverse();return this.pushStack(o,a,O.call(arguments).join(","))}});e.extend({filter:function(a,b,k){if(k)a=":not("+a+")";return e.find.matches(a,b)},dir:function(a,b,k){var p=[];for(a=
a[b];a&&a.nodeType!==9&&(k===undefined||a.nodeType!==1||!e(a).is(k));){a.nodeType===1&&p.push(a);a=a[b]}return p},nth:function(a,b,k){b=b||1;for(var p=0;a;a=a[k])if(a.nodeType===1&&++p===b)break;return a},sibling:function(a,b){for(var k=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&k.push(a);return k}});var Sa=/ jQuery\d+="(?:\d+|null)"/g,va=/^\s+/,Ta=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ua=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,Ha=/<script|<object|<embed|<option|<style/i,
Ia=/checked\s*(?:[^=]|=\s*.checked.)/i,Va=function(a,b,k){return hb.test(k)?a:b+"></"+k+">"},ka={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};ka.optgroup=ka.option;ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead;ka.th=
ka.td;if(!e.support.htmlSerialize)ka._default=[1,"div<div>","</div>"];e.fn.extend({text:function(a){if(e.isFunction(a))return this.each(function(b){var k=e(this);k.text(a.call(this,b,k.text()))});if(typeof a!=="object"&&a!==undefined)return this.empty().append((this[0]&&this[0].ownerDocument||n).createTextNode(a));return e.text(this)},wrapAll:function(a){if(e.isFunction(a))return this.each(function(k){e(this).wrapAll(a.call(this,k))});if(this[0]){var b=e(a,this[0].ownerDocument).eq(0).clone(true);
this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var k=this;k.firstChild&&k.firstChild.nodeType===1;)k=k.firstChild;return k}).append(this)}return this},wrapInner:function(a){if(e.isFunction(a))return this.each(function(b){e(this).wrapInner(a.call(this,b))});return this.each(function(){var b=e(this),k=b.contents();k.length?k.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){e(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){e.nodeName(this,
"body")||e(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=e(arguments[0]);a.push.apply(a,this.toArray());
return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,e(arguments[0]).toArray());return a}},remove:function(a,b){for(var k=0,p;(p=this[k])!=null;k++)if(!a||e.filter(a,[p]).length){if(!b&&p.nodeType===1){e.cleanData(p.getElementsByTagName("*"));e.cleanData([p])}p.parentNode&&
p.parentNode.removeChild(p)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&e.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);return this},clone:function(a){var b=this.map(function(){if(!e.support.noCloneEvent&&!e.isXMLDoc(this)){var k=this.outerHTML,p=this.ownerDocument;if(!k){k=p.createElement("div");k.appendChild(this.cloneNode(true));k=k.innerHTML}return e.clean([k.replace(Sa,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(va,
"")],p)[0]}else return this.cloneNode(true)});if(a===true){q(this,b);q(this.find("*"),b.find("*"))}return b},html:function(a){if(a===undefined)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Sa,""):null;else if(typeof a==="string"&&!Ha.test(a)&&(e.support.leadingWhitespace||!va.test(a))&&!ka[(Ua.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ta,Va);try{for(var b=0,k=this.length;b<k;b++)if(this[b].nodeType===1){e.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(p){this.empty().append(a)}}else e.isFunction(a)?
this.each(function(o){var z=e(this),A=z.html();z.empty().append(function(){return a.call(this,o,A)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(e.isFunction(a))return this.each(function(b){var k=e(this),p=k.html();k.replaceWith(a.call(this,b,p))});if(typeof a!=="string")a=e(a).detach();return this.each(function(){var b=this.nextSibling,k=this.parentNode;e(this).remove();b?e(b).before(a):e(k).append(a)})}else return this.pushStack(e(e.isFunction(a)?
a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,k){function p(W){return e.nodeName(W,"table")?W.getElementsByTagName("tbody")[0]||W.appendChild(W.ownerDocument.createElement("tbody")):W}var o,z,A=a[0],I=[],E;if(!e.support.checkClone&&arguments.length===3&&typeof A==="string"&&Ia.test(A))return this.each(function(){e(this).domManip(a,b,k,true)});if(e.isFunction(A))return this.each(function(W){var ba=e(this);a[0]=A.call(this,W,b?ba.html():undefined);ba.domManip(a,
b,k)});if(this[0]){o=A&&A.parentNode;o=e.support.parentNode&&o&&o.nodeType===11&&o.childNodes.length===this.length?{fragment:o}:t(a,this,I);E=o.fragment;if(z=E.childNodes.length===1?(E=E.firstChild):E.firstChild){b=b&&e.nodeName(z,"tr");for(var H=0,R=this.length;H<R;H++)k.call(b?p(this[H],z):this[H],H>0||o.cacheable||this.length>1?E.cloneNode(true):E)}I.length&&e.each(I,r)}return this}});e.fragments={};e.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},
function(a,b){e.fn[a]=function(k){var p=[];k=e(k);var o=this.length===1&&this[0].parentNode;if(o&&o.nodeType===11&&o.childNodes.length===1&&k.length===1){k[b](this[0]);return this}else{o=0;for(var z=k.length;o<z;o++){var A=(o>0?this.clone(true):this).get();e.fn[b].apply(e(k[o]),A);p=p.concat(A)}return this.pushStack(p,a,k.selector)}}});e.extend({clean:function(a,b,k,p){b=b||n;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||n;for(var o=[],z=0,A;(A=a[z])!=null;z++){if(typeof A===
"number")A+="";if(A){if(typeof A==="string"&&!jb.test(A))A=b.createTextNode(A);else if(typeof A==="string"){A=A.replace(Ta,Va);var I=(Ua.exec(A)||["",""])[1].toLowerCase(),E=ka[I]||ka._default,H=E[0],R=b.createElement("div");for(R.innerHTML=E[1]+A+E[2];H--;)R=R.lastChild;if(!e.support.tbody){H=ib.test(A);I=I==="table"&&!H?R.firstChild&&R.firstChild.childNodes:E[1]==="<table>"&&!H?R.childNodes:[];for(E=I.length-1;E>=0;--E)e.nodeName(I[E],"tbody")&&!I[E].childNodes.length&&I[E].parentNode.removeChild(I[E])}!e.support.leadingWhitespace&&
va.test(A)&&R.insertBefore(b.createTextNode(va.exec(A)[0]),R.firstChild);A=R.childNodes}if(A.nodeType)o.push(A);else o=e.merge(o,A)}}if(k)for(z=0;o[z];z++)if(p&&e.nodeName(o[z],"script")&&(!o[z].type||o[z].type.toLowerCase()==="text/javascript"))p.push(o[z].parentNode?o[z].parentNode.removeChild(o[z]):o[z]);else{o[z].nodeType===1&&o.splice.apply(o,[z+1,0].concat(e.makeArray(o[z].getElementsByTagName("script"))));k.appendChild(o[z])}return o},cleanData:function(a){for(var b,k,p=e.cache,o=e.event.special,
z=e.support.deleteExpando,A=0,I;(I=a[A])!=null;A++)if(k=I[e.expando]){b=p[k];if(b.events)for(var E in b.events)o[E]?e.event.remove(I,E):La(I,E,b.handle);if(z)delete I[e.expando];else I.removeAttribute&&I.removeAttribute(e.expando);delete p[k]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Wa=/alpha\([^)]*\)/,Xa=/opacity=([^)]*)/,Ca=/float/i,Da=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],
qb=["Top","Bottom"],rb=n.defaultView&&n.defaultView.getComputedStyle,Ya=e.support.cssFloat?"cssFloat":"styleFloat",Ea=function(a,b){return b.toUpperCase()};e.fn.css=function(a,b){return l(this,a,b,true,function(k,p,o){if(o===undefined)return e.curCSS(k,p);if(typeof o==="number"&&!kb.test(p))o+="px";e.style(k,p,o)})};e.extend({style:function(a,b,k){if(!(!a||a.nodeType===3||a.nodeType===8)){if((b==="width"||b==="height")&&parseFloat(k)<0)k=undefined;var p=a.style||a,o=k!==undefined;if(!e.support.opacity&&
b==="opacity"){if(o){p.zoom=1;b=parseInt(k,10)+""==="NaN"?"":"alpha(opacity="+k*100+")";a=p.filter||e.curCSS(a,"filter")||"";p.filter=Wa.test(a)?a.replace(Wa,b):b}return p.filter&&p.filter.indexOf("opacity=")>=0?parseFloat(Xa.exec(p.filter)[1])/100+"":""}if(Ca.test(b))b=Ya;b=b.replace(Da,Ea);if(o)p[b]=k;return p[b]}},css:function(a,b,k,p){if(b==="width"||b==="height"){var o,z=b==="width"?pb:qb;k=function(){o=b==="width"?a.offsetWidth:a.offsetHeight;p!=="border"&&e.each(z,function(){p||(o-=parseFloat(e.curCSS(a,
"padding"+this,true))||0);if(p==="margin")o+=parseFloat(e.curCSS(a,"margin"+this,true))||0;else o-=parseFloat(e.curCSS(a,"border"+this+"Width",true))||0})};a.offsetWidth!==0?k():e.swap(a,ob,k);return Math.max(0,Math.round(o))}return e.curCSS(a,b,k)},curCSS:function(a,b,k){var p,o=a.style;if(!e.support.opacity&&b==="opacity"&&a.currentStyle){p=Xa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return p===""?"1":p}if(Ca.test(b))b=Ya;if(!k&&o&&o[b])p=o[b];else if(rb){if(Ca.test(b))b=
"float";b=b.replace(lb,"-$1").toLowerCase();o=a.ownerDocument.defaultView;if(!o)return null;if(a=o.getComputedStyle(a,null))p=a.getPropertyValue(b);if(b==="opacity"&&p==="")p="1"}else if(a.currentStyle){k=b.replace(Da,Ea);p=a.currentStyle[b]||a.currentStyle[k];if(!mb.test(p)&&nb.test(p)){b=o.left;var z=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;o.left=k==="fontSize"?"1em":p||0;p=o.pixelLeft+"px";o.left=b;a.runtimeStyle.left=z}}return p},swap:function(a,b,k){var p={};for(var o in b){p[o]=
a.style[o];a.style[o]=b[o]}k.call(a);for(o in b)a.style[o]=p[o]}});if(e.expr&&e.expr.filters){e.expr.filters.hidden=function(a){var b=a.offsetWidth,k=a.offsetHeight,p=a.nodeName.toLowerCase()==="tr";return b===0&&k===0&&!p?true:b>0&&k>0&&!p?false:e.curCSS(a,"display")==="none"};e.expr.filters.visible=function(a){return!e.expr.filters.hidden(a)}}var sb=h(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,
ra=/=\?(&|$)/,Fa=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=e.fn.load;e.fn.extend({load:function(a,b,k){if(typeof a!=="string")return zb.call(this,a);else if(!this.length)return this;var p=a.indexOf(" ");if(p>=0){var o=a.slice(p,a.length);a=a.slice(0,p)}p="GET";if(b)if(e.isFunction(b)){k=b;b=null}else if(typeof b==="object"){b=e.param(b,e.ajaxSettings.traditional);p="POST"}var z=this;e.ajax({url:a,type:p,dataType:"html",data:b,complete:function(A,I){if(I==="success"||I===
"notmodified")z.html(o?e("<div />").append(A.responseText.replace(tb,"")).find(o):A.responseText);k&&z.each(k,[A.responseText,I,A])}});return this},serialize:function(){return e.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?e.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=e(this).val();return a==null?null:e.isArray(a)?e.map(a,
function(k){return{name:b.name,value:k}}):{name:b.name,value:a}}).get()}});e.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){e.fn[b]=function(k){return this.bind(b,k)}});e.extend({get:function(a,b,k,p){if(e.isFunction(b)){p=p||k;k=b;b=null}return e.ajax({type:"GET",url:a,data:b,success:k,dataType:p})},getScript:function(a,b){return e.get(a,null,b,"script")},getJSON:function(a,b,k){return e.get(a,b,k,"json")},post:function(a,b,k,p){if(e.isFunction(b)){p=
p||k;k=b;b={}}return e.ajax({type:"POST",url:a,data:b,success:k,dataType:p})},ajaxSetup:function(a){e.extend(e.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:window.XMLHttpRequest&&(window.location.protocol!=="file:"||!window.ActiveXObject)?function(){return new window.XMLHttpRequest}:function(){try{return new window.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",
html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){o.success&&o.success.call(E,I,A,Y);o.global&&p("ajaxSuccess",[Y,o])}function k(){o.complete&&o.complete.call(E,Y,A);o.global&&p("ajaxComplete",[Y,o]);o.global&&!--e.active&&e.event.trigger("ajaxStop")}function p(N,M){(o.context?e(o.context):e.event).trigger(N,M)}var o=e.extend(true,{},e.ajaxSettings,a),z,
A,I,E=a&&a.context||o,H=o.type.toUpperCase();if(o.data&&o.processData&&typeof o.data!=="string")o.data=e.param(o.data,o.traditional);if(o.dataType==="jsonp"){if(H==="GET")ra.test(o.url)||(o.url+=(Fa.test(o.url)?"&":"?")+(o.jsonp||"callback")+"=?");else if(!o.data||!ra.test(o.data))o.data=(o.data?o.data+"&":"")+(o.jsonp||"callback")+"=?";o.dataType="json"}if(o.dataType==="json"&&(o.data&&ra.test(o.data)||ra.test(o.url))){z=o.jsonpCallback||"jsonp"+sb++;if(o.data)o.data=(o.data+"").replace(ra,"="+z+
"$1");o.url=o.url.replace(ra,"="+z+"$1");o.dataType="script";window[z]=window[z]||function(N){I=N;b();k();window[z]=undefined;try{delete window[z]}catch(M){}ba&&ba.removeChild(ea)}}if(o.dataType==="script"&&o.cache===null)o.cache=false;if(o.cache===false&&H==="GET"){var R=h(),W=o.url.replace(wb,"$1_="+R+"$2");o.url=W+(W===o.url?(Fa.test(o.url)?"&":"?")+"_="+R:"")}if(o.data&&H==="GET")o.url+=(Fa.test(o.url)?"&":"?")+o.data;o.global&&!e.active++&&e.event.trigger("ajaxStart");R=(R=xb.exec(o.url))&&(R[1]&&
R[1]!==location.protocol||R[2]!==location.host);if(o.dataType==="script"&&H==="GET"&&R){var ba=n.getElementsByTagName("head")[0]||n.documentElement,ea=n.createElement("script");ea.src=o.url;if(o.scriptCharset)ea.charset=o.scriptCharset;if(!z){var da=false;ea.onload=ea.onreadystatechange=function(){if(!da&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){da=true;b();k();ea.onload=ea.onreadystatechange=null;ba&&ea.parentNode&&ba.removeChild(ea)}}}ba.insertBefore(ea,ba.firstChild)}else{var ja=
false,Y=o.xhr();if(Y){o.username?Y.open(H,o.url,o.async,o.username,o.password):Y.open(H,o.url,o.async);try{if(o.data||a&&a.contentType)Y.setRequestHeader("Content-Type",o.contentType);if(o.ifModified){e.lastModified[o.url]&&Y.setRequestHeader("If-Modified-Since",e.lastModified[o.url]);e.etag[o.url]&&Y.setRequestHeader("If-None-Match",e.etag[o.url])}R||Y.setRequestHeader("X-Requested-With","XMLHttpRequest");Y.setRequestHeader("Accept",o.dataType&&o.accepts[o.dataType]?o.accepts[o.dataType]+", */*":
o.accepts._default)}catch(Ba){}if(o.beforeSend&&o.beforeSend.call(E,Y,o)===false){o.global&&!--e.active&&e.event.trigger("ajaxStop");Y.abort();return false}o.global&&p("ajaxSend",[Y,o]);var u=Y.onreadystatechange=function(N){if(!Y||Y.readyState===0||N==="abort"){ja||k();ja=true;if(Y)Y.onreadystatechange=e.noop}else if(!ja&&Y&&(Y.readyState===4||N==="timeout")){ja=true;Y.onreadystatechange=e.noop;A=N==="timeout"?"timeout":!e.httpSuccess(Y)?"error":o.ifModified&&e.httpNotModified(Y,o.url)?"notmodified":
"success";var M;if(A==="success")try{I=e.httpData(Y,o.dataType,o)}catch(X){A="parsererror";M=X}if(A==="success"||A==="notmodified")z||b();else e.handleError(o,Y,A,M);k();N==="timeout"&&Y.abort();if(o.async)Y=null}};try{var x=Y.abort;Y.abort=function(){Y&&x.call(Y);u("abort")}}catch(F){}o.async&&o.timeout>0&&setTimeout(function(){Y&&!ja&&u("timeout")},o.timeout);try{Y.send(H==="POST"||H==="PUT"||H==="DELETE"?o.data:null)}catch(G){e.handleError(o,Y,null,G);k()}o.async||u();return Y}}},handleError:function(a,
b,k,p){if(a.error)a.error.call(a.context||a,b,k,p);if(a.global)(a.context?e(a.context):e.event).trigger("ajaxError",[b,a,p])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var k=a.getResponseHeader("Last-Modified"),p=a.getResponseHeader("Etag");if(k)e.lastModified[b]=k;if(p)e.etag[b]=p;return a.status===304||a.status===0},httpData:function(a,
b,k){var p=a.getResponseHeader("content-type")||"",o=b==="xml"||!b&&p.indexOf("xml")>=0;a=o?a.responseXML:a.responseText;o&&a.documentElement.nodeName==="parsererror"&&e.error("parsererror");if(k&&k.dataFilter)a=k.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&p.indexOf("json")>=0)a=e.parseJSON(a);else if(b==="script"||!b&&p.indexOf("javascript")>=0)e.globalEval(a);return a},param:function(a,b){function k(A,I){if(e.isArray(I))e.each(I,function(E,H){b||/\[\]$/.test(A)?p(A,H):k(A+"["+(typeof H===
"object"||e.isArray(H)?E:"")+"]",H)});else!b&&I!=null&&typeof I==="object"?e.each(I,function(E,H){k(A+"["+E+"]",H)}):p(A,I)}function p(A,I){I=e.isFunction(I)?I():I;o[o.length]=encodeURIComponent(A)+"="+encodeURIComponent(I)}var o=[];if(b===undefined)b=e.ajaxSettings.traditional;if(e.isArray(a)||a.jquery)e.each(a,function(){p(this.name,this.value)});else for(var z in a)k(z,a[z]);return o.join("&").replace(yb,"+")}});var Ga={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,wa,Ja=[["height","marginTop",
"marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];e.fn.extend({show:function(a,b){if(a||a===0)return this.animate(B("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var k=e.data(this[a],"olddisplay");this[a].style.display=k||"";if(e.css(this[a],"display")==="none"){k=this[a].nodeName;var p;if(Ga[k])p=Ga[k];else{var o=e("<"+k+" />").appendTo("body");p=o.css("display");if(p==="none")p="block";o.remove();Ga[k]=p}e.data(this[a],
"olddisplay",p)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=e.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(B("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var k=e.data(this[a],"olddisplay");!k&&k!=="none"&&e.data(this[a],"olddisplay",e.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:e.fn.toggle,toggle:function(a,b){var k=typeof a==="boolean";if(e.isFunction(a)&&e.isFunction(b))this._toggle.apply(this,
arguments);else a==null||k?this.each(function(){var p=k?a:e(this).is(":hidden");e(this)[p?"show":"hide"]()}):this.animate(B("toggle",3),a,b);return this},fadeTo:function(a,b,k){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,k)},animate:function(a,b,k,p){var o=e.speed(b,k,p);if(e.isEmptyObject(a))return this.each(o.complete);return this[o.queue===false?"each":"queue"](function(){var z=e.extend({},o),A,I=this.nodeType===1&&e(this).is(":hidden"),E=this;for(A in a){var H=
A.replace(Da,Ea);if(A!==H){a[H]=a[A];delete a[A];A=H}if(a[A]==="hide"&&I||a[A]==="show"&&!I)return z.complete.call(this);if((A==="height"||A==="width")&&this.style){z.display=e.css(this,"display");z.overflow=this.style.overflow}if(e.isArray(a[A])){(z.specialEasing=z.specialEasing||{})[A]=a[A][1];a[A]=a[A][0]}}if(z.overflow!=null)this.style.overflow="hidden";z.curAnim=e.extend({},a);e.each(a,function(R,W){var ba=new e.fx(E,z,R);if(Ab.test(W))ba[W==="toggle"?I?"show":"hide":W](a);else{var ea=Bb.exec(W),
da=ba.cur(true)||0;if(ea){W=parseFloat(ea[2]);var ja=ea[3]||"px";if(ja!=="px"){E.style[R]=(W||1)+ja;da=(W||1)/ba.cur(true)*da;E.style[R]=da+ja}if(ea[1])W=(ea[1]==="-="?-1:1)*W+da;ba.custom(da,W,ja)}else ba.custom(da,W,"")}});return true})},stop:function(a,b){var k=e.timers;a&&this.queue([]);this.each(function(){for(var p=k.length-1;p>=0;p--)if(k[p].elem===this){b&&k[p](true);k.splice(p,1)}});b||this.dequeue();return this}});e.each({slideDown:B("show",1),slideUp:B("hide",1),slideToggle:B("toggle",
1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){e.fn[a]=function(k,p){return this.animate(b,k,p)}});e.extend({speed:function(a,b,k){var p=a&&typeof a==="object"?a:{complete:k||!k&&b||e.isFunction(a)&&a,duration:a,easing:k&&b||b&&!e.isFunction(b)&&b};p.duration=e.fx.off?0:typeof p.duration==="number"?p.duration:e.fx.speeds[p.duration]||e.fx.speeds._default;p.old=p.complete;p.complete=function(){p.queue!==false&&e(this).dequeue();e.isFunction(p.old)&&p.old.call(this)};return p},easing:{linear:function(a,
b,k,p){return k+p*a},swing:function(a,b,k,p){return(-Math.cos(a*Math.PI)/2+0.5)*p+k}},timers:[],fx:function(a,b,k){this.options=b;this.elem=a;this.prop=k;if(!b.orig)b.orig={}}});e.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(e.fx.step[this.prop]||e.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==
null))return this.elem[this.prop];return(a=parseFloat(e.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(e.curCSS(this.elem,this.prop))||0},custom:function(a,b,k){function p(z){return o.step(z)}this.startTime=h();this.start=a;this.end=b;this.unit=k||this.unit||"px";this.now=this.start;this.pos=this.state=0;var o=this;p.elem=this.elem;if(p()&&e.timers.push(p)&&!wa)wa=setInterval(e.fx.tick,13)},show:function(){this.options.orig[this.prop]=e.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop===
"width"||this.prop==="height"?1:0,this.cur());e(this.elem).show()},hide:function(){this.options.orig[this.prop]=e.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=h(),k=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var p in this.options.curAnim)if(this.options.curAnim[p]!==true)k=false;if(k){if(this.options.display!=null){this.elem.style.overflow=
this.options.overflow;a=e.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(e.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&e(this.elem).hide();if(this.options.hide||this.options.show)for(var o in this.options.curAnim)e.style(this.elem,o,this.options.orig[o]);this.options.complete.call(this.elem)}return false}else{o=b-this.startTime;this.state=o/this.options.duration;a=this.options.easing||(e.easing.swing?"swing":"linear");this.pos=
e.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,o,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};e.extend(e.fx,{tick:function(){for(var a=e.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||e.fx.stop()},stop:function(){clearInterval(wa);wa=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){e.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=
null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(e.expr&&e.expr.filters)e.expr.filters.animated=function(a){return e.grep(e.timers,function(b){return a===b.elem}).length};e.fn.offset="getBoundingClientRect"in n.documentElement?function(a){var b=this[0];if(a)return this.each(function(o){e.offset.setOffset(this,a,o)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return e.offset.bodyOffset(b);var k=b.getBoundingClientRect(),
p=b.ownerDocument;b=p.body;p=p.documentElement;return{top:k.top+(self.pageYOffset||e.support.boxModel&&p.scrollTop||b.scrollTop)-(p.clientTop||b.clientTop||0),left:k.left+(self.pageXOffset||e.support.boxModel&&p.scrollLeft||b.scrollLeft)-(p.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(R){e.offset.setOffset(this,a,R)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return e.offset.bodyOffset(b);e.offset.initialize();var k=b.offsetParent,p=
b,o=b.ownerDocument,z,A=o.documentElement,I=o.body;p=(o=o.defaultView)?o.getComputedStyle(b,null):b.currentStyle;for(var E=b.offsetTop,H=b.offsetLeft;(b=b.parentNode)&&b!==I&&b!==A;){if(e.offset.supportsFixedPosition&&p.position==="fixed")break;z=o?o.getComputedStyle(b,null):b.currentStyle;E-=b.scrollTop;H-=b.scrollLeft;if(b===k){E+=b.offsetTop;H+=b.offsetLeft;if(e.offset.doesNotAddBorder&&!(e.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){E+=parseFloat(z.borderTopWidth)||
0;H+=parseFloat(z.borderLeftWidth)||0}p=k;k=b.offsetParent}if(e.offset.subtractsBorderForOverflowNotVisible&&z.overflow!=="visible"){E+=parseFloat(z.borderTopWidth)||0;H+=parseFloat(z.borderLeftWidth)||0}p=z}if(p.position==="relative"||p.position==="static"){E+=I.offsetTop;H+=I.offsetLeft}if(e.offset.supportsFixedPosition&&p.position==="fixed"){E+=Math.max(A.scrollTop,I.scrollTop);H+=Math.max(A.scrollLeft,I.scrollLeft)}return{top:E,left:H}};e.offset={initialize:function(){var a=n.body,b=n.createElement("div"),
k,p,o,z=parseFloat(e.curCSS(a,"marginTop",true))||0;e.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);
k=b.firstChild;p=k.firstChild;o=k.nextSibling.firstChild.firstChild;this.doesNotAddBorder=p.offsetTop!==5;this.doesAddBorderForTableAndCells=o.offsetTop===5;p.style.position="fixed";p.style.top="20px";this.supportsFixedPosition=p.offsetTop===20||p.offsetTop===15;p.style.position=p.style.top="";k.style.overflow="hidden";k.style.position="relative";this.subtractsBorderForOverflowNotVisible=p.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==z;a.removeChild(b);e.offset.initialize=e.noop},
bodyOffset:function(a){var b=a.offsetTop,k=a.offsetLeft;e.offset.initialize();if(e.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(e.curCSS(a,"marginTop",true))||0;k+=parseFloat(e.curCSS(a,"marginLeft",true))||0}return{top:b,left:k}},setOffset:function(a,b,k){if(/static/.test(e.curCSS(a,"position")))a.style.position="relative";var p=e(a),o=p.offset(),z=parseInt(e.curCSS(a,"top",true),10)||0,A=parseInt(e.curCSS(a,"left",true),10)||0;if(e.isFunction(b))b=b.call(a,k,o);k={top:b.top-o.top+z,left:b.left-
o.left+A};"using"in b?b.using.call(a,k):p.css(k)}};e.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),k=this.offset(),p=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();k.top-=parseFloat(e.curCSS(a,"marginTop",true))||0;k.left-=parseFloat(e.curCSS(a,"marginLeft",true))||0;p.top+=parseFloat(e.curCSS(b[0],"borderTopWidth",true))||0;p.left+=parseFloat(e.curCSS(b[0],"borderLeftWidth",true))||0;return{top:k.top-p.top,left:k.left-p.left}},offsetParent:function(){return this.map(function(){for(var a=
this.offsetParent||n.body;a&&!/^body|html$/i.test(a.nodeName)&&e.css(a,"position")==="static";)a=a.offsetParent;return a})}});e.each(["Left","Top"],function(a,b){var k="scroll"+b;e.fn[k]=function(p){var o=this[0],z;if(!o)return null;if(p!==undefined)return this.each(function(){if(z=C(this))z.scrollTo(!a?p:e(z).scrollLeft(),a?p:e(z).scrollTop());else this[k]=p});else return(z=C(o))?"pageXOffset"in z?z[a?"pageYOffset":"pageXOffset"]:e.support.boxModel&&z.document.documentElement[k]||z.document.body[k]:
o[k]}});e.each(["Height","Width"],function(a,b){var k=b.toLowerCase();e.fn["inner"+b]=function(){return this[0]?e.css(this[0],k,false,"padding"):null};e.fn["outer"+b]=function(p){return this[0]?e.css(this[0],k,false,p?"margin":"border"):null};e.fn[k]=function(p){var o=this[0];if(!o)return p==null?null:this;if(e.isFunction(p))return this.each(function(z){var A=e(this);A[k](p.call(this,z,A[k]()))});return"scrollTo"in o&&o.document?o.document.compatMode==="CSS1Compat"&&o.document.documentElement["client"+
b]||o.document.body["client"+b]:o.nodeType===9?Math.max(o.documentElement["client"+b],o.body["scroll"+b],o.documentElement["scroll"+b],o.body["offset"+b],o.documentElement["offset"+b]):p===undefined?e.css(o,k):this.css(k,typeof p==="string"?p:p+"px")}});s.$=s.jQuery=e});bespin.tiki.register("::embedded",{name:"embedded",dependencies:{theme_manager:"0.0.0",text_editor:"0.0.0",appconfig:"0.0.0",edit_session:"0.0.0",screen_theme:"0.0.0"}});bespin.tiki.module("embedded:index",function(){});
bespin.tiki.register("::settings",{name:"settings",dependencies:{types:"0.0.0"}});
bespin.tiki.module("settings:commands",function(y,s){y("bespin:plugins");y("environment");var v=y("settings").settings;s.setCommand=function(r,l){var h;if(r.setting)if(r.value===undefined)h="<strong>"+r.setting+"</strong> = "+v.get(r.setting);else{h="Setting: <strong>"+r.setting+"</strong> = "+r.value;v.set(r.setting,r.value)}else{r=v._list();h="";r.sort(function(d,f){return d.key<f.key?-1:d.key==f.key?0:1});r.forEach(function(d){h+='<a class="setting" href="https://wiki.mozilla.org/Labs/Bespin/Settings#'+
d.key+'" title="View external documentation on setting: '+d.key+'" target="_blank">'+d.key+"</a> = "+d.value+"<br/>"})}l.done(h)};s.unsetCommand=function(r,l){v.resetValue(r.setting);l.done("Reset "+r.setting+" to default: "+v.get(r.setting))}});
bespin.tiki.module("settings:cookie",function(y,s){var v=y("bespin:util/cookie");s.CookiePersister=function(){};s.CookiePersister.prototype={loadInitialValues:function(r){r._loadDefaultValues().then(function(){var l=v.get("settings");r._loadFromObject(JSON.parse(l))}.bind(this))},persistValue:function(r){try{var l={};r._getSettingNames().forEach(function(f){l[f]=r.get(f)});var h=JSON.stringify(l);v.set("settings",h)}catch(d){console.error("Unable to JSONify the settings! "+d)}}}});
bespin.tiki.module("settings:index",function(y,s){var v=y("bespin:plugins").catalog,r=y("bespin:console").console,l=y("bespin:promise").Promise,h=y("bespin:promise").group,d=y("types:types");s.addSetting=function(f){y("settings").settings.addSetting(f)};s.getSettings=function(){return v.getExtensions("setting")};s.getTypeSpecFromAssignment=function(f){var m=f.assignments;f="text";if(m){var i=null;m.forEach(function(g){if(g.param.name==="setting")i=g});if(i)if((m=i.value)&&m!=="")if(m=v.getExtensionByKey("setting",
m))f=m.type}return f};s.MemorySettings=function(){};s.MemorySettings.prototype={_values:{},_deactivated:{},setPersister:function(f){(this._persister=f)&&f.loadInitialValues(this)},get:function(f){return this._values[f]},set:function(f,m){var i=v.getExtensionByKey("setting",f);if(i)if(typeof m=="string"&&i.type=="string")this._values[f]=m;else{var g=false;d.fromString(m,i.type).then(function(j){g=true;this._values[f]=j;v.publish(this,"settingChange",f,j)}.bind(this),function(j){r.error("Error setting",
f,": ",j)});if(!g){r.warn("About to set string version of ",f,"delaying typed set.");this._values[f]=m}}else{r.warn("Setting not defined: ",f,m);this._deactivated[f]=m}this._persistValue(f,m);return this},addSetting:function(f){if(f.name){!f.defaultValue===undefined&&r.error("Setting.defaultValue == undefined",f);d.isValid(f.defaultValue,f.type).then(function(m){m||r.warn("!Setting.isValid(Setting.defaultValue)",f);this.set(f.name,this._deactivated[f.name]||f.defaultValue)}.bind(this),function(m){r.error("Type error ",
m," ignoring setting ",f)})}else r.error("Setting.name == undefined. Ignoring.",f)},resetValue:function(f){var m=v.getExtensionByKey("setting",f);m?this.set(f,m.defaultValue):r.log("ignore resetValue on ",f)},resetAll:function(){this._getSettingNames().forEach(function(f){this.resetValue(f)}.bind(this))},_getSettingNames:function(){var f=[];v.getExtensions("setting").forEach(function(m){f.push(m.name)});return f},_list:function(){var f=[];this._getSettingNames().forEach(function(m){f.push({key:m,
value:this.get(m)})}.bind(this));return f},_persistValue:function(f,m){var i=this._persister;i&&i.persistValue(this,f,m)},_loadInitialValues:function(){var f=this._persister;f?f.loadInitialValues(this):this._loadDefaultValues()},_loadDefaultValues:function(){return this._loadFromObject(this._defaultValues())},_loadFromObject:function(f){var m=[],i=function(B){return function(C){this.set(B,C)}};for(var g in f)if(f.hasOwnProperty(g)){var j=f[g],q=v.getExtensionByKey("setting",g);if(q){j=d.fromString(j,
q.type);q=i(g);j.then(q);m.push(j)}}var t=new l;h(m).then(function(){t.resolve()});return t},_saveToObject:function(){var f=[],m={};this._getSettingNames().forEach(function(g){var j=this.get(g),q=v.getExtensionByKey("setting",g);if(q){j=d.toString(j,q.type);j.then(function(t){m[g]=t});f.push(j)}}.bind(this));var i=new l;h(f).then(function(){i.resolve(m)});return i},_defaultValues:function(){var f={};v.getExtensions("setting").forEach(function(m){f[m.name]=m.defaultValue});return f}};s.settings=new s.MemorySettings});
bespin.tiki.register("::appconfig",{name:"appconfig",dependencies:{jquery:"0.0.0",canon:"0.0.0",settings:"0.0.0"}});
bespin.tiki.module("appconfig:index",function(y,s){var v=y("jquery").$,r=y("settings").settings,l=y("bespin:promise").group,h=y("bespin:promise").Promise,d=y("bespin:console").console,f=y("bespin:util/stacktrace").Trace,m=y("bespin:util/util"),i=true;s.launch=function(q){var t=new h;v("#_bespin_loading").remove();var B;if(i){B=bespin.tiki.require;i=false}else B=(new (bespin.tiki.require("bespin:sandbox").Sandbox)).createRequire({id:"index",ownerPackage:bespin.tiki.loader.anonymousPackage});var C=
B("bespin:plugins").catalog;q=q||{};s.normalizeConfig(C,q);var e=q.objects;for(var K in e)C.registerObject(K,e[K]);for(var L in q.settings)r.set(L,q.settings[L]);var n=function(){var D=B("environment").env,J=D.editor;if(J){q.lineNumber&&J.setLineNumber(q.lineNumber);if(q.stealFocus)J.focus=true;if(q.readOnly)J.readOnly=q.readOnly;if(q.syntax)J.syntax=q.syntax}if(J=C.getObject("commandLine"))D.commandLine=J;C.publish(this,"appLaunched");t.resolve(D)}.bind(this),w=new h;w.then(function(){e.loginController?
C.createObject("loginController").then(function(D){D.showLogin().then(function(J){q.objects.session.arguments.push(J);s.launchEditor(C,q).then(n,t.reject.bind(t))})}):s.launchEditor(C,q).then(n,t.reject.bind(t))},function(D){t.reject(D)});C.plugins.theme_manager?bespin.tiki.require.ensurePackage("::theme_manager",function(){var D=B("theme_manager");q.theme.basePlugin&&D.setBasePlugin(q.theme.basePlugin);q.theme.standard&&D.setStandardTheme(q.theme.standard);D.startParsing().then(function(){w.resolve()},
function(J){w.reject(J)})}):w.resolve();return t};s.normalizeConfig=function(q,t){if(t.objects===undefined)t.objects={};if(t.autoload===undefined)t.autoload=[];if(t.theme===undefined)t.theme={};if(!t.theme.basePlugin&&q.plugins.screen_theme)t.theme.basePlugin="screen_theme";if(!t.initialContent)t.initialContent="";if(!t.settings)t.settings={};if(!t.objects.notifier&&q.plugins.notifier)t.objects.notifier={};if(!t.objects.loginController&&q.plugins.userident)t.objects.loginController={};if(!t.objects.fileHistory&&
q.plugins.file_history)t.objects.fileHistory={factory:"file_history",arguments:["session"],objects:{"0":"session"}};if(!t.objects.server&&q.plugins.bespin_server){t.objects.server={factory:"bespin_server"};t.objects.filesource={factory:"bespin_filesource",arguments:["server"],objects:{"0":"server"}}}if(!t.objects.files&&q.plugins.filesystem&&t.objects.filesource)t.objects.files={arguments:["filesource"],objects:{"0":"filesource"}};if(!t.objects.editor)t.objects.editor={factory:"text_editor",arguments:[t.initialContent]};
if(!t.objects.session)t.objects.session={arguments:["editor"],objects:{"0":"editor"}};if(!t.objects.commandLine&&q.plugins.command_line)t.objects.commandLine={};if(t.gui===undefined)t.gui={};q={};for(var B in t.gui){var C=t.gui[B];if(C.component)q[C.component]=true}if(!t.gui.center&&t.objects.editor&&!q.editor)t.gui.center={component:"editor"};if(!t.gui.south&&t.objects.commandLine&&!q.commandLine)t.gui.south={component:"commandLine"}};s.launchEditor=function(q,t){var B=new h;if(t===null){d.error("Cannot start editor without a configuration!");
B.reject("Cannot start editor without a configuration!");return B}g(q,t).then(function(){j(q,t,B)},function(C){d.error("Error while creating objects");(new f(C)).log();B.reject(C)});return B};var g=function(q,t){var B=[];for(var C in t.objects)B.push(q.createObject(C));return l(B)},j=function(q,t,B){var C=document.createElement("div");C.setAttribute("class","container");var e=document.createElement("div");e.setAttribute("class","center-container");C.appendChild(e);var K=t.element||document.body;m.addClass(K,
"bespin");K.appendChild(C);for(var L in t.gui){var n=t.gui[L],w=q.getObject(n.component);if(!w){q="Cannot find object "+n.component+" to attach to the Bespin UI";d.error(q);B.reject(q);return}K=w.element;if(!K){q="Component "+n.component+' does not have an "element" attribute to attach to the Bespin UI';d.error(q);B.reject(q);return}v(K).addClass(L);L=="west"||L=="east"||L=="center"?e.appendChild(K):C.appendChild(K);w.elementAppended&&w.elementAppended()}B.resolve()}});
bespin.tiki.register("::events",{name:"events",dependencies:{traits:"0.0.0"}});bespin.tiki.module("events:index",function(y,s){s.Event=function(){var v=[],r=function(){var l=arguments;v.forEach(function(h){h.func.apply(null,l)})};r.add=function(){arguments.length==1?v.push({ref:arguments[0],func:arguments[0]}):v.push({ref:arguments[0],func:arguments[1]})};r.remove=function(l){v=v.filter(function(h){return l!==h.ref})};r.removeAll=function(){v=[]};return r}});
bespin.tiki.register("::screen_theme",{name:"screen_theme",dependencies:{theme_manager:"0.0.0"}});bespin.tiki.module("screen_theme:index",function(){});
(function(){var y=bespin.tiki.require("jquery").$;y(document).ready(function(){bespin.tiki.require("bespin:plugins").catalog.registerMetadata({text_editor:{resourceURL:"resources/text_editor/",description:"Canvas-based text editor component and many common editing commands",dependencies:{completion:"0.0.0",undomanager:"0.0.0",settings:"0.0.0",canon:"0.0.0",rangeutils:"0.0.0",traits:"0.0.0",theme_manager:"0.0.0",keyboard:"0.0.0",edit_session:"0.0.0",syntax_manager:"0.0.0"},testmodules:["tests/controllers/testLayoutmanager",
"tests/models/testTextstorage","tests/testScratchcanvas","tests/utils/testRect"],provides:[{action:"new",pointer:"views/editor#EditorView",ep:"factory",name:"text_editor"},{pointer:"views/editor#EditorView",ep:"appcomponent",name:"editor_view"},{predicates:{isTextView:true},pointer:"commands/editing#backspace",ep:"command",key:"backspace",name:"backspace"},{predicates:{isTextView:true},pointer:"commands/editing#deleteCommand",ep:"command",key:"delete",name:"delete"},{description:"Delete all lines currently selected",
key:"ctrl_d",predicates:{isTextView:true},pointer:"commands/editing#deleteLines",ep:"command",name:"deletelines"},{description:"Create a new, empty line below the current one",key:"ctrl_return",predicates:{isTextView:true},pointer:"commands/editing#openLine",ep:"command",name:"openline"},{description:"Join the current line with the following",key:"ctrl_shift_j",predicates:{isTextView:true},pointer:"commands/editing#joinLines",ep:"command",name:"joinline"},{params:[{defaultValue:"",type:"text",name:"text",
description:"The text to insert"}],pointer:"commands/editing#insertText",ep:"command",name:"insertText"},{predicates:{completing:false,isTextView:true},pointer:"commands/editing#newline",ep:"command",key:"return",name:"newline"},{predicates:{completing:false,isTextView:true},pointer:"commands/editing#tab",ep:"command",key:"tab",name:"tab"},{predicates:{isTextView:true},pointer:"commands/editing#untab",ep:"command",key:"shift_tab",name:"untab"},{predicates:{isTextView:true},ep:"command",name:"move"},
{description:"Repeat the last search (forward)",pointer:"commands/editor#findNextCommand",ep:"command",key:"ctrl_g",name:"findnext"},{description:"Repeat the last search (backward)",pointer:"commands/editor#findPrevCommand",ep:"command",key:"ctrl_shift_g",name:"findprev"},{predicates:{completing:false,isTextView:true},pointer:"commands/movement#moveDown",ep:"command",key:"down",name:"move down"},{predicates:{isTextView:true},pointer:"commands/movement#moveLeft",ep:"command",key:"left",name:"move left"},
{predicates:{isTextView:true},pointer:"commands/movement#moveRight",ep:"command",key:"right",name:"move right"},{predicates:{completing:false,isTextView:true},pointer:"commands/movement#moveUp",ep:"command",key:"up",name:"move up"},{predicates:{isTextView:true},ep:"command",name:"select"},{predicates:{isTextView:true},pointer:"commands/movement#selectDown",ep:"command",key:"shift_down",name:"select down"},{predicates:{isTextView:true},pointer:"commands/movement#selectLeft",ep:"command",key:"shift_left",
name:"select left"},{predicates:{isTextView:true},pointer:"commands/movement#selectRight",ep:"command",key:"shift_right",name:"select right"},{predicates:{isTextView:true},pointer:"commands/movement#selectUp",ep:"command",key:"shift_up",name:"select up"},{predicates:{isTextView:true},pointer:"commands/movement#moveLineEnd",ep:"command",key:["end","ctrl_right"],name:"move lineend"},{predicates:{isTextView:true},pointer:"commands/movement#selectLineEnd",ep:"command",key:["shift_end","ctrl_shift_right"],
name:"select lineend"},{predicates:{isTextView:true},pointer:"commands/movement#moveDocEnd",ep:"command",key:"ctrl_down",name:"move docend"},{predicates:{isTextView:true},pointer:"commands/movement#selectDocEnd",ep:"command",key:"ctrl_shift_down",name:"select docend"},{predicates:{isTextView:true},pointer:"commands/movement#moveLineStart",ep:"command",key:["home","ctrl_left"],name:"move linestart"},{predicates:{isTextView:true},pointer:"commands/movement#selectLineStart",ep:"command",key:["shift_home",
"ctrl_shift_left"],name:"select linestart"},{predicates:{isTextView:true},pointer:"commands/movement#moveDocStart",ep:"command",key:"ctrl_up",name:"move docstart"},{predicates:{isTextView:true},pointer:"commands/movement#selectDocStart",ep:"command",key:"ctrl_shift_up",name:"select docstart"},{predicates:{isTextView:true},pointer:"commands/movement#moveNextWord",ep:"command",key:["alt_right"],name:"move nextword"},{predicates:{isTextView:true},pointer:"commands/movement#selectNextWord",ep:"command",
key:["alt_shift_right"],name:"select nextword"},{predicates:{isTextView:true},pointer:"commands/movement#movePreviousWord",ep:"command",key:["alt_left"],name:"move prevword"},{predicates:{isTextView:true},pointer:"commands/movement#selectPreviousWord",ep:"command",key:["alt_shift_left"],name:"select prevword"},{predicates:{isTextView:true},pointer:"commands/movement#selectAll",ep:"command",key:["ctrl_a","meta_a"],name:"select all"},{predicates:{isTextView:true},ep:"command",name:"scroll"},{predicates:{isTextView:true},
pointer:"commands/scrolling#scrollDocStart",ep:"command",key:"ctrl_home",name:"scroll start"},{predicates:{isTextView:true},pointer:"commands/scrolling#scrollDocEnd",ep:"command",key:"ctrl_end",name:"scroll end"},{predicates:{isTextView:true},pointer:"commands/scrolling#scrollPageDown",ep:"command",key:"pagedown",name:"scroll down"},{predicates:{isTextView:true},pointer:"commands/scrolling#scrollPageUp",ep:"command",key:"pageup",name:"scroll up"},{pointer:"commands/editor#lcCommand",description:"Change all selected text to lowercase",
withKey:"CMD SHIFT L",ep:"command",name:"lc"},{pointer:"commands/editor#detabCommand",description:"Convert tabs to spaces.",params:[{defaultValue:null,type:"text",name:"tabsize",description:"Optionally, specify a tab size. (Defaults to setting.)"}],ep:"command",name:"detab"},{pointer:"commands/editor#entabCommand",description:"Convert spaces to tabs.",params:[{defaultValue:null,type:"text",name:"tabsize",description:"Optionally, specify a tab size. (Defaults to setting.)"}],ep:"command",name:"entab"},
{pointer:"commands/editor#trimCommand",description:"trim trailing or leading whitespace from each line in selection",params:[{defaultValue:"both",type:{data:[{name:"left"},{name:"right"},{name:"both"}],name:"selection"},name:"side",description:"Do we trim from the left, right or both"}],ep:"command",name:"trim"},{pointer:"commands/editor#ucCommand",description:"Change all selected text to uppercase",withKey:"CMD SHIFT U",ep:"command",name:"uc"},{predicates:{isTextView:true},pointer:"controllers/undo#undoManagerCommand",
ep:"command",key:["ctrl_shift_z"],name:"redo"},{predicates:{isTextView:true},pointer:"controllers/undo#undoManagerCommand",ep:"command",key:["ctrl_z"],name:"undo"},{description:"The distance in characters between each tab",defaultValue:8,type:"number",ep:"setting",name:"tabstop"},{description:"Customize the keymapping",defaultValue:"{}",type:"text",ep:"setting",name:"customKeymapping"},{description:"The keymapping to use",defaultValue:"standard",type:"text",ep:"setting",name:"keymapping"},{description:"The editor font size in pixels",
defaultValue:14,type:"number",ep:"setting",name:"fontsize"},{description:"The editor font face",defaultValue:"Monaco, Lucida Console, monospace",type:"text",ep:"setting",name:"fontface"},{defaultValue:{color:"#e5c138",paddingLeft:5,backgroundColor:"#4c4a41",paddingRight:10},ep:"themevariable",name:"gutter"},{defaultValue:{color:"#e6e6e6",selectedTextBackgroundColor:"#526da5",backgroundColor:"#2a211c",cursorColor:"#879aff",unfocusedCursorBackgroundColor:"#73171e",unfocusedCursorColor:"#ff0033"},ep:"themevariable",
name:"editor"},{defaultValue:{comment:"#666666",directive:"#999999",keyword:"#42A8ED",plain:"#e6e6e6",error:"#ff0000",operator:"#88BBFF",identifier:"#D841FF",string:"#039A0A"},ep:"themevariable",name:"highlighter"},{defaultValue:{nibStrokeStyle:"rgb(150, 150, 150)",fullAlpha:1,barFillStyle:"rgb(0, 0, 0)",particalAlpha:0.3,barFillGradientBottomStop:"rgb(44, 44, 44)",backgroundStyle:"#2A211C",thickness:17,padding:5,trackStrokeStyle:"rgb(150, 150, 150)",nibArrowStyle:"rgb(255, 255, 255)",barFillGradientBottomStart:"rgb(22, 22, 22)",
barFillGradientTopStop:"rgb(40, 40, 40)",barFillGradientTopStart:"rgb(90, 90, 90)",nibStyle:"rgb(100, 100, 100)",trackFillStyle:"rgba(50, 50, 50, 0.8)"},ep:"themevariable",name:"scroller"},{description:"Event: Notify when something within the editor changed.",params:[{required:true,name:"pointer",description:"Function that is called whenever a change happened."}],ep:"extensionpoint",name:"editorChange"}],type:"plugins/supported",name:"text_editor"},less:{resourceURL:"resources/less/",description:"Leaner CSS",
contributors:[],author:"Alexis Sellier <self@cloudhead.net>",url:"http://lesscss.org",version:"1.0.11",dependencies:{},testmodules:[],provides:[],keywords:["css","parser","lesscss","browser"],type:"plugins/thirdparty",name:"less"},theme_manager_base:{resourceURL:"resources/theme_manager_base/",name:"theme_manager_base",share:true,environments:{main:true},dependencies:{},testmodules:[],provides:[{description:"(Less)files holding the CSS style information for the UI.",params:[{required:true,name:"url",
description:"Name of the ThemeStylesFile - can also be an array of files."}],ep:"extensionpoint",name:"themestyles"},{description:"Event: Notify when the theme(styles) changed.",params:[{required:true,name:"pointer",description:"Function that is called whenever the theme is changed."}],ep:"extensionpoint",name:"themeChange"},{indexOn:"name",description:"A theme is a way change the look of the application.",params:[{required:false,name:"url",description:"Name of a ThemeStylesFile that holds theme specific CSS rules - can also be an array of files."},
{required:true,name:"pointer",description:"Function that returns the ThemeData"}],ep:"extensionpoint",name:"theme"}],type:"plugins/supported",description:"Defines extension points required for theming"},canon:{resourceURL:"resources/canon/",name:"canon",environments:{main:true,worker:false},dependencies:{environment:"0.0.0",events:"0.0.0",settings:"0.0.0"},testmodules:[],provides:[{indexOn:"name",description:"A command is a bit of functionality with optional typed arguments which can do something small like moving the cursor around the screen, or large like cloning a project from VCS.",
ep:"extensionpoint",name:"command"},{description:"An extension point to be called whenever a new command begins output.",ep:"extensionpoint",name:"addedRequestOutput"},{description:"A dimensionsChanged is a way to be notified of changes to the dimension of Bespin",ep:"extensionpoint",name:"dimensionsChanged"},{description:"How many typed commands do we recall for reference?",defaultValue:50,type:"number",ep:"setting",name:"historyLength"},{action:"create",pointer:"history#InMemoryHistory",ep:"factory",
name:"history"}],type:"plugins/supported",description:"Manages commands"},traits:{resourceURL:"resources/traits/",description:"Traits library, traitsjs.org",dependencies:{},testmodules:[],provides:[],type:"plugins/thirdparty",name:"traits"},keyboard:{resourceURL:"resources/keyboard/",description:"Keyboard shortcuts",dependencies:{canon:"0.0",settings:"0.0"},testmodules:["tests/testKeyboard"],provides:[{description:"A keymapping defines how keystrokes are interpreted.",params:[{required:true,name:"states",
description:"Holds the states and all the informations about the keymapping. See docs: pluginguide/keymapping"}],ep:"extensionpoint",name:"keymapping"}],type:"plugins/supported",name:"keyboard"},worker_manager:{resourceURL:"resources/worker_manager/",description:"Manages a web worker on the browser side",dependencies:{canon:"0.0.0",events:"0.0.0",underscore:"0.0.0"},testmodules:[],provides:[{description:"Low-level web worker control (for plugin development)",ep:"command",name:"worker"},{description:"Restarts all web workers (for plugin development)",
pointer:"#workerRestartCommand",ep:"command",name:"worker restart"}],type:"plugins/supported",name:"worker_manager"},edit_session:{resourceURL:"resources/edit_session/",description:"Ties together the files being edited with the views on screen",dependencies:{events:"0.0.0"},testmodules:["tests/testSession"],provides:[{action:"call",pointer:"#createSession",ep:"factory",name:"session"}],type:"plugins/supported",name:"edit_session"},syntax_manager:{resourceURL:"resources/syntax_manager/",name:"syntax_manager",
environments:{main:true,worker:false},dependencies:{worker_manager:"0.0.0",events:"0.0.0",underscore:"0.0.0",syntax_directory:"0.0.0"},testmodules:[],provides:[],type:"plugins/supported",description:"Provides syntax highlighting services for the editor"},completion:{resourceURL:"resources/completion/",description:"Code completion support",dependencies:{jquery:"0.0.0",ctags:"0.0.0",rangeutils:"0.0.0",canon:"0.0.0",underscore:"0.0.0"},testmodules:[],provides:[{indexOn:"name",description:"Code completion support for specific languages",
ep:"extensionpoint",name:"completion"},{description:"Accept the chosen completion",key:["return","tab"],predicates:{completing:true},pointer:"controller#completeCommand",ep:"command",name:"complete"},{description:"Abandon the completion",key:"escape",predicates:{completing:true},pointer:"controller#completeCancelCommand",ep:"command",name:"complete cancel"},{description:"Choose the completion below",key:"down",predicates:{completing:true},pointer:"controller#completeDownCommand",ep:"command",name:"complete down"},
{description:"Choose the completion above",key:"up",predicates:{completing:true},pointer:"controller#completeUpCommand",ep:"command",name:"complete up"}],type:"plugins/supported",name:"completion"},environment:{testmodules:[],dependencies:{settings:"0.0.0"},resourceURL:"resources/environment/",name:"environment",type:"plugins/supported"},undomanager:{resourceURL:"resources/undomanager/",description:"Manages undoable events",testmodules:["tests/testUndomanager"],provides:[{pointer:"#undoManagerCommand",
ep:"command",key:["ctrl_shift_z"],name:"redo"},{pointer:"#undoManagerCommand",ep:"command",key:["ctrl_z"],name:"undo"}],type:"plugins/supported",name:"undomanager"},rangeutils:{testmodules:["tests/test"],type:"plugins/supported",resourceURL:"resources/rangeutils/",description:"Utility functions for dealing with ranges of text",name:"rangeutils"},stylesheet:{resourceURL:"resources/stylesheet/",name:"stylesheet",environments:{worker:true},dependencies:{standard_syntax:"0.0.0"},testmodules:[],provides:[{pointer:"#CSSSyntax",
ep:"syntax",fileexts:["css","less"],name:"css"}],type:"plugins/supported",description:"CSS syntax highlighter"},html:{resourceURL:"resources/html/",name:"html",environments:{worker:true},dependencies:{standard_syntax:"0.0.0"},testmodules:[],provides:[{pointer:"#HTMLSyntax",ep:"syntax",fileexts:["htm","html"],name:"html"}],type:"plugins/supported",description:"HTML syntax highlighter"},js_syntax:{resourceURL:"resources/js_syntax/",name:"js_syntax",environments:{worker:true},dependencies:{standard_syntax:"0.0.0"},
testmodules:[],provides:[{pointer:"#JSSyntax",ep:"syntax",fileexts:["js","json"],name:"js"}],type:"plugins/supported",description:"JavaScript syntax highlighter"},ctags:{resourceURL:"resources/ctags/",description:"Reads and writes tag files",dependencies:{traits:"0.0.0",underscore:"0.0.0"},testmodules:[],type:"plugins/supported",name:"ctags"},events:{resourceURL:"resources/events/",description:"Dead simple event implementation",dependencies:{traits:"0.0"},testmodules:["tests/test"],provides:[],type:"plugins/supported",
name:"events"},theme_manager:{resourceURL:"resources/theme_manager/",name:"theme_manager",share:true,environments:{main:true,worker:false},dependencies:{theme_manager_base:"0.0.0",settings:"0.0.0",events:"0.0.0",less:"0.0.0"},testmodules:[],provides:[{unregister:"themestyles#unregisterThemeStyles",register:"themestyles#registerThemeStyles",ep:"extensionhandler",name:"themestyles"},{unregister:"index#unregisterTheme",register:"index#registerTheme",ep:"extensionhandler",name:"theme"},{defaultValue:"standard",
description:"The theme plugin's name to use. If set to 'standard' no theme will be used",type:"text",ep:"setting",name:"theme"},{pointer:"#appLaunched",ep:"appLaunched"}],type:"plugins/supported",description:"Handles colors in Bespin"},standard_syntax:{resourceURL:"resources/standard_syntax/",description:"Easy-to-use basis for syntax engines",environments:{worker:true},dependencies:{syntax_worker:"0.0.0",syntax_directory:"0.0.0",underscore:"0.0.0"},testmodules:[],type:"plugins/supported",name:"standard_syntax"},
types:{resourceURL:"resources/types/",description:"Defines parameter types for commands",testmodules:["tests/testBasic","tests/testTypes"],provides:[{indexOn:"name",description:"Commands can accept various arguments that the user enters or that are automatically supplied by the environment. Those arguments have types that define how they are supplied or completed. The pointer points to an object with methods convert(str value) and getDefault(). Both functions have `this` set to the command's `takes` parameter. If getDefault is not defined, the default on the command's `takes` is used, if there is one. The object can have a noInput property that is set to true to reflect that this type is provided directly by the system. getDefault must be defined in that case.",
ep:"extensionpoint",name:"type"},{description:"Text that the user needs to enter.",pointer:"basic#text",ep:"type",name:"text"},{description:"A JavaScript number",pointer:"basic#number",ep:"type",name:"number"},{description:"A true/false value",pointer:"basic#bool",ep:"type",name:"boolean"},{description:"An object that converts via JavaScript",pointer:"basic#object",ep:"type",name:"object"},{description:"A string that is constrained to be one of a number of pre-defined values",pointer:"basic#selection",
ep:"type",name:"selection"},{description:"A type which we don't understand from the outset, but which we hope context can help us with",ep:"type",name:"deferred"}],type:"plugins/supported",name:"types"},jquery:{testmodules:[],resourceURL:"resources/jquery/",name:"jquery",type:"plugins/thirdparty"},embedded:{testmodules:[],dependencies:{theme_manager:"0.0.0",text_editor:"0.0.0",appconfig:"0.0.0",edit_session:"0.0.0",screen_theme:"0.0.0"},resourceURL:"resources/embedded/",name:"embedded",type:"plugins/supported"},
settings:{resourceURL:"resources/settings/",description:"Infrastructure and commands for managing user preferences",share:true,dependencies:{types:"0.0"},testmodules:[],provides:[{description:"Storage for the customizable Bespin settings",pointer:"index#settings",ep:"appcomponent",name:"settings"},{indexOn:"name",description:"A setting is something that the application offers as a way to customize how it works",register:"index#addSetting",ep:"extensionpoint",name:"setting"},{description:"A settingChange is a way to be notified of changes to a setting",
ep:"extensionpoint",name:"settingChange"},{pointer:"commands#setCommand",description:"define and show settings",params:[{defaultValue:null,type:{pointer:"settings:index#getSettings",name:"selection"},name:"setting",description:"The name of the setting to display or alter"},{defaultValue:null,type:{pointer:"settings:index#getTypeSpecFromAssignment",name:"deferred"},name:"value",description:"The new value for the chosen setting"}],ep:"command",name:"set"},{pointer:"commands#unsetCommand",description:"unset a setting entirely",
params:[{type:{pointer:"settings:index#getSettings",name:"selection"},name:"setting",description:"The name of the setting to return to defaults"}],ep:"command",name:"unset"}],type:"plugins/supported",name:"settings"},appconfig:{resourceURL:"resources/appconfig/",description:"Instantiates components and displays the GUI based on configuration.",dependencies:{jquery:"0.0.0",canon:"0.0.0",settings:"0.0.0"},testmodules:[],provides:[{description:"Event: Fired when the app is completely launched.",ep:"extensionpoint",
name:"appLaunched"}],type:"plugins/supported",name:"appconfig"},syntax_worker:{resourceURL:"resources/syntax_worker/",description:"Coordinates multiple syntax engines",environments:{worker:true},dependencies:{syntax_directory:"0.0.0",underscore:"0.0.0"},testmodules:[],type:"plugins/supported",name:"syntax_worker"},screen_theme:{resourceURL:"resources/screen_theme/",description:"Bespins standard theme basePlugin",dependencies:{theme_manager:"0.0.0"},testmodules:[],provides:[{url:["theme.less"],ep:"themestyles"},
{defaultValue:"@global_font",ep:"themevariable",name:"container_font"},{defaultValue:"@global_font_size",ep:"themevariable",name:"container_font_size"},{defaultValue:"@global_container_background",ep:"themevariable",name:"container_bg"},{defaultValue:"@global_color",ep:"themevariable",name:"container_color"},{defaultValue:"@global_line_height",ep:"themevariable",name:"container_line_height"},{defaultValue:"@global_pane_background",ep:"themevariable",name:"pane_bg"},{defaultValue:"@global_pane_border_radius",
ep:"themevariable",name:"pane_border_radius"},{defaultValue:"@global_form_font",ep:"themevariable",name:"form_font"},{defaultValue:"@global_form_font_size",ep:"themevariable",name:"form_font_size"},{defaultValue:"@global_form_line_height",ep:"themevariable",name:"form_line_height"},{defaultValue:"@global_form_color",ep:"themevariable",name:"form_color"},{defaultValue:"@global_form_text_shadow",ep:"themevariable",name:"form_text_shadow"},{defaultValue:"@global_pane_link_color",ep:"themevariable",name:"pane_a_color"},
{defaultValue:"@global_font",ep:"themevariable",name:"pane_font"},{defaultValue:"@global_font_size",ep:"themevariable",name:"pane_font_size"},{defaultValue:"@global_pane_text_shadow",ep:"themevariable",name:"pane_text_shadow"},{defaultValue:"@global_pane_h1_font",ep:"themevariable",name:"pane_h1_font"},{defaultValue:"@global_pane_h1_font_size",ep:"themevariable",name:"pane_h1_font_size"},{defaultValue:"@global_pane_h1_color",ep:"themevariable",name:"pane_h1_color"},{defaultValue:"@global_font_size * 1.8",
ep:"themevariable",name:"pane_line_height"},{defaultValue:"@global_pane_color",ep:"themevariable",name:"pane_color"},{defaultValue:"@global_text_shadow",ep:"themevariable",name:"pane_text_shadow"},{defaultValue:"@global_font",ep:"themevariable",name:"button_font"},{defaultValue:"@global_font_size",ep:"themevariable",name:"button_font_size"},{defaultValue:"@global_button_color",ep:"themevariable",name:"button_color"},{defaultValue:"@global_button_background",ep:"themevariable",name:"button_bg"},{defaultValue:"@button_bg - #063A27",
ep:"themevariable",name:"button_bg2"},{defaultValue:"@button_bg - #194A5E",ep:"themevariable",name:"button_border"},{defaultValue:"@global_control_background",ep:"themevariable",name:"control_bg"},{defaultValue:"@global_control_color",ep:"themevariable",name:"control_color"},{defaultValue:"@global_control_border",ep:"themevariable",name:"control_border"},{defaultValue:"@global_control_border_radius",ep:"themevariable",name:"control_border_radius"},{defaultValue:"@global_control_active_background",
ep:"themevariable",name:"control_active_bg"},{defaultValue:"@global_control_active_border",ep:"themevariable",name:"control_active_border"},{defaultValue:"@global_control_active_color",ep:"themevariable",name:"control_active_color"},{defaultValue:"@global_control_active_inset_color",ep:"themevariable",name:"control_active_inset_color"}],type:"plugins/supported",name:"screen_theme"}})})})();
(function(){var y=bespin.tiki.require("jquery").$,s=function(v,r,l){v=v.style[l]||document.defaultView.getComputedStyle(v,"").getPropertyValue(l);if(!v||v=="auto"||v=="intrinsic")v=r.style[l];return v};bespin.useBespin=function(v,r){var l=bespin.tiki.require("bespin:util/util"),h={},d=h.settings;r=r||{};for(var f in r)h[f]=r[f];r=h.settings;if(d!==undefined)for(f in d)if(r[f]===undefined)h.settings[f]=d[f];var m=null,i=new (bespin.tiki.require("bespin:promise").Promise);bespin.tiki.require.ensurePackage("::appconfig",
function(){var g=bespin.tiki.require("appconfig");if(l.isString(v))v=document.getElementById(v);if(l.none(h.initialContent))h.initialContent=v.value||v.innerHTML;v.innerHTML="";if(v.type=="textarea"){var j=v.parentNode,q=document.createElement("div"),t=function(){var C="position:relative;";["margin-top","margin-left","margin-right","margin-bottom"].forEach(function(L){C+=L+":"+s(v,q,L)+";"});var e=s(v,q,"width"),K=s(v,q,"height");C+="height:"+K+";width:"+e+";";C+="display:inline-block;";q.setAttribute("style",
C)};window.addEventListener("resize",t,false);t();for(v.nextSibling?j.insertBefore(q,v.nextSibling):j.appendChild(q);j!==document;){if(j.tagName.toUpperCase()==="FORM"){var B=j.onsubmit;j.onsubmit=function(C){v.value=m.editor.value;v.innerHTML=m.editor.value;B&&B.call(this,C)};break}j=j.parentNode}v.style.display="none";h.element=q;if(!l.none(v.getAttribute("readonly")))h.readOnly=true}else h.element=v;g.launch(h).then(function(C){m=C;i.resolve(C)})});return i};y(document).ready(function(){for(var v=
[],r=document.querySelectorAll(".bespin"),l=0;l<r.length;l++){var h=r[l],d=h.getAttribute("data-bespinoptions")||"{}";d=bespin.useBespin(h,JSON.parse(d));d.then(function(f){h.bespin=f},function(f){throw new Error("Launch failed: "+f);});v.push(d)}if(window.onBespinLoad){r=bespin.tiki.require("bespin:promise").group;r(v).then(function(){window.onBespinLoad()},function(){throw new Error("At least one Bespin failed to launch!");})}})})();

Просмотреть файл

@ -0,0 +1,31 @@
bespin.tiki.register("::syntax_worker",{name:"syntax_worker",dependencies:{syntax_directory:"0.0.0",underscore:"0.0.0"}});
bespin.tiki.module("syntax_worker:index",function(b,f){var c=b("bespin:promise"),d=b("underscore")._;b("bespin:console");var a=b("syntax_directory").syntaxDirectory;f.syntaxWorker={engines:{},annotate:function(e,m){function n(i){return i.split(":")}function o(){p.push(d(g).invoke("join",":").join(" "))}var l=this.engines,p=[],j=[],q=[],g=d(e.split(" ")).map(n);d(m).each(function(i){o();for(var r=[],t={},k=0;k<i.length;){for(var s;;){s=d(g).last();if(s.length<3)break;var h=s[2];if(i.substring(k,k+
h.length)!==h)break;g.pop()}h=l[s[0]].get(s,i,k);if(h==null)k={state:"plain",tag:"plain",start:k,end:i.length};else{g[g.length-1]=h.state;h.hasOwnProperty("newContext")&&g.push(h.newContext);k=h.token;h=h.symbol;if(h!=null)t["-"+h[0]]=h[1]}r.push(k);k=k.end}j.push(r);q.push(t)});o();return{states:p,attrs:j,symbols:q}},loadSyntax:function(e){var m=new c.Promise,n=this.engines;if(n.hasOwnProperty(e)){m.resolve();return m}var o=a.get(e);if(o==null)throw new Error('No syntax engine installed for syntax "'+
e+'".');o.extension.load().then(function(l){n[e]=l;l=l.subsyntaxes;l==null?m.resolve():c.group(d(l).map(this.loadSyntax,this)).then(d(m.resolve).bind(m))}.bind(this));return m}}});bespin.tiki.register("::stylesheet",{name:"stylesheet",dependencies:{standard_syntax:"0.0.0"}});
bespin.tiki.module("stylesheet:index",function(b,f){b("bespin:promise");b=b("standard_syntax").StandardSyntax;var c={regex:/^\/\/.*/,tag:"comment"},d=function(a){return[{regex:/^[^*\/]+/,tag:"comment"},{regex:/^\*\//,tag:"comment",then:a},{regex:/^[*\/]/,tag:"comment"}]};c={start:[{regex:/^([a-zA-Z-\s]*)(?:\:)/,tag:"identifier",then:"style"},{regex:/^([\w]+)(?![a-zA-Z0-9_:])([,|{]*?)(?!;)(?!(;|%))/,tag:"keyword",then:"header"},{regex:/^#([a-zA-Z]*)(?=.*{*?)/,tag:"keyword",then:"header"},{regex:/^\.([a-zA-Z]*)(?=.*{*?)/,
tag:"keyword",then:"header"},c,{regex:/^\/\*/,tag:"comment",then:"comment"},{regex:/^./,tag:"plain"}],header:[{regex:/^[^{|\/\/|\/\*]*/,tag:"keyword",then:"start"},c,{regex:/^\/\*/,tag:"comment",then:"comment_header"}],style:[{regex:/^[^;|}|\/\/|\/\*]+/,tag:"plain"},{regex:/^;|}/,tag:"plain",then:"start"},c,{regex:/^\/\*/,tag:"comment",then:"comment_style"}],comment:d("start"),comment_header:d("header"),comment_style:d("style")};f.CSSSyntax=new b(c)});bespin.tiki.register("::html",{name:"html",dependencies:{standard_syntax:"0.0.0"}});
bespin.tiki.module("html:index",function(b,f){b=b("standard_syntax").StandardSyntax;var c={},d=function(a,e){c[a+"_beforeAttrName"]=[{regex:/^\s+/,tag:"plain"},{regex:/^\//,tag:"operator",then:a+"_selfClosingStartTag"},{regex:/^>/,tag:"operator",then:e},{regex:/^./,tag:"keyword",then:a+"_attrName"}];c[a+"_attrName"]=[{regex:/^\s+/,tag:"plain",then:a+"_afterAttrName"},{regex:/^\//,tag:"operator",then:a+"_selfClosingStartTag"},{regex:/^=/,tag:"operator",then:a+"_beforeAttrValue"},{regex:/^>/,tag:"operator",
then:e},{regex:/^["'<]+/,tag:"error"},{regex:/^[^ \t\n\/=>"'<]+/,tag:"keyword"}];c[a+"_afterAttrName"]=[{regex:/^\s+/,tag:"plain"},{regex:/^\//,tag:"operator",then:a+"_selfClosingStartTag"},{regex:/^=/,tag:"operator",then:a+"_beforeAttrValue"},{regex:/^>/,tag:"operator",then:e},{regex:/^./,tag:"keyword",then:a+"_attrName"}];c[a+"_beforeAttrValue"]=[{regex:/^\s+/,tag:"plain"},{regex:/^"/,tag:"string",then:a+"_attrValueQQ"},{regex:/^(?=&)/,tag:"plain",then:a+"_attrValueU"},{regex:/^'/,tag:"string",
then:a+"_attrValueQ"},{regex:/^>/,tag:"error",then:e},{regex:/^./,tag:"string",then:a+"_attrValueU"}];c[a+"_attrValueQQ"]=[{regex:/^"/,tag:"string",then:a+"_afterAttrValueQ"},{regex:/^[^"]+/,tag:"string"}];c[a+"_attrValueQ"]=[{regex:/^'/,tag:"string",then:a+"_afterAttrValueQ"},{regex:/^[^']+/,tag:"string"}];c[a+"_attrValueU"]=[{regex:/^\s/,tag:"string",then:a+"_beforeAttrName"},{regex:/^>/,tag:"operator",then:e},{regex:/[^ \t\n>]+/,tag:"string"}];c[a+"_afterAttrValueQ"]=[{regex:/^\s/,tag:"plain",
then:a+"_beforeAttrName"},{regex:/^\//,tag:"operator",then:a+"_selfClosingStartTag"},{regex:/^>/,tag:"operator",then:e},{regex:/^(?=.)/,tag:"operator",then:a+"_beforeAttrName"}];c[a+"_selfClosingStartTag"]=[{regex:/^>/,tag:"operator",then:"start"},{regex:/^./,tag:"error",then:a+"_beforeAttrName"}]};c={start:[{regex:/^[^<]+/,tag:"plain"},{regex:/^<!--/,tag:"comment",then:"commentStart"},{regex:/^<!/,tag:"directive",then:"markupDeclarationOpen"},{regex:/^<\?/,tag:"comment",then:"bogusComment"},{regex:/^</,
tag:"operator",then:"tagOpen"}],tagOpen:[{regex:/^\//,tag:"operator",then:"endTagOpen"},{regex:/^script/i,tag:"keyword",then:"script_beforeAttrName"},{regex:/^[a-zA-Z]/,tag:"keyword",then:"tagName"},{regex:/^(?=.)/,tag:"plain",then:"start"}],scriptData:[{regex:/^<(?=\/script>)/i,tag:"operator",then:"tagOpen"},{regex:/^[^<]+/,tag:"plain"}],endTagOpen:[{regex:/^[a-zA-Z]/,tag:"keyword",then:"tagName"},{regex:/^>/,tag:"error",then:"start"},{regex:/^./,tag:"error",then:"bogusComment"}],tagName:[{regex:/^\s+/,
tag:"plain",then:"normal_beforeAttrName"},{regex:/^\//,tag:"operator",then:"normal_selfClosingStartTag"},{regex:/^>/,tag:"operator",then:"start"},{regex:/^[^ \t\n\/>]+/,tag:"keyword"}],bogusComment:[{regex:/^[^>]+/,tag:"comment"},{regex:/^>/,tag:"comment",then:"start"}],markupDeclarationOpen:[{regex:/^doctype/i,tag:"directive",then:"doctype"},{regex:/^(?=.)/,tag:"comment",then:"bogusComment"}],commentStart:[{regex:/^--\>/,tag:"comment",then:"start"},{regex:/^[^-]+/,tag:"comment"}],doctype:[{regex:/^\s/,
tag:"plain",then:"beforeDoctypeName"},{regex:/^./,tag:"error",then:"beforeDoctypeName"}],beforeDoctypeName:[{regex:/^\s+/,tag:"plain"},{regex:/^>/,tag:"error",then:"start"},{regex:/^./,tag:"directive",then:"doctypeName"}],doctypeName:[{regex:/^\s/,tag:"plain",then:"afterDoctypeName"},{regex:/^>/,tag:"directive",then:"start"},{regex:/^[^ \t\n>]+/,tag:"directive"}],afterDoctypeName:[{regex:/^\s+/,tag:"directive"},{regex:/^>/,tag:"directive",then:"start"},{regex:/^public/i,tag:"directive",then:"afterDoctypePublicKeyword"},
{regex:/^system/i,tag:"directive",then:"afterDoctypeSystemKeyword"},{regex:/^./,tag:"error",then:"bogusDoctype"}],afterDoctypePublicKeyword:[{regex:/^\s+/,tag:"plain",then:"beforeDoctypePublicId"},{regex:/^"/,tag:"error",then:"doctypePublicIdQQ"},{regex:/^'/,tag:"error",then:"doctypePublicIdQ"},{regex:/^>/,tag:"error",then:"start"},{regex:/^./,tag:"error",then:"bogusDoctype"}],beforeDoctypePublicId:[{regex:/^\s+/,tag:"plain"},{regex:/^"/,tag:"string",then:"doctypePublicIdQQ"},{regex:/^'/,tag:"string",
then:"doctypePublicIdQ"},{regex:/^>/,tag:"error",then:"start"},{regex:/^./,tag:"error",then:"bogusDoctype"}],doctypePublicIdQQ:[{regex:/^"/,tag:"string",then:"afterDoctypePublicId"},{regex:/^>/,tag:"error",then:"start"},{regex:/^[^>"]+/,tag:"string"}],doctypePublicIdQ:[{regex:/^'/,tag:"string",then:"afterDoctypePublicId"},{regex:/^>/,tag:"error",then:"start"},{regex:/^[^>']+/,tag:"string"}],afterDoctypePublicId:[{regex:/^\s/,tag:"plain",then:"betweenDoctypePublicAndSystemIds"},{regex:/^>/,tag:"directive",
then:"start"},{regex:/^"/,tag:"error",then:"doctypeSystemIdQQ"},{regex:/^'/,tag:"error",then:"doctypeSystemIdQ"},{regex:/^./,tag:"error",then:"bogusDoctype"}],betweenDoctypePublicAndSystemIds:[{regex:/^\s+/,tag:"plain",then:"betweenDoctypePublicAndSystemIds"},{regex:/^>/,tag:"directive",then:"start"},{regex:/^"/,tag:"string",then:"doctypeSystemIdQQ"},{regex:/^'/,tag:"string",then:"doctypeSystemIdQ"},{regex:/^./,tag:"error",then:"bogusDoctype"}],afterDoctypeSystemKeyword:[{regex:/^\s/,tag:"plain",
then:"beforeDoctypeSystemId"},{regex:/^"/,tag:"error",then:"doctypeSystemIdQQ"},{regex:/^'/,tag:"error",then:"doctypeSystemIdQ"},{regex:/^>/,tag:"error",then:"start"},{regex:/^./,tag:"error",then:"bogusDoctype"}],beforeDoctypeSystemId:[{regex:/^\s+/,tag:"plain",then:"beforeDoctypeSystemId"},{regex:/^"/,tag:"string",then:"doctypeSystemIdQQ"},{regex:/^'/,tag:"string",then:"doctypeSystemIdQ"},{regex:/^>/,tag:"error",then:"start"},{regex:/./,tag:"error",then:"bogusDoctype"}],doctypeSystemIdQQ:[{regex:/^"/,
tag:"string",then:"afterDoctypeSystemId"},{regex:/^>/,tag:"error",then:"start"},{regex:/^[^">]+/,tag:"string"}],doctypeSystemIdQ:[{regex:/^'/,tag:"string",then:"afterDoctypeSystemId"},{regex:/^>/,tag:"error",then:"start"},{regex:/^[^'>]+/,tag:"string"}],afterDoctypeSystemId:[{regex:/^\s+/,tag:"plain"},{regex:/^>/,tag:"directive",then:"start"},{regex:/^./,tag:"error",then:"bogusDoctype"}],bogusDoctype:[{regex:/^>/,tag:"directive",then:"start"},{regex:/^[^>]+/,tag:"directive"}]};d("normal","start");
d("script","start js:start:<\/script>");f.HTMLSyntax=new b(c,["js"])});bespin.tiki.register("::js_syntax",{name:"js_syntax",dependencies:{standard_syntax:"0.0.0"}});
bespin.tiki.module("js_syntax:index",function(b,f){b=b("standard_syntax").StandardSyntax;f.JSSyntax=new b({start:[{regex:/^var(?=\s*([A-Za-z_$][A-Za-z0-9_$]*)\s*=\s*require\s*\(\s*['"]([^'"]*)['"]\s*\)\s*[;,])/,tag:"keyword",symbol:"$1:$2"},{regex:/^(?:break|case|catch|continue|default|delete|do|else|false|finally|for|function|if|in|instanceof|let|new|null|return|switch|this|throw|true|try|typeof|var|void|while|with)(?![a-zA-Z0-9_])/,tag:"keyword"},{regex:/^[A-Za-z_][A-Za-z0-9_]*/,tag:"plain"},{regex:/^[^'"\/ \tA-Za-z0-9_]+/,
tag:"plain"},{regex:/^[ \t]+/,tag:"plain"},{regex:/^'(?=.)/,tag:"string",then:"qstring"},{regex:/^"(?=.)/,tag:"string",then:"qqstring"},{regex:/^\/\/.*/,tag:"comment"},{regex:/^\/\*/,tag:"comment",then:"comment"},{regex:/^./,tag:"plain"}],qstring:[{regex:/^(?:\\.|[^'\\])*'?/,tag:"string",then:"start"}],qqstring:[{regex:/^(?:\\.|[^"\\])*"?/,tag:"string",then:"start"}],comment:[{regex:/^[^*\/]+/,tag:"comment"},{regex:/^\*\//,tag:"comment",then:"start"},{regex:/^[*\/]/,tag:"comment"}]})});
bespin.tiki.register("::standard_syntax",{name:"standard_syntax",dependencies:{syntax_worker:"0.0.0",syntax_directory:"0.0.0",underscore:"0.0.0"}});
bespin.tiki.module("standard_syntax:index",function(b,f){b("bespin:promise");var c=b("underscore")._;b("bespin:console");b("syntax_directory");f.StandardSyntax=function(d,a){this.states=d;this.subsyntaxes=a};f.StandardSyntax.prototype={get:function(d,a,e){var m=d[0],n=d[1];if(!this.states.hasOwnProperty(n))throw new Error('StandardSyntax: no such state "'+n+'"');var o=a.substring(e),l={start:e,state:d},p=null;c(this.states[n]).each(function(j){var q=j.regex.exec(o);if(q!=null){var g=q[0].length;l.end=
e+g;l.tag=j.tag;var i=null;if(j.hasOwnProperty("symbol")){i=/^([^:]+):(.*)/.exec(j.symbol.replace(/\$([0-9]+)/g,function(t,k){return q[k]}));i=[i[1],i[2]]}var r=null;if(j.hasOwnProperty("then")){g=j.then.split(" ");j=[m,g[0]];if(g.length>1)r=g[1].split(":")}else if(g===0)throw new Error("StandardSyntax: Infinite loop detected: zero-length match that didn't change state");else j=d;p={state:j,token:l,symbol:i};if(r!=null)p.newContext=r;c.breakLoop()}});return p}}});
bespin.metadata={js_syntax:{resourceURL:"resources/js_syntax/",name:"js_syntax",environments:{worker:true},dependencies:{standard_syntax:"0.0.0"},testmodules:[],provides:[{pointer:"#JSSyntax",ep:"syntax",fileexts:["js","json"],name:"js"}],type:"plugins/supported",description:"JavaScript syntax highlighter"},stylesheet:{resourceURL:"resources/stylesheet/",name:"stylesheet",environments:{worker:true},dependencies:{standard_syntax:"0.0.0"},testmodules:[],provides:[{pointer:"#CSSSyntax",ep:"syntax",fileexts:["css",
"less"],name:"css"}],type:"plugins/supported",description:"CSS syntax highlighter"},syntax_worker:{resourceURL:"resources/syntax_worker/",description:"Coordinates multiple syntax engines",environments:{worker:true},dependencies:{syntax_directory:"0.0.0",underscore:"0.0.0"},testmodules:[],type:"plugins/supported",name:"syntax_worker"},standard_syntax:{resourceURL:"resources/standard_syntax/",description:"Easy-to-use basis for syntax engines",environments:{worker:true},dependencies:{syntax_worker:"0.0.0",
syntax_directory:"0.0.0",underscore:"0.0.0"},testmodules:[],type:"plugins/supported",name:"standard_syntax"},html:{resourceURL:"resources/html/",name:"html",environments:{worker:true},dependencies:{standard_syntax:"0.0.0"},testmodules:[],provides:[{pointer:"#HTMLSyntax",ep:"syntax",fileexts:["htm","html"],name:"html"}],type:"plugins/supported",description:"HTML syntax highlighter"}};
if(typeof window!=="undefined")throw new Error('"worker.js can only be loaded in a web worker. Use the "worker_manager" plugin to instantiate web workers.');var messageQueue=[],target=null;if(typeof bespin==="undefined")bespin={};
function pump(){if(messageQueue.length!==0){var b=messageQueue[0];switch(b.op){case "load":var f=b.base;bespin.base=f;bespin.hasOwnProperty("tiki")||importScripts(f+"tiki.js");if(!bespin.bootLoaded){importScripts(f+"plugin/register/boot");bespin.bootLoaded=true}var c=bespin.tiki.require;c.loader.sources[0].xhr=true;c.ensurePackage("::bespin",function(){var a=c("bespin:plugins").catalog,e=c("bespin:promise").Promise;if(bespin.hasOwnProperty("metadata")){a.registerMetadata(bespin.metadata);a=new e;
a.resolve()}else a=a.loadMetadataFromURL("plugin/register/worker");a.then(function(){c.ensurePackage(b.pkg,function(){target=c(b.module)[b.target];messageQueue.shift();pump()})})});break;case "invoke":f=function(a){postMessage(JSON.stringify({op:"finish",id:b.id,result:a}));messageQueue.shift();pump()};if(!target.hasOwnProperty(b.method))throw new Error("No such method: "+b.method);var d=target[b.method].apply(target,b.args);typeof d==="object"&&d.isPromise?d.then(f,function(a){throw a;}):f(d);break}}}
onmessage=function(b){messageQueue.push(JSON.parse(b.data));messageQueue.length===1&&pump()};

Просмотреть файл

@ -0,0 +1,268 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Bespin.
*
* The Initial Developer of the Original Code is
* Mozilla.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bespin Team (bespin@mozilla.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
.bespin {
.container {
font-family: @container_font;
font-size: @container_font_size;
color: @container_color;
background: @container_bg;
line-height: @container_line_height;
display: -moz-box;
-moz-box-orient: vertical;
display: -webkit-box;
-webkit-box-orient: vertical;
width: 100%;
height: 100%;
margin: 0;
}
.container .north {
-moz-box-ordinal-group: 1;
-webkit-box-ordinal-group: 1;
}
.container .center-container {
display: -moz-box;
-moz-box-orient: horizontal;
-moz-box-ordinal-group: 2;
-moz-box-flex: 1;
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-ordinal-group: 2;
-webkit-box-flex: 1;
}
.container .south {
-moz-box-ordinal-group: 3;
-webkit-box-ordinal-group: 3;
}
.container .center-container .west {
-moz-box-ordinal-group: 1;
-webkit-box-ordinal-group: 1;
}
.container .center-container .center {
-moz-box-flex: 1;
-moz-box-ordinal-group: 2;
-webkit-box-flex: 1;
-webkit-box-ordinal-group: 2;
}
.container .center-container .east {
-moz-box-ordinal-group: 3;
-webkit-box-ordinal-group: 3;
}
input, textarea {
display: block;
border: 0px;
width: 200px;
padding: 4px;
color: @control_color;
background: @control_bg;
border: @control_border;
font-size: 8pt;
-moz-border-radius: @control_border_radius;
-webkit-border-radius: @control_border_radius;
box-shadow:
rgba(255,255,255,0.3) 0px 0px 2px,
inset rgba(0,0,0,0.3) 0px 0px 4px;
-moz-box-shadow:
rgba(255,255,255,0.3) 0px 0px 2px,
inset rgba(0,0,0,0.3) 0px 0px 4px;
-webkit-box-shadow:
rgba(255,255,255,0.3) 0px 0px 2px,
inset rgba(0,0,0,0.3) 0px 0px 4px;
}
input:focus, textarea:focus {
color: @control_active_color;
border: @control_active_border;
background: @control_active_bg;
outline: none;
box-shadow: opacity(@control_active_inset_color, 0.6) 0px 0px 2px,
inset opacity(@control_active_inset_color, 0.3) 0px 0px 6px;
-moz-box-shadow: opacity(@control_active_inset_color, 0.6) 0px 0px 2px,
inset opacity(@control_active_inset_color, 0.3) 0px 0px 6px;
-webkit-box-shadow: opacity(@control_active_inset_color, 0.6) 0px 0px 2px,
inset opacity(@control_active_inset_color, 0.3) 0px 0px 6px;
}
input[type=submit], input[type=button] {
font-family: @button_font;
font-size: @button_font_size;
text-shadow: 1px 1px rgba(0, 0, 0, 0.4);
padding: 8px 12px;
margin-left: 8px;
color: @button_color;
background: transparent -moz-linear-gradient(top, @button_bg, @button_bg2);
background: transparent -webkit-gradient(linear, 50% 0%, 50% 100%, from(@button_bg), to(@button_bg2));
border: 1px solid @button_border;
-moz-border-radius: @control_border_radius;
-webkit-border-radius: @control_border_radius;
-moz-box-shadow:
inset rgba(255, 255, 255, 0.2) 0 1px 0px,
inset rgba(0, 0, 0, 0.2) 0 -1px 0px,
rgba(0, 0, 0, 0.1) 0px 1px 2px;
-webkit-box-shadow:
inset rgba(255, 255, 255, 0.2) 0 1px 0px,
inset rgba(0, 0, 0, 0.2) 0 -1px 0px,
rgba(0, 0, 0, 0.1) 0px 1px 2px;
box-shadow:
inset rgba(255, 255, 255, 0.2) 0 1px 0px,
inset rgba(0, 0, 0, 0.2) 0 -1px 0px,
rgba(0, 0, 0, 0.1) 0px 1px 2px;
}
.pane {
font-size: @pane_font_size;
font-family: @pane_font;
border-top: 1px solid rgba(255,255,255,0.1);
border-left: 1px solid rgba(0, 0, 0, 0.1);
border-right: 1px solid rgba(0, 0, 0, 0.1);
border-bottom: 2px solid rgba(0, 0, 0, 0.1);
background-color: @pane_bg;
overflow: visible;
padding: 15px;
color: @pane_color;
line-height: @pane_line_height;
margin-bottom: 6px;
margin-top: 6px;
text-shadow: @pane_text_shadow;
-moz-border-radius: @pane_border_radius;
-webkit-border-radius: @pane_border_radius;
-moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 2px;
-webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 2px;
a {
color: @pane_a_color;
}
h1 {
font-family: @pane_h1_font;
font-size: @pane_h1_font_size;
color: @pane_h1_color;
letter-spacing: -1.25px;
line-height: 1.0;
margin-top: 0px;
margin-left: 10px;
margin-bottom: 25px;
margin-top: 10px;
text-shadow: @pane_text_shadow;
}
p {
margin-left: 10px;
}
}
.form {
font-family: @form_font;
font-size: @form_font_size;
line-height: @form_line_height;
color: @form_color;
text-shadow: @form_text_shadow;
fieldset, p {
color: @form_color;
margin-bottom: 6px;
margin-top: 6px;
text-shadow: form_text_shadow;
}
}
/*
* The state classes are a little bit complex, because of the doubble class bug in IE6
* The state class looks like this:
*
* .ui-radio-state[-checked][-disabled][-hover] or .ui-checkbox-state[-checked][-disabled][-hover]
*
* Examples:
*
* .ui-radio-state-checked (simply checked)
* .ui-radio-state-checked-hover (checked and hovered/focused)
* .ui-radio-state-hover (unchecked and hovered/focused)
*
* If you don´t have to deal with the doubble class bug of IE6 you can also use the simple ui-checkbox-checked, ui-checkbox-disabled, ui-checkbox-hover state-classnames (or: ui-radio-checked...)
* and the ui-radio/ui-checkbox role-classnames.
*
*/
span.ui-checkbox,
span.ui-radio {
display: block;
float: left;
width: 24px;
height: 24px;
background: url(images/radio-unselected.png) no-repeat;
}
span.ui-checkbox {
background: url(images/check-unselected.png) no-repeat;
}
span.ui-helper-hidden {
display: none;
}
span.ui-checkbox-state-checked,
span.ui-checkbox-state-checked-hover {
background: url(images/check-selected.png) no-repeat;
}
span.ui-radio-state-checked,
span.ui-radio-state-checked-hover {
background: url(images/radio-selected.png) no-repeat;
}
.ui-helper-hidden-accessible {
position: absolute;
left: -999em;
}
}

Просмотреть файл

@ -0,0 +1,152 @@
var editor = {
index : 0,
tabs : [],
currentTab : null,
tempCount : 0,
resize : function(width, height) {
if(width)
this.width = width;
if(height)
this.height = height;
if(this.currentTab) {
$(this.currentTab.editorElement).width(this.width);
$(this.currentTab.editorElement).height(this.height);
this.currentTab.editorEnv.dimensionsChanged();
}
},
switchTab : function(index) {
if(index == undefined)
index = this.tabs.length - 1;
if(index < 0)
return;
var tabSelect = document.getElementById("editor-tab-select");
tabSelect.selectedIndex = index;
if(this.currentTab)
$(this.currentTab.editorElement).hide();
this.index = index;
this.currentTab = this.tabs[index];
this.resize();
$(this.currentTab.editorElement).show();
this.currentTab.editor.focus = true;
this.currentTab.editorEnv.dimensionsChanged()
},
closeCurrentTab : function() {
this.currentTab.destroy();
this.currentTab = '';
this.tabs.splice(this.index, 1);
var tabSelect = document.getElementById("editor-tab-select");
var option = tabSelect.getElementsByTagName("option")[this.index];
tabSelect.removeChild(option);
this.switchTab();
},
getTabForFile : function(filename) {
for(var i = 0; i < this.tabs.length; i++) {
if(this.tabs[i].filename == filename)
return i;
}
return -1;
},
openNew : function(content, filename) {
if(!filename) {
this.tempCount++;
filename = utils.tempfile("mozmill.utils.temp" + this.tempCount).path;
var tabName = "temp " + this.tempCount;
}
else
var tabName = getBasename(filename);
var option = $('<option></option>').val(this.tabs.length - 1).html(tabName);
$("#editor-tab-select").append(option);
var newTab = new editorTab(content, filename);
this.tabs.push(newTab);
// will switch to tab when it has loaded
},
getContent : function() {
return this.currentTab.getContent();
},
setContent : function(content) {
this.currentTab.setContent(content);
},
getFilename : function() {
return this.currentTab.filename;
},
showFilename : function(filename) {
$("#editor-tab-select option").eq(editor.index).html(filename);
},
changeFilename : function(filename) {
this.currentTab.filename = filename;
this.showFilename(getBasename(filename));
},
onFileChanged : function() {
var selected = $("#editor-tab-select :selected");
selected.html(selected.html().replace("*", "")).append("*");
// remove listener until saving to prevent typing slow down
editor.currentTab.editor.textChanged.remove(editor.onFileChanged);
},
onFileSaved : function() {
var selected = $("#editor-tab-select :selected");
selected.html(selected.html().replace("*", ""));
editor.currentTab.editor.textChanged.add(editor.onFileChanged);
}
}
function editorTab(content, filename) {
var elem = $("<pre></pre>").addClass("bespin").appendTo("#editors");
elem.val(content);
var bespinElement = elem.get(0);
var editorObject = this;
bespin.useBespin(bespinElement, {
settings: {"tabstop": 4},
syntax: "js",
stealFocus: true})
.then(function(env) {
editorObject.editorEnv = env;
editorObject.editor = env.editor;
env.editor.textChanged.add(editor.onFileChanged);
editor.switchTab();
env.settings.set("fontsize", 13);
});
this.editorElement = bespinElement;
this.filename = filename;
}
editorTab.prototype = {
setContent : function(content) {
this.editor.value = content;
},
getContent : function() {
return this.editor.value;
},
destroy : function() {
this.editorElement.parentNode.removeChild(this.editorElement);
}
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.1 KiB

Просмотреть файл

@ -0,0 +1,63 @@
var utils = {}; Components.utils.import('resource://mozmill/modules/utils.js', utils);
var showFileDialog = function(){
$("#fileDialog").dialog("open");
}
var showTestDialog = function(){
$("#testDialog").dialog("open");
}
var showOptionDialog = function(){
$("#optionDialog").dialog("open");
}
var showHelpDialog = function(){
$("#helpDialog").dialog("open");
}
var showRecordDialog = function(){
$("#tabs").tabs().tabs("select", 0);
$("#recordDialog").dialog("open");
MozMillrec.on();
$("#recordDialog").dialog().parents(".ui-dialog:first").find(".ui-dialog-buttonpane button")[1].innerHTML = "Stop";
}
//Align mozmill to all the other open windows in a way that makes it usable
var align = function(){
var enumerator = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator)
.getEnumerator("");
while(enumerator.hasMoreElements()) {
var win = enumerator.getNext();
if (win.document.title != 'MozMill IDE'){
var wintype = win.document.documentElement.getAttribute("windowtype");
//move to top left corner
win.screenY = 0;
win.screenX = 0;
//make only browser windows big
if (wintype == "navigator:browser"){
var width = window.screen.availWidth/2.5;
var height = window.screen.availHeight;
win.resizeTo((window.screen.availWidth - width), window.screen.availHeight);
}
}
else {
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var latestbrowser = wm.getMostRecentWindow('navigator:browser');
//if there is no most recent browser window, use whatever window
if (!latestbrowser){
var latestbrowser = wm.getMostRecentWindow('');
}
win.screenX = latestbrowser.innerWidth;
win.screenY = 0;
}
}
return true;
};

Просмотреть файл

@ -0,0 +1,114 @@
/* Styles for jQuery menu widget
Author: Maggie Wachs, maggie@filamentgroup.com
Date: September 2008
*/
/* REQUIRED STYLES - the menus will only render correctly with these rules */
.fg-menu-container { position: absolute; top:0; left:-999px; padding: .4em; overflow: hidden; }
.fg-menu-container.fg-menu-flyout { overflow: visible; }
.fg-menu, .fg-menu ul { list-style-type:none; padding: 0; margin:0; }
.fg-menu { position:relative; }
.fg-menu-flyout .fg-menu { position:static; }
.fg-menu ul { position:absolute; top:0; }
.fg-menu ul ul { top:-1px; }
.fg-menu-container.fg-menu-ipod .fg-menu-content,
.fg-menu-container.fg-menu-ipod .fg-menu-content ul { background: none !important; }
.fg-menu.fg-menu-scroll,
.fg-menu ul.fg-menu-scroll { overflow: scroll; overflow-x: hidden; }
.fg-menu li { clear:both; float:left; width:100%; margin: 0; padding:0; border: 0; }
.fg-menu li li { font-size:1em; } /* inner li font size must be reset so that they don't blow up */
.fg-menu-flyout ul ul { padding: .4em; }
.fg-menu-flyout li { position:relative; }
.fg-menu-scroll { overflow: scroll; overflow-x: hidden; }
.fg-menu-breadcrumb { margin: 0; padding: 0; }
.fg-menu-footer { margin-top: .4em; padding: .4em; }
.fg-menu-header { margin-bottom: .4em; padding: .4em; }
.fg-menu-breadcrumb li { float: left; list-style: none; margin: 0; padding: 0 .2em; font-size: .9em; opacity: .7; }
.fg-menu-breadcrumb li.fg-menu-prev-list,
.fg-menu-breadcrumb li.fg-menu-current-crumb { clear: left; float: none; opacity: 1; }
.fg-menu-breadcrumb li.fg-menu-current-crumb { padding-top: .2em; }
.fg-menu-breadcrumb a,
.fg-menu-breadcrumb span { float: left; }
.fg-menu-footer a:link,
.fg-menu-footer a:visited { float:left; width:100%; text-decoration: none; }
.fg-menu-footer a:hover,
.fg-menu-footer a:active { }
.fg-menu-footer a span { float:left; cursor: pointer; }
.fg-menu-breadcrumb .fg-menu-prev-list a:link,
.fg-menu-breadcrumb .fg-menu-prev-list a:visited,
.fg-menu-breadcrumb .fg-menu-prev-list a:hover,
.fg-menu-breadcrumb .fg-menu-prev-list a:active { background-image: none; text-decoration:none; }
.fg-menu-breadcrumb .fg-menu-prev-list a { float: left; padding-right: .4em; }
.fg-menu-breadcrumb .fg-menu-prev-list a .ui-icon { float: left; }
.fg-menu-breadcrumb .fg-menu-current-crumb a:link,
.fg-menu-breadcrumb .fg-menu-current-crumb a:visited,
.fg-menu-breadcrumb .fg-menu-current-crumb a:hover,
.fg-menu-breadcrumb .fg-menu-current-crumb a:active { display:block; background-image:none; font-size:1.3em; text-decoration:none; }
/* REQUIRED LINK STYLES: links are "display:block" by default; if the menu options are split into
selectable node links and 'next' links, the script floats the node links left and floats the 'next' links to the right */
.fg-menu a:link,
.fg-menu a:visited,
.fg-menu a:hover,
.fg-menu a:active { float:left; width:92%; padding:.3em 3%; text-decoration:none; outline: 0 !important; }
.fg-menu a { border: 1px dashed transparent; }
.fg-menu a.ui-state-default:link,
.fg-menu a.ui-state-default:visited,
.fg-menu a.ui-state-default:hover,
.fg-menu a.ui-state-default:active,
.fg-menu a.ui-state-hover:link,
.fg-menu a.ui-state-hover:visited,
.fg-menu a.ui-state-hover:hover,
.fg-menu a.ui-state-hover:active,
.fg-menu a.ui-state-active:link,
.fg-menu a.ui-state-active:visited,
.fg-menu a.ui-state-active:hover,
.fg-menu a.ui-state-active:active { border-style: solid; font-weight: normal; }
.fg-menu a span { display:block; cursor:pointer; }
/* SUGGESTED STYLES - for use with jQuery UI Themeroller CSS */
.fg-menu-indicator span { float:left; }
.fg-menu-indicator span.ui-icon { float:right; }
.fg-menu-content.ui-widget-content,
.fg-menu-content ul.ui-widget-content { border:0; }
/* ICONS AND DIVIDERS */
.fg-menu.fg-menu-has-icons a:link,
.fg-menu.fg-menu-has-icons a:visited,
.fg-menu.fg-menu-has-icons a:hover,
.fg-menu.fg-menu-has-icons a:active { padding-left:20px; }
.fg-menu .horizontal-divider hr, .fg-menu .horizontal-divider span { padding:0; margin:5px .6em; }
.fg-menu .horizontal-divider hr { border:0; height:1px; }
.fg-menu .horizontal-divider span { font-size:.9em; text-transform: uppercase; padding-left:.2em; }

Просмотреть файл

@ -0,0 +1,510 @@
/*--------------------------------------------------------------------
Scripts for creating and manipulating custom menus based on standard <ul> markup
Version: 3.0, 03.31.2009
By: Maggie Costello Wachs (maggie@filamentgroup.com) and Scott Jehl (scott@filamentgroup.com)
http://www.filamentgroup.com
* reference articles: http://www.filamentgroup.com/lab/jquery_ipod_style_drilldown_menu/
Copyright (c) 2009 Filament Group
Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
--------------------------------------------------------------------*/
var allUIMenus = [];
$.fn.menu = function(options){
var caller = this;
var options = options;
var m = new Menu(caller, options);
allUIMenus.push(m);
$(this)
.mousedown(function(){
if (!m.menuOpen) { m.showLoading(); };
})
.click(function(){
if (m.menuOpen == false) { m.showMenu(); }
else { m.kill(); };
return false;
});
};
function Menu(caller, options){
var menu = this;
var caller = $(caller);
var container = $('<div class="fg-menu-container ui-widget ui-widget-content ui-corner-all">'+options.content+'</div>');
this.menuOpen = false;
this.menuExists = false;
caller.showMenu = this.showMenu; // for keyboard accessiblity
var options = jQuery.extend({
content: null,
width: 180, // width of menu container, must be set or passed in to calculate widths of child menus
maxHeight: 180, // max height of menu (if a drilldown: height does not include breadcrumb)
positionOpts: {
posX: 'left',
posY: 'bottom',
offsetX: 0,
offsetY: 0,
directionH: 'right',
directionV: 'down',
detectH: true, // do horizontal collision detection
detectV: true, // do vertical collision detection
linkToFront: false
},
showSpeed: 200, // show/hide speed in milliseconds
callerOnState: 'ui-state-active', // class to change the appearance of the link/button when the menu is showing
loadingState: 'ui-state-loading', // class added to the link/button while the menu is created
linkHover: 'ui-state-hover', // class for menu option hover state
linkHoverSecondary: 'li-hover', // alternate class, may be used for multi-level menus
// ----- multi-level menu defaults -----
crossSpeed: 200, // cross-fade speed for multi-level menus
crumbDefaultText: 'Choose an option:',
backLink: true, // in the ipod-style menu: instead of breadcrumbs, show only a 'back' link
backLinkText: 'Back',
flyOut: false, // multi-level menus are ipod-style by default; this parameter overrides to make a flyout instead
flyOutOnState: 'ui-state-default',
nextMenuLink: 'ui-icon-triangle-1-e', // class to style the link (specifically, a span within the link) used in the multi-level menu to show the next level
topLinkText: 'All',
nextCrumbLink: 'ui-icon-carat-1-e'
}, options);
var killAllMenus = function(){
$.each(allUIMenus, function(i){
if (allUIMenus[i].menuOpen) { allUIMenus[i].kill(); };
});
};
this.kill = function(){
caller
.removeClass(options.loadingState)
.removeClass('fg-menu-open')
.removeClass(options.callerOnState);
container.find('li').removeClass(options.linkHoverSecondary).find('a').removeClass(options.linkHover);
if (options.flyOutOnState) { container.find('li a').removeClass(options.flyOutOnState); };
if (options.callerOnState) { caller.removeClass(options.callerOnState); };
if (container.is('.fg-menu-ipod')) { menu.resetDrilldownMenu(); };
if (container.is('.fg-menu-flyout')) { menu.resetFlyoutMenu(); };
container.parent().hide();
menu.menuOpen = false;
$(document).unbind('click', killAllMenus);
$(document).unbind('keydown');
};
this.showLoading = function(){
caller.addClass(options.loadingState);
};
this.showMenu = function(){
killAllMenus();
if (!menu.menuExists) { menu.create() };
caller
.addClass('fg-menu-open')
.addClass(options.callerOnState);
container.parent().show().click(function(){ menu.kill(); return false; });
container.hide().slideDown(options.showSpeed).find('.fg-menu:eq(0)');
menu.menuOpen = true;
caller.removeClass(options.loadingState);
$(document).click(killAllMenus);
// assign key events
$(document).keydown(function(event){
var e;
if (event.which !="") { e = event.which; }
else if (event.charCode != "") { e = event.charCode; }
else if (event.keyCode != "") { e = event.keyCode; }
var menuType = ($(event.target).parents('div').is('.fg-menu-flyout')) ? 'flyout' : 'ipod' ;
switch(e) {
case 37: // left arrow
if (menuType == 'flyout') {
$(event.target).trigger('mouseout');
if ($('.'+options.flyOutOnState).size() > 0) { $('.'+options.flyOutOnState).trigger('mouseover'); };
};
if (menuType == 'ipod') {
$(event.target).trigger('mouseout');
if ($('.fg-menu-footer').find('a').size() > 0) { $('.fg-menu-footer').find('a').trigger('click'); };
if ($('.fg-menu-header').find('a').size() > 0) { $('.fg-menu-current-crumb').prev().find('a').trigger('click'); };
if ($('.fg-menu-current').prev().is('.fg-menu-indicator')) {
$('.fg-menu-current').prev().trigger('mouseover');
};
};
return false;
break;
case 38: // up arrow
if ($(event.target).is('.' + options.linkHover)) {
var prevLink = $(event.target).parent().prev().find('a:eq(0)');
if (prevLink.size() > 0) {
$(event.target).trigger('mouseout');
prevLink.trigger('mouseover');
};
}
else { container.find('a:eq(0)').trigger('mouseover'); }
return false;
break;
case 39: // right arrow
if ($(event.target).is('.fg-menu-indicator')) {
if (menuType == 'flyout') {
$(event.target).next().find('a:eq(0)').trigger('mouseover');
}
else if (menuType == 'ipod') {
$(event.target).trigger('click');
setTimeout(function(){
$(event.target).next().find('a:eq(0)').trigger('mouseover');
}, options.crossSpeed);
};
};
return false;
break;
case 40: // down arrow
if ($(event.target).is('.' + options.linkHover)) {
var nextLink = $(event.target).parent().next().find('a:eq(0)');
if (nextLink.size() > 0) {
$(event.target).trigger('mouseout');
nextLink.trigger('mouseover');
};
}
else { container.find('a:eq(0)').trigger('mouseover'); }
return false;
break;
case 27: // escape
killAllMenus();
break;
case 13: // enter
if ($(event.target).is('.fg-menu-indicator') && menuType == 'ipod') {
$(event.target).trigger('click');
setTimeout(function(){
$(event.target).next().find('a:eq(0)').trigger('mouseover');
}, options.crossSpeed);
};
break;
};
});
};
this.create = function(){
container.css({ width: options.width }).appendTo('body').find('ul:first').not('.fg-menu-breadcrumb').addClass('fg-menu');
container.find('ul, li a').addClass('ui-corner-all');
// aria roles & attributes
container.find('ul').attr('role', 'menu').eq(0).attr('aria-activedescendant','active-menuitem').attr('aria-labelledby', caller.attr('id'));
container.find('li').attr('role', 'menuitem');
container.find('li:has(ul)').attr('aria-haspopup', 'true').find('ul').attr('aria-expanded', 'false');
container.find('a').attr('tabindex', '-1');
// when there are multiple levels of hierarchy, create flyout or drilldown menu
if (container.find('ul').size() > 1) {
if (options.flyOut) { menu.flyout(container, options); }
else { menu.drilldown(container, options); }
}
else {
container.find('li').click(function(){ // Mozmill modified : 'a' to 'li'
menu.chooseItem(this);
return false;
});
};
if (options.linkHover) {
var allLinks = container.find('.fg-menu li a');
allLinks.hover(
function(){
var menuitem = $(this);
$('.'+options.linkHover).removeClass(options.linkHover).blur().parent().removeAttr('id');
$(this).addClass(options.linkHover).focus().parent().attr('id','active-menuitem');
},
function(){
$(this).removeClass(options.linkHover).blur().parent().removeAttr('id');
}
);
};
if (options.linkHoverSecondary) {
container.find('.fg-menu li').hover(
function(){
$(this).siblings('li').removeClass(options.linkHoverSecondary);
if (options.flyOutOnState) { $(this).siblings('li').find('a').removeClass(options.flyOutOnState); }
$(this).addClass(options.linkHoverSecondary);
},
function(){ $(this).removeClass(options.linkHoverSecondary); }
);
};
menu.setPosition(container, caller, options);
menu.menuExists = true;
};
this.chooseItem = function(item){
menu.kill();
// edit this for your own custom function/callback:
$('#menuSelection').text($(item).text());
// location.href = $(item).attr('href');
};
};
Menu.prototype.flyout = function(container, options) {
var menu = this;
this.resetFlyoutMenu = function(){
var allLists = container.find('ul ul');
allLists.removeClass('ui-widget-content').hide();
};
container.addClass('fg-menu-flyout').find('li:has(ul)').each(function(){
var linkWidth = container.width();
var showTimer, hideTimer;
var allSubLists = $(this).find('ul');
allSubLists.css({ left: linkWidth, width: linkWidth }).hide();
$(this).find('a:eq(0)').addClass('fg-menu-indicator').html('<span>' + $(this).find('a:eq(0)').text() + '</span><span class="ui-icon '+options.nextMenuLink+'"></span>').hover(
function(){
clearTimeout(hideTimer);
var subList = $(this).next();
if (!fitVertical(subList, $(this).offset().top)) { subList.css({ top: 'auto', bottom: 0 }); };
if (!fitHorizontal(subList, $(this).offset().left + 100)) { subList.css({ left: 'auto', right: linkWidth, 'z-index': 999 }); };
showTimer = setTimeout(function(){
subList.addClass('ui-widget-content').show(options.showSpeed).attr('aria-expanded', 'true');
}, 300);
},
function(){
clearTimeout(showTimer);
var subList = $(this).next();
hideTimer = setTimeout(function(){
subList.removeClass('ui-widget-content').hide(options.showSpeed).attr('aria-expanded', 'false');
}, 400);
}
);
$(this).find('ul a').hover(
function(){
clearTimeout(hideTimer);
if ($(this).parents('ul').prev().is('a.fg-menu-indicator')) {
$(this).parents('ul').prev().addClass(options.flyOutOnState);
}
},
function(){
hideTimer = setTimeout(function(){
allSubLists.hide(options.showSpeed);
container.find(options.flyOutOnState).removeClass(options.flyOutOnState);
}, 500);
}
);
});
container.find('a').click(function(){
menu.chooseItem(this);
return false;
});
};
/* Menu.prototype.setPosition parameters (defaults noted with *):
referrer = the link (or other element) used to show the overlaid object
settings = can override the defaults:
- posX/Y: where the top left corner of the object should be positioned in relation to its referrer.
X: left*, center, right
Y: top, center, bottom*
- offsetX/Y: the number of pixels to be offset from the x or y position. Can be a positive or negative number.
- directionH/V: where the entire menu should appear in relation to its referrer.
Horizontal: left*, right
Vertical: up, down*
- detectH/V: detect the viewport horizontally / vertically
- linkToFront: copy the menu link and place it on top of the menu (visual effect to make it look like it overlaps the object) */
Menu.prototype.setPosition = function(widget, caller, options) {
var el = widget;
var referrer = caller;
var dims = {
refX: referrer.offset().left,
refY: referrer.offset().top,
refW: referrer.getTotalWidth(),
refH: referrer.getTotalHeight()
};
var options = options;
var xVal, yVal;
var helper = $('<div class="positionHelper"></div>');
helper.css({ position: 'absolute', left: dims.refX, top: dims.refY, width: dims.refW, height: dims.refH });
el.wrap(helper);
// get X pos
switch(options.positionOpts.posX) {
case 'left': xVal = 0;
break;
case 'center': xVal = dims.refW / 2;
break;
case 'right': xVal = dims.refW;
break;
};
// get Y pos
switch(options.positionOpts.posY) {
case 'top': yVal = 0;
break;
case 'center': yVal = dims.refH / 2;
break;
case 'bottom': yVal = dims.refH;
break;
};
// add the offsets (zero by default)
xVal += options.positionOpts.offsetX;
yVal += options.positionOpts.offsetY;
// position the object vertically
if (options.positionOpts.directionV == 'up') {
el.css({ top: 'auto', bottom: yVal });
if (options.positionOpts.detectV && !fitVertical(el)) {
el.css({ bottom: 'auto', top: yVal });
}
}
else {
el.css({ bottom: 'auto', top: yVal });
if (options.positionOpts.detectV && !fitVertical(el)) {
el.css({ top: 'auto', bottom: yVal });
}
};
// and horizontally
if (options.positionOpts.directionH == 'left') {
el.css({ left: 'auto', right: xVal });
if (options.positionOpts.detectH && !fitHorizontal(el)) {
el.css({ right: 'auto', left: xVal });
}
}
else {
el.css({ right: 'auto', left: xVal });
if (options.positionOpts.detectH && !fitHorizontal(el)) {
el.css({ left: 'auto', right: xVal });
}
};
// if specified, clone the referring element and position it so that it appears on top of the menu
if (options.positionOpts.linkToFront) {
referrer.clone().addClass('linkClone').css({
position: 'absolute',
top: 0,
right: 'auto',
bottom: 'auto',
left: 0,
width: referrer.width(),
height: referrer.height()
}).insertAfter(el);
};
};
/* Utilities to sort and find viewport dimensions */
function sortBigToSmall(a, b) { return b - a; };
jQuery.fn.getTotalWidth = function(){
return $(this).width() + parseInt($(this).css('paddingRight')) + parseInt($(this).css('paddingLeft')) + parseInt($(this).css('borderRightWidth')) + parseInt($(this).css('borderLeftWidth'));
};
jQuery.fn.getTotalHeight = function(){
return $(this).height() + parseInt($(this).css('paddingTop')) + parseInt($(this).css('paddingBottom')) + parseInt($(this).css('borderTopWidth')) + parseInt($(this).css('borderBottomWidth'));
};
function getScrollTop(){
return self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
};
function getScrollLeft(){
return self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
};
function getWindowHeight(){
var de = document.documentElement;
return self.innerHeight || (de && de.clientHeight) || document.body.clientHeight;
};
function getWindowWidth(){
var de = document.documentElement;
return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
};
/* Utilities to test whether an element will fit in the viewport
Parameters:
el = element to position, required
leftOffset / topOffset = optional parameter if the offset cannot be calculated (i.e., if the object is in the DOM but is set to display: 'none') */
function fitHorizontal(el, leftOffset){
var leftVal = parseInt(leftOffset) || $(el).offset().left;
return (leftVal + $(el).width() <= getWindowWidth() + getScrollLeft() && leftVal - getScrollLeft() >= 0);
};
function fitVertical(el, topOffset){
var topVal = parseInt(topOffset) || $(el).offset().top;
return (topVal + $(el).height() <= getWindowHeight() + getScrollTop() && topVal - getScrollTop() >= 0);
};
/*--------------------------------------------------------------------
* javascript method: "pxToEm"
* by:
Scott Jehl (scott@filamentgroup.com)
Maggie Wachs (maggie@filamentgroup.com)
http://www.filamentgroup.com
*
* Copyright (c) 2008 Filament Group
* Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
*
* Description: Extends the native Number and String objects with pxToEm method. pxToEm converts a pixel value to ems depending on inherited font size.
* Article: http://www.filamentgroup.com/lab/retaining_scalable_interfaces_with_pixel_to_em_conversion/
* Demo: http://www.filamentgroup.com/examples/pxToEm/
*
* Options:
scope: string or jQuery selector for font-size scoping
reverse: Boolean, true reverses the conversion to em-px
* Dependencies: jQuery library
* Usage Example: myPixelValue.pxToEm(); or myPixelValue.pxToEm({'scope':'#navigation', reverse: true});
*
* Version: 2.0, 08.01.2008
* Changelog:
* 08.02.2007 initial Version 1.0
* 08.01.2008 - fixed font-size calculation for IE
--------------------------------------------------------------------*/
Number.prototype.pxToEm = String.prototype.pxToEm = function(settings){
//set defaults
settings = jQuery.extend({
scope: 'body',
reverse: false
}, settings);
var pxVal = (this == '') ? 0 : parseFloat(this);
var scopeVal;
var getWindowWidth = function(){
var de = document.documentElement;
return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
};
/* When a percentage-based font-size is set on the body, IE returns that percent of the window width as the font-size.
For example, if the body font-size is 62.5% and the window width is 1000px, IE will return 625px as the font-size.
When this happens, we calculate the correct body font-size (%) and multiply it by 16 (the standard browser font size)
to get an accurate em value. */
if (settings.scope == 'body' && $.browser.msie && (parseFloat($('body').css('font-size')) / getWindowWidth()).toFixed(1) > 0.0) {
var calcFontSize = function(){
return (parseFloat($('body').css('font-size'))/getWindowWidth()).toFixed(3) * 16;
};
scopeVal = calcFontSize();
}
else { scopeVal = parseFloat(jQuery(settings.scope).css("font-size")); };
var result = (settings.reverse == true) ? (pxVal * scopeVal).toFixed(2) + 'px' : (pxVal / scopeVal).toFixed(2) + 'em';
return result;
};

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -0,0 +1,557 @@
/*
* jQuery UI @VERSION
*
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://docs.jquery.com/UI
*/
;jQuery.ui || (function($) {
var _remove = $.fn.remove,
isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);
//Helper functions and ui object
$.ui = {
version: "@VERSION",
// $.ui.plugin is deprecated. Use the proxy pattern instead.
plugin: {
add: function(module, option, set) {
var proto = $.ui[module].prototype;
for(var i in set) {
proto.plugins[i] = proto.plugins[i] || [];
proto.plugins[i].push([option, set[i]]);
}
},
call: function(instance, name, args) {
var set = instance.plugins[name];
if(!set || !instance.element[0].parentNode) { return; }
for (var i = 0; i < set.length; i++) {
if (instance.options[set[i][0]]) {
set[i][1].apply(instance.element, args);
}
}
}
},
contains: function(a, b) {
return document.compareDocumentPosition
? a.compareDocumentPosition(b) & 16
: a !== b && a.contains(b);
},
hasScroll: function(el, a) {
//If overflow is hidden, the element might have extra content, but the user wants to hide it
if ($(el).css('overflow') == 'hidden') { return false; }
var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
has = false;
if (el[scroll] > 0) { return true; }
// TODO: determine which cases actually cause this to happen
// if the element doesn't have the scroll set, see if it's possible to
// set the scroll
el[scroll] = 1;
has = (el[scroll] > 0);
el[scroll] = 0;
return has;
},
isOverAxis: function(x, reference, size) {
//Determines when x coordinate is over "b" element axis
return (x > reference) && (x < (reference + size));
},
isOver: function(y, x, top, left, height, width) {
//Determines when x, y coordinates is over "b" element
return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
},
keyCode: {
BACKSPACE: 8,
CAPS_LOCK: 20,
COMMA: 188,
CONTROL: 17,
DELETE: 46,
DOWN: 40,
END: 35,
ENTER: 13,
ESCAPE: 27,
HOME: 36,
INSERT: 45,
LEFT: 37,
NUMPAD_ADD: 107,
NUMPAD_DECIMAL: 110,
NUMPAD_DIVIDE: 111,
NUMPAD_ENTER: 108,
NUMPAD_MULTIPLY: 106,
NUMPAD_SUBTRACT: 109,
PAGE_DOWN: 34,
PAGE_UP: 33,
PERIOD: 190,
RIGHT: 39,
SHIFT: 16,
SPACE: 32,
TAB: 9,
UP: 38
}
};
// WAI-ARIA normalization
if (isFF2) {
var attr = $.attr,
removeAttr = $.fn.removeAttr,
ariaNS = "http://www.w3.org/2005/07/aaa",
ariaState = /^aria-/,
ariaRole = /^wairole:/;
$.attr = function(elem, name, value) {
var set = value !== undefined;
return (name == 'role'
? (set
? attr.call(this, elem, name, "wairole:" + value)
: (attr.apply(this, arguments) || "").replace(ariaRole, ""))
: (ariaState.test(name)
? (set
? elem.setAttributeNS(ariaNS,
name.replace(ariaState, "aaa:"), value)
: attr.call(this, elem, name.replace(ariaState, "aaa:")))
: attr.apply(this, arguments)));
};
$.fn.removeAttr = function(name) {
return (ariaState.test(name)
? this.each(function() {
this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
}) : removeAttr.call(this, name));
};
}
//jQuery plugins
$.fn.extend({
_focus: $.fn.focus,
focus: function(delay, fn) {
return typeof delay === 'number'
? this.each(function() {
var elem = this;
setTimeout(function() {
$(elem).focus();
(fn && fn.call(elem));
}, delay);
})
: this._focus.apply(this, arguments);
},
remove: function() {
// Safari has a native remove event which actually removes DOM elements,
// so we have to use triggerHandler instead of trigger (#3037).
$("*", this).add(this).each(function() {
$(this).triggerHandler("remove");
});
return _remove.apply(this, arguments );
},
enableSelection: function() {
return this
.attr('unselectable', 'off')
.css('MozUserSelect', '')
.unbind('selectstart.ui');
},
disableSelection: function() {
return this
.attr('unselectable', 'on')
.css('MozUserSelect', 'none')
.bind('selectstart.ui', function() { return false; });
},
scrollParent: function() {
var scrollParent;
if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
scrollParent = this.parents().filter(function() {
return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
}).eq(0);
} else {
scrollParent = this.parents().filter(function() {
return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
}).eq(0);
}
return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
},
zIndex: function(zIndex) {
if (zIndex !== undefined) {
return this.css('zIndex', zIndex);
}
var elem = this[0];
while (elem && elem.style) {
// IE returns 0 when zIndex is not specified
// other browsers return an empty string
// we ignore the case of nested elements with an explicit value of 0
// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
if (elem.style.zIndex !== '' && elem.style.zIndex !== 0) {
return +elem.style.zIndex;
}
elem = elem.parentNode;
}
return 0;
}
});
//Additional selectors
$.extend($.expr[':'], {
data: function(elem, i, match) {
return !!$.data(elem, match[3]);
},
focusable: function(element) {
var nodeName = element.nodeName.toLowerCase(),
tabIndex = $.attr(element, 'tabindex');
return (/input|select|textarea|button|object/.test(nodeName)
? !element.disabled
: 'a' == nodeName || 'area' == nodeName
? element.href || !isNaN(tabIndex)
: !isNaN(tabIndex))
// the element and all of its ancestors must be visible
// the browser may report that the area is hidden
&& !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
},
tabbable: function(element) {
var tabIndex = $.attr(element, 'tabindex');
return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
}
});
// $.widget is a factory to create jQuery plugins
// taking some boilerplate code out of the plugin code
$.widget = function(name, prototype) {
var namespace = name.split(".")[0],
fullName;
name = name.split(".")[1];
fullName = namespace + '-' + name;
// create selector for plugin
$.expr[':'][fullName] = function(elem) {
return !!$.data(elem, name);
};
// create plugin method
$.fn[name] = function(options) {
var isMethodCall = (typeof options == 'string'),
args = Array.prototype.slice.call(arguments, 1),
returnValue = this;
// allow multiple hashes to be passed on init
options = !isMethodCall && args.length
? $.extend.apply(null, [true, options].concat(args))
: options;
// prevent calls to internal methods
if (isMethodCall && options.substring(0, 1) == '_') {
return returnValue;
}
(isMethodCall
? this.each(function() {
var instance = $.data(this, name),
methodValue = (instance && $.isFunction(instance[options])
? instance[options].apply(instance, args)
: instance);
if (methodValue !== instance && methodValue !== undefined) {
returnValue = methodValue;
return false;
}
})
: this.each(function() {
($.data(this, name) ||
$.data(this, name, new $[namespace][name](this, options))._init());
}));
return returnValue;
};
// create widget constructor
$[namespace] = $[namespace] || {};
$[namespace][name] = function(element, options) {
var self = this;
this.namespace = namespace;
this.widgetName = name;
this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
this.widgetBaseClass = fullName;
this.options = $.extend(true, {},
$.widget.defaults,
$[namespace][name].defaults,
$.metadata && $.metadata.get(element)[name],
options);
this.element = $(element)
.bind('setData.' + name, function(event, key, value) {
if (event.target == element) {
return self._setData(key, value);
}
})
.bind('getData.' + name, function(event, key) {
if (event.target == element) {
return self._getData(key);
}
})
.bind('remove.' + name, function() {
return self.destroy();
});
};
// add widget prototype
$[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
};
$.widget.prototype = {
_init: function() {},
destroy: function() {
this.element.removeData(this.widgetName)
.removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
.removeAttr('aria-disabled');
return this;
},
// override when the widget element is a wrapper or similar
widget: function() {
return this.element;
},
option: function(key, value) {
var options = key,
self = this;
if (typeof key == "string") {
if (value === undefined) {
return this._getData(key);
}
options = {};
options[key] = value;
}
$.each(options, function(key, value) {
self._setData(key, value);
});
return self;
},
_getData: function(key) {
return this.options[key];
},
_setData: function(key, value) {
this.options[key] = value;
if (key == 'disabled') {
this.element
[value ? 'addClass' : 'removeClass'](
this.widgetBaseClass + '-disabled' + ' ' +
this.namespace + '-state-disabled')
.attr("aria-disabled", value);
}
},
enable: function() {
this._setData('disabled', false);
return this;
},
disable: function() {
this._setData('disabled', true);
return this;
},
_trigger: function(type, event, data) {
var callback = this.options[type];
event = $.Event(event);
event.type = (type == this.widgetEventPrefix
? type : this.widgetEventPrefix + type).toLowerCase();
data = data || {};
// copy original event properties over to the new event
// this would happen if we could call $.event.fix instead of $.Event
// but we don't have a way to force an event to be fixed multiple times
if (event.originalEvent) {
for (var i = $.event.props.length, prop; i;) {
prop = $.event.props[--i];
event[prop] = event.originalEvent[prop];
}
}
this.element.trigger(event, data);
return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
|| event.isDefaultPrevented());
}
};
$.widget.defaults = {
disabled: false
};
/** Mouse Interaction Plugin **/
$.ui.mouse = {
_mouseInit: function() {
var self = this;
this.element
.bind('mousedown.'+this.widgetName, function(event) {
return self._mouseDown(event);
})
.bind('click.'+this.widgetName, function(event) {
if(self._preventClickEvent) {
self._preventClickEvent = false;
event.stopImmediatePropagation();
return false;
}
});
// Prevent text selection in IE
if ($.browser.msie) {
this._mouseUnselectable = this.element.attr('unselectable');
this.element.attr('unselectable', 'on');
}
this.started = false;
},
// TODO: make sure destroying one instance of mouse doesn't mess with
// other instances of mouse
_mouseDestroy: function() {
this.element.unbind('.'+this.widgetName);
// Restore text selection in IE
($.browser.msie
&& this.element.attr('unselectable', this._mouseUnselectable));
},
_mouseDown: function(event) {
// don't let more than one widget handle mouseStart
// TODO: figure out why we have to use originalEvent
event.originalEvent = event.originalEvent || {};
if (event.originalEvent.mouseHandled) { return; }
// we may have missed mouseup (out of window)
(this._mouseStarted && this._mouseUp(event));
this._mouseDownEvent = event;
var self = this,
btnIsLeft = (event.which == 1),
elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
return true;
}
this.mouseDelayMet = !this.options.delay;
if (!this.mouseDelayMet) {
this._mouseDelayTimer = setTimeout(function() {
self.mouseDelayMet = true;
}, this.options.delay);
}
if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
this._mouseStarted = (this._mouseStart(event) !== false);
if (!this._mouseStarted) {
event.preventDefault();
return true;
}
}
// these delegates are required to keep context
this._mouseMoveDelegate = function(event) {
return self._mouseMove(event);
};
this._mouseUpDelegate = function(event) {
return self._mouseUp(event);
};
$(document)
.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
// preventDefault() is used to prevent the selection of text here -
// however, in Safari, this causes select boxes not to be selectable
// anymore, so this fix is needed
($.browser.safari || event.preventDefault());
event.originalEvent.mouseHandled = true;
return true;
},
_mouseMove: function(event) {
// IE mouseup check - mouseup happened when mouse was out of window
if ($.browser.msie && !event.button) {
return this._mouseUp(event);
}
if (this._mouseStarted) {
this._mouseDrag(event);
return event.preventDefault();
}
if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
this._mouseStarted =
(this._mouseStart(this._mouseDownEvent, event) !== false);
(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
}
return !this._mouseStarted;
},
_mouseUp: function(event) {
$(document)
.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
if (this._mouseStarted) {
this._mouseStarted = false;
this._preventClickEvent = (event.target == this._mouseDownEvent.target);
this._mouseStop(event);
}
return false;
},
_mouseDistanceMet: function(event) {
return (Math.max(
Math.abs(this._mouseDownEvent.pageX - event.pageX),
Math.abs(this._mouseDownEvent.pageY - event.pageY)
) >= this.options.distance
);
},
_mouseDelayMet: function(event) {
return this.mouseDelayMet;
},
// These are placeholder methods, to be overriden by extending plugin
_mouseStart: function(event) {},
_mouseDrag: function(event) {},
_mouseStop: function(event) {},
_mouseCapture: function(event) { return true; }
};
$.ui.mouse.defaults = {
cancel: ':input,option',
distance: 1,
delay: 0
};
})(jQuery);

Просмотреть файл

@ -0,0 +1,173 @@
/*
* jQuery UI Menu @VERSION
*
* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://docs.jquery.com/UI/Menu
*
* Depends:
* jquery.ui.core.js
*/
(function($) {
$.widget("ui.menu", {
_init: function() {
var self = this;
this.element.attr("role", "menu")
.attr("aria-activedescendant", "ui-active-menuitem")
.addClass("ui-menu ui-widget ui-widget-content ui-corner-bottom")
.click(function(e) {
// temporary
e.preventDefault();
self.select();
});
var items = this.element.children("li");
items.addClass("ui-menu-item").attr("role", "menuitem")
.children("a").attr("tabindex", "-1").addClass("ui-corner-all")
// mouseenter doesn't work with event delegation
.mouseenter(function() {
self.activate($(this).parent());
});
},
activate: function(item) {
this.deactivate();
this.active = item.children("a").addClass("ui-state-hover").attr("id", "ui-active-menuitem").end();
this._trigger("focus", null, { item: item });
if (this.hasScroll()) {
var offset = item.offset().top - this.element.offset().top,
scroll = this.element.attr("scrollTop"),
elementHeight = this.element.height();
if (offset < 0) {
this.element.attr("scrollTop", scroll + offset);
} else if (offset > elementHeight) {
this.element.attr("scrollTop", scroll + offset - elementHeight + item.height());
}
}
},
deactivate: function() {
if (!this.active)
return;
this.active.children("a").removeClass("ui-state-hover").removeAttr("id", "ui-active-menuitem");
this.active = null;
},
next: function() {
this.move("next", "li:first");
},
previous: function() {
this.move("prev", "li:last");
},
first: function() {
return this.active && !this.active.prev().length;
},
last: function() {
return this.active && !this.active.next().length;
},
move: function(direction, edge) {
if (!this.active) {
this.activate(this.element.children(edge));
return;
}
var next = this.active[direction]();
if (next.length) {
this.activate(next);
} else {
this.activate(this.element.children(edge));
}
},
// TODO merge with previousPage
nextPage: function() {
if (this.hasScroll()) {
// TODO merge with no-scroll-else
if (!this.active || this.last()) {
this.activate(this.element.children(":first"));
return;
}
// last item on page, then scroll one page down, otherwise select last item on page
if (this.active && this.active.offset().top - this.element.offset().top + this.active.height() > this.element.height()) {
// last
var offsetBase = this.element.offset().top,
height = this.element.height();
var result = this.element.children("li").filter(function() {
var close = $(this).offset().top - offsetBase - height * 1.5 - $(this).height() / 2;
// TODO improve approximation
return close < 10 && close > -10;
})
// TODO try to catch this earlier when scrollTop indicates the last page anyway
if (!result.length)
result = this.element.children(":last")
this.activate(result);
} else {
// not last
var offsetBase = this.element.offset().top,
height = this.element.height();
var result = this.element.children("li").filter(function() {
var close = $(this).offset().top - offsetBase + $(this).height() - height;
// TODO improve approximation
return close < 10 && close > -10;
})
this.activate(result);
}
} else {
this.activate(this.element.children(!this.active || this.last() ? ":first" : ":last"));
}
},
// TODO merge with nextPage
previousPage: function() {
if (this.hasScroll()) {
// TODO merge with no-scroll-else
if (!this.active || this.first()) {
this.activate(this.element.children(":last"));
return;
}
// first item on page, then scroll one page up, otherwise select first item on page
if (this.active && this.active.offset().top - this.element.offset().top <= 1) {
// first
var offsetBase = this.element.offset().top,
height = this.element.height();
var result = this.element.children("li").filter(function() {
var close = $(this).offset().top - offsetBase + height / 2 + $(this).height() / 2;
// TODO improve approximation
return close < 10 && close > -10;
})
// TODO try to catch this earlier when scrollTop indicates the first page anyway
if (!result.length)
result = this.element.children(":first")
this.activate(result);
} else {
// not first
var offsetBase = this.element.offset().top,
height = this.element.height();
var result = this.element.children("li").filter(function() {
var close = $(this).offset().top - offsetBase;
// TODO improve approximation
return close < 10 && close > -10;
})
this.activate(result);
}
} else {
this.activate(this.element.children(!this.active || this.first() ? ":last" : ":first"));
}
},
hasScroll: function() {
return this.element.height() < this.element.attr("scrollHeight");
},
select: function() {
this._trigger("selected", null, { item: this.active });
}
});
})(jQuery);

Просмотреть файл

@ -0,0 +1,156 @@
// ***** BEGIN LICENSE BLOCK *****
// Version: MPL 1.1/GPL 2.0/LGPL 2.1
//
// The contents of this file are subject to the Mozilla Public License Version
// 1.1 (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// The Original Code is Mozilla Corporation Code.
//
// The Initial Developer of the Original Code is
// Adam Christian.
// Portions created by the Initial Developer are Copyright (C) 2008
// the Initial Developer. All Rights Reserved.
//
// Contributor(s):
// Adam Christian <adam.christian@gmail.com>
// Mikeal Rogers <mikeal.rogers@gmail.com>
//
// Alternatively, the contents of this file may be used under the terms of
// either the GNU General Public License Version 2 or later (the "GPL"), or
// the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
// in which case the provisions of the GPL or the LGPL are applicable instead
// of those above. If you wish to allow use of your version of this file only
// under the terms of either the GPL or the LGPL, and not to allow others to
// use your version of this file under the terms of the MPL, indicate your
// decision by deleting the provisions above and replace them with the notice
// and other provisions required by the GPL or the LGPL. If you do not delete
// the provisions above, a recipient may use your version of this file under
// the terms of any one of the MPL, the GPL or the LGPL.
//
// ***** END LICENSE BLOCK *****
var frame = {}; Components.utils.import('resource://mozmill/modules/frame.js', frame);
function getBasename(path){
var splt = "/"
if (navigator.platform.indexOf("Win") != -1){
splt = "\\";
}
var pathArr = path.split(splt);
return pathArr[pathArr.length-1]
}
function openFile(){
var openObj = utils.openFile(window);
if (openObj) {
$("#tabs").tabs("select", 0);
var index = editor.getTabForFile(openObj.path);
if(index != -1)
editor.switchTab(index);
else
editor.openNew(openObj.data, openObj.path);
}
}
function saveAsFile() {
var content = editor.getContent();
var filename = utils.saveAsFile(window, content);
if (filename) {
$("#tabs").tabs("select", 0);
editor.changeFilename(filename);
saveToFile();
return true;
}
return false;
}
function saveToFile() {
var filename = editor.getFilename();
var content = editor.getContent();
utils.saveFile(window, content, filename);
editor.onFileSaved();
}
function saveFile() {
var filename = editor.getFilename();
if(/mozmill\.utils\.temp/.test(filename))
saveAsFile();
else {
saveToFile();
}
}
function closeFile() {
$("#tabs").tabs("select", 0);
var really = confirm("Are you sure you want to close this file?");
if (really == true)
editor.closeCurrentTab();
}
function runFile(){
var nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
fp.init(window, "Select a File", nsIFilePicker.modeOpen);
fp.appendFilter("JavaScript Files","*.js");
var res = fp.show();
if (res == nsIFilePicker.returnOK){
$("#tabs").tabs("select", 1);
frame.runTestFile(fp.file.path, true);
}
testFinished();
}
function runDirectory(){
var nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
fp.init(window, "Select a Directory", nsIFilePicker.modeGetFolder);
var res = fp.show();
if (res == nsIFilePicker.returnOK){
$("#tabs").tabs("select", 1);
frame.runTestDirectory(fp.file.path, true);
}
testFinished();
}
function runEditor(){
saveToFile();
var filename = editor.getFilename();
frame.runTestFile(filename);
testFinished();
}
function newFile(){
editor.openNew();
}
function newTemplate(){
var template = "var setupModule = function(module) {\n" +
" module.controller = mozmill.getBrowserController();\n" +
"}\n" +
"\n" +
"var testFoo = function(){\n" +
" controller.open('http://www.google.com');\n" +
"}\n";
editor.openNew(template);
}
function tabSelected(selector) {
editor.switchTab(selector.selectedIndex);
}
function openHelp() {
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var browser = wm.getMostRecentWindow("navigator:browser").gBrowser;
browser.selectedTab =
browser.addTab("http://quality.mozilla.org/docs/mozmill/getting-started/");
}

Просмотреть файл

@ -0,0 +1,134 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>MozMill IDE</title>
<meta name="generator" content="TextMate http://macromates.com/">
<meta name="author" content="adam">
<!-- Date: 2009-02-03 -->
<link type="text/css" href="css/smoothness/jquery-ui-1.7.1.custom.css" rel="Stylesheet" />
<link type="text/css" href="css/mozmill.css" rel="Stylesheet" />
<link type="text/css" href="css/fg.menu.css" rel="Stylesheet"/>
<link id="bespin_base" href="editor/bespin">
<link href="editor/bespin/BespinEmbedded.css" type="text/css" rel="stylesheet">
<script type="text/javascript" src="editor/bespin/BespinEmbedded.js"></script>
<script src="mozmill.js"></script>
<script src="output.js"></script>
<script src="dx.js"></script>
<script src="rec.js"></script>
<script src="menus.js"></script>
<script src="editor/editor.js"></script>
<script src="jquery/jquery-1.3.2.min.js"></script>
<script src="jquery/jquery-ui-1.7.1.custom.min.js"></script>
<script src="ui.js"></script>
<script src="jquery/fg.menu.js"></script>
</head>
<body onload=""onunload="cleanUp();">
<script src="shortcuts.js"></script>
<script type="text/javascript">
var syncHeights = function() {
$('#tabs')[0].style.height = window.innerHeight - 8 + "px";
$('#resOut')[0].style.height = window.innerHeight - 150 + "px";
$('#shellOutput')[0].style.height = window.innerHeight - 200 + "px";
editor.resize(window.innerWidth - 40, window.innerHeight - 108);
}
window.onresize = function(){ syncHeights(); }
window.onBespinLoad = function() { newTemplate(); }
$(function() {
$("#tabs").tabs();
syncHeights();
$('#tabs').bind('tabsshow', function(event, ui) {
syncHeights();
});
$('#fileMenu').menu({
content: $('#fileMenulist').html(),
showSpeed: 120
});
});
</script>
<div id="tabs">
<ul>
<li><a id="editorTab" href="#tabs-1">Editor</a></li>
<li><a id="outputTab" href="#tabs-2">Output</a></li>
<li><a id="eventsTab" href="#tabs-3">Inspector</a></li>
<li><a id="shellTab" href="#tabs-4">Shell</a></li>
</ul>
<div id="tabs-1" class="tab">
<div id="fileMenuButton"><span tabindex="0" class="menu" id="fileMenu"><u>A</u>ctions</span></div>
<div style="display:none;">
<ul id="fileMenulist">
<li class="menuitem" onclick="openFile();"><a href="#" ><u>O</u>pen</a></li>
<li class="menuitem" onclick="newTemplate();"><a href="#"><u>N</u>ew</li>
<li class="menuitem" onclick="saveFile();"><a href="#" ><u>S</u>ave</a></li>
<li class="menuitem" onclick="saveAsFile();"><a href="#">Sav<u>e</u> As</a></li>
<li class="menuitem" onclick="closeFile();"><a href="#" >Close C<u>u</u>rrent File</a></li>
<li class="menuitem" onclick="runFile();"><a href="#">Run <u>F</u>ile</a></li>
<li class="menuitem" onclick="runDirectory();"><a href="#">Run Direc<u>t</u>ory</a></li>
<li class="menuitem" onclick="openHelp();"><a href="#"><u>H</u>elp</a></li>
</ul>
</div>
<span id="openTabs"><span id="openTabsLabel">Open Files: </span><select id="editor-tab-select" onchange="tabSelected(this);"></select></span>
<span style="float:right;">
<button id="runButton" class="ui-state-default ui-corner-all" onclick="runEditor();"><u>R</u>un</button>
<button id="recordToggle" class="ui-state-default ui-corner-all" onclick="MozMillrec.toggle();">Recor<u>d</u></button>
</span>
<div id="editors"></div>
</div>
<div id="tabs-2" class="tab">
<div id="outOptions" >
<span id="outToggles">
Pass:<input id="outPass" label="Pass" type=checkbox checked onchange="updateOutput();"/>
Fail:<input id="outFail" label="Fail" type=checkbox checked onchange="updateOutput();"/>
Test:<input id="outTest" label="Test" type=checkbox checked onchange="updateOutput();"/>
</span>
<button id="outClear" style="float:right;" class="ui-state-default ui-corner-all" onclick="logicalClear();">C<u>l</u>ear</button>
</div>
<p>
<div id="resOut" style="overflow:auto;position:absolute;height:90%;width:98%"></div>
</p>
</div>
<div id="tabs-3" class="tab">
<div id="dxOptions" style="float:right;">
Double Click: <input id="inspectDouble" type="radio" name="inspectClickSelection" value="double" onclick="MozMilldx.changeClick();" checked>
Single Click: <input id="inspectSingle" type="radio" name="inspectClickSelection" onclick="MozMilldx.changeClick();" value="single">
</div>
<br>
<div id="dxContainer"><div id="elementStr">
<strong>Element</strong>:
<span ondblclick="copyToClipboard(this.textContent);" id="dxElement"></span></div>
<span id="controllerStr"><strong>Controller</strong>:
<span ondblclick="copyToClipboard(this.textContent);" id="dxController"></span></span>
<br> <div class="ui-helper-hidden">
<strong>Validation</strong>:
<span ondblclick="copyToClipboard(this.textContent);" id="dxValidation"></span> </div>
</div>
<div id="dxButtons">
<button id="dxToggle" class="ui-state-default ui-corner-all ui-priority-primary" onclick="MozMilldx.dxToggle();">Start</button>
<button id="dxCopy" class="ui-state-default ui-corner-all ui-helper-hidden" onclick="copyInspector();">Send To Clipboard</button>
</div>
</p>
</div>
<div id="tabs-4" class="tab">
<p>
<textarea id="shellInput">Type commands here...</textarea>
<div id="shellOutput">
</div>
</p>
</div>
</div>
<script src="shell.js"></script>
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,77 @@
// ***** BEGIN LICENSE BLOCK *****
// Version: MPL 1.1/GPL 2.0/LGPL 2.1
//
// The contents of this file are subject to the Mozilla Public License Version
// 1.1 (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// The Original Code is Mozilla Corporation Code.
//
// The Initial Developer of the Original Code is
// Adam Christian.
// Portions created by the Initial Developer are Copyright (C) 2008
// the Initial Developer. All Rights Reserved.
//
// Contributor(s):
// Adam Christian <adam.christian@gmail.com>
// Mikeal Rogers <mikeal.rogers@gmail.com>
//
// Alternatively, the contents of this file may be used under the terms of
// either the GNU General Public License Version 2 or later (the "GPL"), or
// the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
// in which case the provisions of the GPL or the LGPL are applicable instead
// of those above. If you wish to allow use of your version of this file only
// under the terms of either the GPL or the LGPL, and not to allow others to
// use your version of this file under the terms of the MPL, indicate your
// decision by deleting the provisions above and replace them with the notice
// and other provisions required by the GPL or the LGPL. If you do not delete
// the provisions above, a recipient may use your version of this file under
// the terms of any one of the MPL, the GPL or the LGPL.
//
// ***** END LICENSE BLOCK *****
var mozmill = {}; Components.utils.import('resource://mozmill/modules/mozmill.js', mozmill);
var utils = {}; Components.utils.import('resource://mozmill/modules/utils.js', utils);
var updateOutput = function(){
//get the checkboxes
var pass = document.getElementById('outPass');
var fail = document.getElementById('outFail');
var info = document.getElementById('outTest');
//get the collections
var passCollect = window.document.getElementsByClassName('pass');
var failCollect = window.document.getElementsByClassName('fail');
var infoCollect = window.document.getElementsByClassName('test');
//set the htmlcollection display property in accordance item.checked
var setDisplay = function(item, collection){
for (var i = 0; i < collection.length; i++){
if (item.checked == true){
collection[i].style.display = "block";
} else {
collection[i].style.display = "none";
}
}
};
setDisplay(pass, passCollect);
setDisplay(fail, failCollect);
setDisplay(info, infoCollect);
};
function cleanUp(){
//cleanup frame event listeners for output
removeStateListeners();
// Just store width and height
utils.setPreference("mozmill.screenX", window.screenX);
utils.setPreference("mozmill.screenY", window.screenY);
utils.setPreference("mozmill.width", window.document.documentElement.clientWidth);
utils.setPreference("mozmill.height", window.document.documentElement.clientHeight);
}

Просмотреть файл

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is MozMill.
-
- The Initial Developer of the Original Code is
- Mozilla Foundation.
- Portions created by the Initial Developer are Copyright (C) 2009
- the Initial Developer. All Rights Reserved.
-
- Contributor(s): Heather Arthur <harthur@cmu.edu>
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the GPL or the LGPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://mozmill/skin/chrome.css" type="text/css"?>
<window id="mozmill-window"
title="MozMill IDE"
windowtype="mozmill:ide"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
persist="width height screenX screenY">
<script type="application/x-javascript" src="chrome://mozmill/content/chrome.js"/>
<tooltip id="mozmill-tooltip" onpopupshowing="return fillTooltip(document.tooltipNode);"/>
<iframe id="mozmill-iframe" src="mozmill.html" flex="1"
tooltip="mozmill-tooltip" onkeypress="onkeypress"/>
</window>

Просмотреть файл

@ -0,0 +1,203 @@
// ***** BEGIN LICENSE BLOCK *****
// Version: MPL 1.1/GPL 2.0/LGPL 2.1
//
// The contents of this file are subject to the Mozilla Public License Version
// 1.1 (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// The Original Code is Mozilla Corporation Code.
//
// The Initial Developer of the Original Code is
// Adam Christian.
// Portions created by the Initial Developer are Copyright (C) 2008
// the Initial Developer. All Rights Reserved.
//
// Contributor(s):
// Adam Christian <adam.christian@gmail.com>
// Mikeal Rogers <mikeal.rogers@gmail.com>
//
// Alternatively, the contents of this file may be used under the terms of
// either the GNU General Public License Version 2 or later (the "GPL"), or
// the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
// in which case the provisions of the GPL or the LGPL are applicable instead
// of those above. If you wish to allow use of your version of this file only
// under the terms of either the GPL or the LGPL, and not to allow others to
// use your version of this file under the terms of the MPL, indicate your
// decision by deleting the provisions above and replace them with the notice
// and other provisions required by the GPL or the LGPL. If you do not delete
// the provisions above, a recipient may use your version of this file under
// the terms of any one of the MPL, the GPL or the LGPL.
//
// ***** END LICENSE BLOCK *****
var arrays = {}; Components.utils.import('resource://mozmill/stdlib/arrays.js', arrays);
var json2 = {}; Components.utils.import('resource://mozmill/stdlib/json2.js', json2);
var utils = {}; Components.utils.import('resource://mozmill/modules/utils.js', utils);
var aConsoleService = Components.classes["@mozilla.org/consoleservice;1"].
getService(Components.interfaces.nsIConsoleService);
var createCell = function (t, obj, message) {
// try {
// alert(json2.JSON.stringify(message.exception.message));
// } catch(err){}
// //alert(msgObj.exception.message);
//
var r = document.getElementById("resOut");
var msg = document.createElement('div');
msg.setAttribute("class", t);
if (t == "fail"){
$(msg).addClass("ui-state-error ui-corner-all");
}
if (t == "pass"){
$(msg).addClass("ui-state-highlight ui-corner-all");
msg.style.background = "lightgreen";
msg.style.border = "1px solid darkgreen";
}
else {
$(msg).addClass("ui-state-highlight ui-corner-all");
}
msg.style.height = "15px";
msg.style.overflow = "hidden";
//if message isn't an object
if (typeof(message) == "string"){
msg.innerHTML = "<strong>"+t+"</strong>"+' :: '+message;
}
else {
try {
var display = message.exception.message;
if (display == undefined) {
var display = message.exception;
}
} catch(err){
var display = message['function'];
}
//add each piece in its own hbox
msg.innerHTML = '<span style="float:right;top:0px;cursor: pointer;" class="ui-icon ui-icon-triangle-1-s"/>';
msg.innerHTML += "<strong>"+t+"</strong>"+' :: '+display;
var createTree = function(obj){
var mainDiv = document.createElement('div');
for (prop in obj){
var newDiv = document.createElement('div');
newDiv.style.position = "relative";
newDiv.style.height = "15px";
newDiv.style.overflow = "hidden";
newDiv.style.width = "95%";
newDiv.style.left = "10px";
//some properties don't have a length attib
try {
if (obj[prop] && obj[prop].length > 50){
newDiv.innerHTML = '<span style="float:right;top:0px;cursor: pointer;" class="ui-icon ui-icon-triangle-1-s"/>';
}
} catch(e){}
newDiv.innerHTML += "<strong>"+prop+"</strong>: "+obj[prop];
mainDiv.appendChild(newDiv);
}
return mainDiv;
}
//iterate the properties creating output entries for them
for (prop in message){
if (typeof message[prop] == "object"){
var newDiv = createTree(message[prop]);
}
else {
var newDiv = document.createElement('div');
newDiv.innerHTML = "<strong>"+prop+"</strong>: "+message[prop];
}
newDiv.style.position = "relative";
newDiv.style.left = "10px";
newDiv.style.overflow = "hidden";
msg.appendChild(newDiv);
}
}
//Add the event listener for clicking on the box to see more info
msg.addEventListener('click', function(e){
// if (e.which == 3){
// var rout = document.getElementById('resOut');
// if (e.target.parentNode != rout){
// copyToClipboard(e.target.parentNode.innerHTML);
// }
// else {
// copyToClipboard(e.target.innerHTML);
// }
// alert('Copied to clipboard...')
// return;
// }
if (e.target.tagName == "SPAN"){
if (e.target.parentNode.style.height == "15px"){
e.target.parentNode.style.overflow = "";
e.target.parentNode.style.height = "";
e.target.className = "ui-icon ui-icon-triangle-1-n";
}
else {
e.target.parentNode.style.height = "15px";
e.target.parentNode.style.overflow = "hidden";
e.target.className = "ui-icon ui-icon-triangle-1-s";
}
}
}, true);
if (r.childNodes.length == 0){
r.appendChild(msg);
}
else {
r.insertBefore(msg, r.childNodes[0]);
}
updateOutput();
}
var frame = {}; Components.utils.import('resource://mozmill/modules/frame.js', frame);
// var utils = {}; Components.utils.import('resouce://mozmill/modules/utils.js', utils);
// Set UI Listeners in frame
function stateListener (state) {
if (state != 'test') {
// utils.getWindowByTitle('MozMill IDE').document.getElementById('runningStatus').innerHTML = state;
}
}
frame.events.addListener('setState', stateListener);
aConsoleService.logStringMessage('+++++++++++++++++++++++');
aConsoleService.logStringMessage("Current setStateListener size: "+String(frame.events.listeners.setState.length) );
function testListener (test) {
createCell('test', test, 'Started running test: '+test.name);
}
frame.events.addListener('setTest', testListener);
function passListener (text) {
createCell('pass', text, text);
}
frame.events.addListener('pass', passListener);
function failListener (text) {
createCell('fail', text, text);
}
frame.events.addListener('fail', failListener);
function logListener (obj) {
createCell('log', obj, obj);
}
frame.events.addListener('log', logListener);
function loggerListener (obj) {
createCell('logger', obj, obj)
}
frame.events.addListener('logger', loggerListener);
function removeStateListeners(){
frame.events.removeListener(testListener);
frame.events.removeListener(passListener);
frame.events.removeListener(failListener);
frame.events.removeListener(logListener);
frame.events.removeListener(loggerListener);
}

Просмотреть файл

@ -0,0 +1,86 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation Code.
*
* The Initial Developer of the Original Code is
* Adam Christian.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Adam Christian <adam.christian@gmail.com>
* Mikeal Rogers <mikeal.rogers@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var mozmillInit = {}; Components.utils.import('resource://mozmill/modules/init.js', mozmillInit);
var MozMill = {
onLoad: function() {
// initialization code
this.initialized = true;
},
onMenuItemCommand: function() {
var utils = {}; Components.utils.import('resource://mozmill/modules/utils.js', utils);
var mmWindows = utils.getWindowByTitle('MozMill IDE');
if (!mmWindows){
var height = utils.getPreference("mozmill.height", 740);
var width = utils.getPreference("mozmill.width", 635);
//move to top left corner
var left = utils.getPreference("mozmill.screenX", 0);
var top = utils.getPreference("mozmill.screenY", 0);
if (left == 0){
//make only browser windows big
var width = window.screen.availWidth/2.5;
var height = window.screen.availHeight;
window.resizeTo((window.screen.availWidth - width), window.screen.availHeight);
var height = window.innerHeight;
var left = window.innerWidth;
}
var paramString = "chrome,resizable,height=" + height +
",width=" + width + ",left="+left+",top="+top;
var w = window.open("chrome://mozmill/content/mozmill.xul", "", paramString);
} else { mmWindows[0].focus(); }
}
};
window.addEventListener("load", function(e) { MozMill.onLoad(e); }, false);
function mozMillTestWindow() {
window.openDialog("chrome://mozmill/content/testwindow.html", "_blank", "chrome,dialog=no, resizable");
}
//adding a mozmill keyboard shortcut
// window.addEventListener("keypress", function(e) {
// if ((e.charCode == 109) && (e.ctrlKey)) {
// MozMill.onMenuItemCommand(e);
// }
// }, false);

Просмотреть файл

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://mozmill/skin/overlay.css" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://mozmill/locale/overlay.dtd">
<overlay id="mozmill-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="chrome://mozmill/content/overlay.js"/>
<keyset>
<key id="open-mozmill" modifiers="accel shift" key="m" oncommand="MozMill.onMenuItemCommand(event);"/>
</keyset>
<menupopup id="menu_ToolsPopup">
<menuitem key="open-mozmill" id="mozmill-mozmill" label="&mozmill;"
oncommand="MozMill.onMenuItemCommand(event);"/>
</menupopup>
</overlay>

Просмотреть файл

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://mozmill/skin/overlay.css" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://mozmill/locale/overlay.dtd">
<overlay id="mozmill-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="overlay.js"/>
<menupopup id="taskPopup">
<menuitem id="mozmill-mozmill" label="&mozmill;"
oncommand="MozMill.onMenuItemCommand(event);"/>
</menupopup>
</overlay>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше