PageRenderTime 142ms CodeModel.GetById 33ms app.highlight 95ms RepoModel.GetById 1ms app.codeStats 1ms

/Frameworks/Objective-J/Objective-J.js

http://github.com/polymar/polish
JavaScript | 2436 lines | 2414 code | 1 blank | 21 comment | 393 complexity | 1bd1583396e5b51a52e552f95501ff94 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * Objective-J.js
   3 * Objective-J
   4 *
   5 * Created by Francisco Tolmasky.
   6 * Copyright 2008, 280 North, Inc.
   7 *
   8 * This library is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU Lesser General Public
  10 * License as published by the Free Software Foundation; either
  11 * version 2.1 of the License, or (at your option) any later version.
  12 *
  13 * This library is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 * Lesser General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU Lesser General Public
  19 * License along with this library; if not, write to the Free Software
  20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 */
  22
  23var NO = false,
  24    YES = true,
  25    nil = null,
  26    Nil = null,
  27    NULL = null,
  28    ABS = Math.abs,
  29    ASIN = Math.asin,
  30    ACOS = Math.acos,
  31    ATAN = Math.atan,
  32    ATAN2 = Math.atan2,
  33    SIN = Math.sin,
  34    COS = Math.cos,
  35    TAN = Math.tan,
  36    EXP = Math.exp,
  37    POW = Math.pow,
  38    CEIL = Math.ceil,
  39    FLOOR = Math.floor,
  40    ROUND = Math.round,
  41    MIN = Math.min,
  42    MAX = Math.max,
  43    RAND = Math.random,
  44    SQRT = Math.sqrt,
  45    E = Math.E,
  46    LN2 = Math.LN2,
  47    LN10 = Math.LN10,
  48    LOG2E = Math.LOG2E,
  49    LOG10E = Math.LOG10E,
  50    PI = Math.PI,
  51    PI2 = Math.PI * 2.0,
  52    PI_2 = Math.PI / 2.0,
  53    SQRT1_2 = Math.SQRT1_2,
  54    SQRT2 = Math.SQRT2;
  55window.setNativeTimeout = window.setTimeout;
  56window.clearNativeTimeout = window.clearTimeout;
  57window.setNativeInterval = window.setInterval;
  58window.clearNativeInterval = window.clearInterval;
  59var objj_continue_alerting = NO;
  60function objj_alert(aString)
  61{
  62    if (!objj_continue_alerting)
  63        return;
  64    objj_continue_alerting = confirm(aString + "\n\nClick cancel to prevent further alerts.");
  65}
  66function objj_fprintf(stream, string)
  67{
  68    stream(string);
  69}
  70function objj_printf(string)
  71{
  72    objj_fprintf(alert, string);
  73}
  74if (window.console && window.console.warn)
  75    var warning_stream = function(aString) { window.console.warn(aString); }
  76else
  77    var warning_stream = function(){};
  78var _sprintfFormatRegex = new RegExp("([^%]+|%[\\+\\-\\ \\#0]*[0-9\\*]*(.[0-9\\*]+)?[hlL]?[cbBdieEfgGosuxXpn%@])", "g");
  79var _sprintfTagRegex = new RegExp("(%)([\\+\\-\\ \\#0]*)([0-9\\*]*)((.[0-9\\*]+)?)([hlL]?)([cbBdieEfgGosuxXpn%@])");
  80function sprintf(format)
  81{
  82    var format = arguments[0],
  83        tokens = format.match(_sprintfFormatRegex),
  84        index = 0,
  85        result = "",
  86        arg = 1;
  87    for (var i = 0; i < tokens.length; i++)
  88    {
  89        var t = tokens[i];
  90        if (format.substring(index, index + t.length) != t)
  91        {
  92            return result;
  93        }
  94        index += t.length;
  95        if (t.charAt(0) != "%")
  96        {
  97            result += t;
  98        }
  99        else
 100        {
 101            var subtokens = t.match(_sprintfTagRegex);
 102            if (subtokens.length != 8 || subtokens[0] != t)
 103            {
 104                return result;
 105            }
 106            var percentSign = subtokens[1],
 107                flags = subtokens[2],
 108                widthString = subtokens[3],
 109                precisionString = subtokens[4],
 110                length = subtokens[6],
 111                specifier = subtokens[7];
 112            var width = null;
 113            if (widthString == "*")
 114                width = arguments[arg++];
 115            else if (widthString != "")
 116                width = Number(widthString);
 117            var precision = null;
 118            if (precisionString == ".*")
 119                precision = arguments[arg++];
 120            else if (precisionString != "")
 121                precision = Number(precisionString.substring(1));
 122            var leftJustify = (flags.indexOf("-") >= 0);
 123            var padZeros = (flags.indexOf("0") >= 0);
 124            var subresult = "";
 125            if (RegExp("[bBdiufeExXo]").test(specifier))
 126            {
 127                var num = Number(arguments[arg++]);
 128                var sign = "";
 129                if (num < 0)
 130                {
 131                    sign = "-";
 132                }
 133                else
 134                {
 135                    if (flags.indexOf("+") >= 0)
 136                        sign = "+";
 137                    else if (flags.indexOf(" ") >= 0)
 138                        sign = " ";
 139                }
 140                if (specifier == "d" || specifier == "i" || specifier == "u")
 141                {
 142                    var number = String(Math.abs(Math.floor(num)));
 143                    subresult = _sprintf_justify(sign, "", number, "", width, leftJustify, padZeros)
 144                }
 145                if (specifier == "f")
 146                {
 147                    var number = String((precision != null) ? Math.abs(num).toFixed(precision) : Math.abs(num));
 148                    var suffix = (flags.indexOf("#") >= 0 && number.indexOf(".") < 0) ? "." : "";
 149                    subresult = _sprintf_justify(sign, "", number, suffix, width, leftJustify, padZeros);
 150                }
 151                if (specifier == "e" || specifier == "E")
 152                {
 153                    var number = String(Math.abs(num).toExponential(precision != null ? precision : 21));
 154                    var suffix = (flags.indexOf("#") >= 0 && number.indexOf(".") < 0) ? "." : "";
 155                    subresult = _sprintf_justify(sign, "", number, suffix, width, leftJustify, padZeros);
 156                }
 157                if (specifier == "x" || specifier == "X")
 158                {
 159                    var number = String(Math.abs(num).toString(16));
 160                    var prefix = (flags.indexOf("#") >= 0 && num != 0) ? "0x" : "";
 161                    subresult = _sprintf_justify(sign, prefix, number, "", width, leftJustify, padZeros);
 162                }
 163                if (specifier == "b" || specifier == "B")
 164                {
 165                    var number = String(Math.abs(num).toString(2));
 166                    var prefix = (flags.indexOf("#") >= 0 && num != 0) ? "0b" : "";
 167                    subresult = _sprintf_justify(sign, prefix, number, "", width, leftJustify, padZeros);
 168                }
 169                if (specifier == "o")
 170                {
 171                    var number = String(Math.abs(num).toString(8));
 172                    var prefix = (flags.indexOf("#") >= 0 && num != 0) ? "0" : "";
 173                    subresult = _sprintf_justify(sign, prefix, number, "", width, leftJustify, padZeros);
 174                }
 175                if (RegExp("[A-Z]").test(specifier))
 176                    subresult = subresult.toUpperCase();
 177                else
 178                    subresult = subresult.toLowerCase();
 179            }
 180            else
 181            {
 182                var subresult = "";
 183                if (specifier == "%")
 184                    subresult = "%";
 185                else if (specifier == "c")
 186                    subresult = String(arguments[arg++]).charAt(0);
 187                else if (specifier == "s" || specifier == "@")
 188                    subresult = String(arguments[arg++]);
 189                else if (specifier == "p" || specifier == "n")
 190                {
 191                    arg++;
 192                    subresult = "";
 193                }
 194                subresult = _sprintf_justify("", "", subresult, "", width, leftJustify, false);
 195            }
 196            result += subresult;
 197        }
 198    }
 199    return result;
 200}
 201var _sprintf_justify = function(sign, prefix, string, suffix, width, leftJustify, padZeros)
 202{
 203    var length = (sign.length + prefix.length + string.length + suffix.length);
 204    if (leftJustify)
 205    {
 206        return sign + prefix + string + suffix + _sprintf_pad(width - length, " ");
 207    }
 208    else
 209    {
 210        if (padZeros)
 211            return sign + prefix + _sprintf_pad(width - length, "0") + string + suffix;
 212        else
 213            return _sprintf_pad(width - length, " ") + sign + prefix + string + suffix;
 214    }
 215}
 216var _sprintf_pad = function(n, ch)
 217{
 218    var result = "";
 219    for (var i = 0; i < n; i++)
 220        result += ch;
 221    return result;
 222}
 223var base64_map_to = [
 224        "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
 225        "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
 226        "0","1","2","3","4","5","6","7","8","9","+","/","="],
 227    base64_map_from = [];
 228for (var i = 0; i < base64_map_to.length; i++)
 229    base64_map_from[base64_map_to[i].charCodeAt(0)] = i;
 230function base64_decode_to_array(input, strip)
 231{
 232    if (strip)
 233        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
 234    var pad = (input[input.length-1] == "=" ? 1 : 0) + (input[input.length-2] == "=" ? 1 : 0),
 235        length = input.length,
 236        output = [];
 237    var i = 0;
 238    while (i < length)
 239    {
 240        var bits = (base64_map_from[input.charCodeAt(i++)] << 18) |
 241                    (base64_map_from[input.charCodeAt(i++)] << 12) |
 242                    (base64_map_from[input.charCodeAt(i++)] << 6) |
 243                    (base64_map_from[input.charCodeAt(i++)]);
 244        output.push((bits & 0xFF0000) >> 16);
 245        output.push((bits & 0xFF00) >> 8);
 246        output.push(bits & 0xFF);
 247    }
 248    if (pad > 0)
 249        return output.slice(0, -1 * pad);
 250    return output;
 251}
 252function base64_encode_array(input)
 253{
 254    var pad = (3 - (input.length % 3)) % 3,
 255        length = input.length + pad,
 256        output = [];
 257    if (pad > 0) input.push(0);
 258    if (pad > 1) input.push(0);
 259    var i = 0;
 260    while (i < length)
 261    {
 262        var bits = (input[i++] << 16) |
 263                    (input[i++] << 8) |
 264                    (input[i++]);
 265        output.push(base64_map_to[(bits & 0xFC0000) >> 18]);
 266        output.push(base64_map_to[(bits & 0x3F000) >> 12]);
 267        output.push(base64_map_to[(bits & 0xFC0) >> 6]);
 268        output.push(base64_map_to[bits & 0x3F]);
 269    }
 270    if (pad > 0)
 271    {
 272        output[output.length-1] = "=";
 273        input.pop();
 274    }
 275    if (pad > 1)
 276    {
 277        output[output.length-2] = "=";
 278        input.pop();
 279    }
 280    return output.join("");
 281}
 282function base64_decode_to_string(input, strip)
 283{
 284    return bytes_to_string(base64_decode_to_array(input, strip));
 285}
 286function bytes_to_string(bytes)
 287{
 288    return String.fromCharCode.apply(null, bytes);
 289}
 290function base64_encode_string(input)
 291{
 292    var temp = [];
 293    for (var i = 0; i < input.length; i++)
 294        temp.push(input.charCodeAt(i));
 295    return base64_encode_array(temp);
 296}
 297var CLS_CLASS = 0x1,
 298    CLS_META = 0x2,
 299    CLS_INITIALIZED = 0x4,
 300    CLS_INITIALIZING = 0x8;
 301function objj_ivar( aName, aType)
 302{
 303    this.name = aName;
 304    this.type = aType;
 305}
 306function objj_method( aName, anImplementation, types)
 307{
 308    this.name = aName;
 309    this.method_imp = anImplementation;
 310    this.types = types;
 311}
 312function objj_class()
 313{
 314    this.isa = NULL;
 315    this.super_class = NULL;
 316    this.sub_classes = [];
 317    this.name = NULL;
 318    this.info = 0;
 319    this.ivars = [];
 320    this.method_list = [];
 321    this.method_hash = {};
 322    this.method_store = function() { };
 323    this.method_dtable = this.method_store.prototype;
 324    this.allocator = function() { };
 325    this.__address = -1;
 326}
 327function objj_object()
 328{
 329    this.isa = NULL;
 330    this.__address = -1;
 331}
 332var OBJECT_COUNT = 0;
 333function _objj_generateObjectHash()
 334{
 335    return OBJECT_COUNT++;
 336}
 337function class_getName( aClass)
 338{
 339    if (aClass == Nil)
 340        return "";
 341    return aClass.name;
 342}
 343function class_isMetaClass( aClass)
 344{
 345    if (!aClass)
 346        return NO;
 347    return ((aClass.info & (CLS_META)));
 348}
 349function class_getSuperclass( aClass)
 350{
 351    if (aClass == Nil)
 352        return Nil;
 353    return aClass.super_class;
 354}
 355function class_setSuperclass( aClass, aSuperClass)
 356{
 357}
 358function class_isMetaClass( aClass)
 359{
 360    return ((aClass.info & (CLS_META)));
 361}
 362function class_addIvar( aClass, aName, aType)
 363{
 364    var thePrototype = aClass.allocator.prototype;
 365    if (typeof thePrototype[aName] != "undefined")
 366        return NO;
 367    aClass.ivars.push(new objj_ivar(aName, aType));
 368    thePrototype[aName] = NULL;
 369    return YES;
 370}
 371function class_addIvars( aClass, ivars)
 372{
 373    var index = 0,
 374        count = ivars.length,
 375        thePrototype = aClass.allocator.prototype;
 376    for (; index < count; ++index)
 377    {
 378        var ivar = ivars[index],
 379            name = ivar.name;
 380        if (typeof thePrototype[name] === "undefined")
 381        {
 382            aClass.ivars.push(ivar);
 383            thePrototype[name] = NULL;
 384        }
 385    }
 386}
 387function class_copyIvarList( aClass)
 388{
 389    return aClass.ivars.slice(0);
 390}
 391function class_addMethod( aClass, aName, anImplementation, aType)
 392{
 393    if (aClass.method_hash[aName])
 394        return NO;
 395    var method = new objj_method(aName, anImplementation, aType);
 396    aClass.method_list.push(method);
 397    aClass.method_dtable[aName] = method;
 398    method.method_imp.displayName = (((aClass.info & (CLS_META))) ? '+' : '-') + " [" + class_getName(aClass) + ' ' + method_getName(method) + ']';
 399    if (!((aClass.info & (CLS_META))) && (((aClass.info & (CLS_META))) ? aClass : aClass.isa).isa === (((aClass.info & (CLS_META))) ? aClass : aClass.isa))
 400        class_addMethods((((aClass.info & (CLS_META))) ? aClass : aClass.isa), methods);
 401    return YES;
 402}
 403function class_addMethods( aClass, methods)
 404{
 405    var index = 0,
 406        count = methods.length,
 407        method_list = aClass.method_list,
 408        method_dtable = aClass.method_dtable;
 409    for (; index < count; ++index)
 410    {
 411        var method = methods[index];
 412        if (aClass.method_hash[method.name])
 413            continue;
 414        method_list.push(method);
 415        method_dtable[method.name] = method;
 416        method.method_imp.displayName = (((aClass.info & (CLS_META))) ? '+' : '-') + " [" + class_getName(aClass) + ' ' + method_getName(method) + ']';
 417    }
 418    if (!((aClass.info & (CLS_META))) && (((aClass.info & (CLS_META))) ? aClass : aClass.isa).isa === (((aClass.info & (CLS_META))) ? aClass : aClass.isa))
 419        class_addMethods((((aClass.info & (CLS_META))) ? aClass : aClass.isa), methods);
 420}
 421function class_getInstanceMethod( aClass, aSelector)
 422{
 423    if (!aClass || !aSelector)
 424        return NULL;
 425    var method = aClass.method_dtable[aSelector];
 426    return method ? method : NULL;
 427}
 428function class_getClassMethod( aClass, aSelector)
 429{
 430    if (!aClass || !aSelector)
 431        return NULL;
 432    var method = (((aClass.info & (CLS_META))) ? aClass : aClass.isa).method_dtable[aSelector];
 433    return method ? method : NULL;
 434}
 435function class_copyMethodList( aClass)
 436{
 437    return aClass.method_list.slice(0);
 438}
 439function class_replaceMethod( aClass, aSelector, aMethodImplementation)
 440{
 441    if (!aClass || !aSelector)
 442        return NULL;
 443    var method = aClass.method_dtable[aSelector],
 444        method_imp = NULL;
 445    if (method)
 446        method_imp = method.method_imp;
 447    method.method_imp = aMethodImplementation;
 448    return method_imp;
 449}
 450var _class_initialize = function( aClass)
 451{
 452    var meta = (((aClass.info & (CLS_META))) ? aClass : aClass.isa);
 453    if ((aClass.info & (CLS_META)))
 454        aClass = objj_getClass(aClass.name);
 455    if (aClass.super_class && !((((aClass.super_class.info & (CLS_META))) ? aClass.super_class : aClass.super_class.isa).info & (CLS_INITIALIZED)))
 456        _class_initialize(aClass.super_class);
 457    if (!(meta.info & (CLS_INITIALIZED)) && !(meta.info & (CLS_INITIALIZING)))
 458    {
 459        meta.info = (meta.info | (CLS_INITIALIZING)) & ~(0);
 460        objj_msgSend(aClass, "initialize");
 461        meta.info = (meta.info | (CLS_INITIALIZED)) & ~(CLS_INITIALIZING);
 462    }
 463}
 464var _objj_forward = new objj_method("forward", function(self, _cmd)
 465{
 466    return objj_msgSend(self, "forward::", _cmd, arguments);
 467});
 468function class_getMethodImplementation( aClass, aSelector)
 469{
 470    if (!((((aClass.info & (CLS_META))) ? aClass : aClass.isa).info & (CLS_INITIALIZED))) _class_initialize(aClass); var method = aClass.method_dtable[aSelector]; if (!method) method = _objj_forward; var implementation = method.method_imp;;
 471    return implementation;
 472}
 473var GLOBAL_NAMESPACE = window,
 474    REGISTERED_CLASSES = {};
 475function objj_allocateClassPair( superclass, aName)
 476{
 477    var classObject = new objj_class(),
 478        metaClassObject = new objj_class(),
 479        rootClassObject = classObject;
 480    if (superclass)
 481    {
 482        rootClassObject = superclass;
 483        while (rootClassObject.superclass)
 484            rootClassObject = rootClassObject.superclass;
 485        classObject.allocator.prototype = new superclass.allocator;
 486        classObject.method_store.prototype = new superclass.method_store;
 487        classObject.method_dtable = classObject.method_store.prototype;
 488        metaClassObject.method_store.prototype = new superclass.isa.method_store;
 489        metaClassObject.method_dtable = metaClassObject.method_store.prototype;
 490        classObject.super_class = superclass;
 491        metaClassObject.super_class = superclass.isa;
 492    }
 493    else
 494        classObject.allocator.prototype = new objj_object();
 495    classObject.isa = metaClassObject;
 496    classObject.name = aName;
 497    classObject.info = CLS_CLASS;
 498    classObject.__address = (OBJECT_COUNT++);
 499    metaClassObject.isa = rootClassObject.isa;
 500    metaClassObject.name = aName;
 501    metaClassObject.info = CLS_META;
 502    metaClassObject.__address = (OBJECT_COUNT++);
 503    return classObject;
 504}
 505function objj_registerClassPair( aClass)
 506{
 507    GLOBAL_NAMESPACE[aClass.name] = aClass;
 508    REGISTERED_CLASSES[aClass.name] = aClass;
 509}
 510function class_createInstance( aClass)
 511{
 512    if (!aClass)
 513        objj_exception_throw(new objj_exception(OBJJNilClassException, "*** Attempting to create object with Nil class."));
 514    var object = new aClass.allocator;
 515    object.__address = (OBJECT_COUNT++);
 516    object.isa = aClass;
 517    return object;
 518}
 519var prototype_bug = function() { }
 520prototype_bug.prototype.member = false;
 521with (new prototype_bug())
 522    member = true;
 523if (new prototype_bug().member)
 524{
 525var fast_class_createInstance = class_createInstance;
 526class_createInstance = function( aClass)
 527{
 528    var object = fast_class_createInstance(aClass);
 529    if (object)
 530    {
 531        var theClass = object.isa,
 532            actualClass = theClass;
 533        while (theClass)
 534        {
 535            var ivars = theClass.ivars;
 536                count = ivars.length;
 537            while (count--)
 538                object[ivars[count].name] = NULL;
 539            theClass = theClass.super_class;
 540        }
 541        object.isa = actualClass;
 542    }
 543    return object;
 544}
 545}
 546function object_getClassName( anObject)
 547{
 548    if (!anObject)
 549        return "";
 550    var theClass = anObject.isa;
 551    return theClass ? class_getName(theClass) : "";
 552}
 553function objj_lookUpClass( aName)
 554{
 555    var theClass = REGISTERED_CLASSES[aName];
 556    return theClass ? theClass : Nil;
 557}
 558function objj_getClass( aName)
 559{
 560    var theClass = REGISTERED_CLASSES[aName];
 561    if (!theClass)
 562    {
 563    }
 564    return theClass ? theClass : Nil;
 565}
 566function objj_getMetaClass( aName)
 567{
 568    var theClass = objj_getClass(aName);
 569    return (((theClass.info & (CLS_META))) ? theClass : theClass.isa);
 570}
 571function ivar_getName(anIvar)
 572{
 573    return anIvar.name;
 574}
 575function ivar_getTypeEncoding(anIvar)
 576{
 577    return anIvar.type;
 578}
 579function objj_msgSend( aReceiver, aSelector)
 580{
 581    if (aReceiver == nil)
 582        return nil;
 583    if (!((((aReceiver.isa.info & (CLS_META))) ? aReceiver.isa : aReceiver.isa.isa).info & (CLS_INITIALIZED))) _class_initialize(aReceiver.isa); var method = aReceiver.isa.method_dtable[aSelector]; if (!method) method = _objj_forward; var implementation = method.method_imp;;
 584    switch(arguments.length)
 585    {
 586        case 2:
 587            return implementation(aReceiver, aSelector);
 588        case 3:
 589            return implementation(aReceiver, aSelector, arguments[2]);
 590        case 4:
 591            return implementation(aReceiver, aSelector, arguments[2], arguments[3]);
 592    }
 593    return implementation.apply(aReceiver, arguments);
 594}
 595function objj_msgSendSuper( aSuper, aSelector)
 596{
 597    var super_class = aSuper.super_class;
 598    arguments[0] = aSuper.receiver;
 599    if (!((((super_class.info & (CLS_META))) ? super_class : super_class.isa).info & (CLS_INITIALIZED))) _class_initialize(super_class); var method = super_class.method_dtable[aSelector]; if (!method) method = _objj_forward; var implementation = method.method_imp;;
 600    return implementation.apply(aSuper.receiver, arguments);
 601}
 602function method_getName( aMethod)
 603{
 604    return aMethod.name;
 605}
 606function method_getImplementation( aMethod)
 607{
 608    return aMethod.method_imp;
 609}
 610function method_setImplementation( aMethod, anImplementation)
 611{
 612    var oldImplementation = aMethod.method_imp;
 613    aMethod.method_imp = anImplementation;
 614    return oldImplementation;
 615}
 616function method_exchangeImplementations( lhs, rhs)
 617{
 618    var lhs_imp = method_getImplementation(lhs),
 619        rhs_imp = method_getImplementation(rhs);
 620    method_setImplementation(lhs, rhs_imp);
 621    method_setImplementation(rhs, lhs_imp);
 622}
 623function sel_getName(aSelector)
 624{
 625    return aSelector ? aSelector : "<null selector>";
 626}
 627function sel_getUid( aName)
 628{
 629    return aName;
 630}
 631function sel_isEqual( lhs, rhs)
 632{
 633    return lhs === rhs;
 634}
 635function sel_registerName(aName)
 636{
 637    return aName;
 638}
 639function objj_dictionary()
 640{
 641    this._keys = [];
 642    this.count = 0;
 643    this._buckets = {};
 644    this.__address = (OBJECT_COUNT++);
 645}
 646function dictionary_containsKey(aDictionary, aKey)
 647{
 648    return aDictionary._buckets[aKey] != NULL;
 649}
 650function dictionary_getCount(aDictionary)
 651{
 652    return aDictionary.count;
 653}
 654function dictionary_getValue(aDictionary, aKey)
 655{
 656    return aDictionary._buckets[aKey];
 657}
 658function dictionary_setValue(aDictionary, aKey, aValue)
 659{
 660    if (aDictionary._buckets[aKey] == NULL)
 661    {
 662        aDictionary._keys.push(aKey);
 663        ++aDictionary.count;
 664    }
 665    if ((aDictionary._buckets[aKey] = aValue) == NULL)
 666        --aDictionary.count;
 667}
 668function dictionary_removeValue(aDictionary, aKey)
 669{
 670    if (aDictionary._buckets[aKey] == NULL)
 671        return;
 672    --aDictionary.count;
 673    if (aDictionary._keys.indexOf)
 674        aDictionary._keys.splice(aDictionary._keys.indexOf(aKey), 1);
 675    else
 676    {
 677        var keys = aDictionary._keys,
 678            index = 0,
 679            count = keys.length;
 680        for (; index < count; ++index)
 681            if (keys[index] == aKey)
 682            {
 683                keys.splice(index, 1);
 684                break;
 685            }
 686    }
 687    delete aDictionary._buckets[aKey];
 688}
 689function dictionary_replaceValue(aDictionary, aKey, aValue)
 690{
 691    if (aDictionary[aKey] == NULL)
 692        return;
 693}
 694function dictionary_description(aDictionary)
 695{
 696    var str = "{ ";
 697    for ( x in aDictionary._buckets)
 698        str += x + ":" + aDictionary._buckets[x] + ",";
 699    str += " }";
 700    return str;
 701}
 702var kCFPropertyListOpenStepFormat = 1,
 703    kCFPropertyListXMLFormat_v1_0 = 100,
 704    kCFPropertyListBinaryFormat_v1_0 = 200,
 705    kCFPropertyList280NorthFormat_v1_0 = -1000;
 706var OBJJPlistParseException = "OBJJPlistParseException",
 707    OBJJPlistSerializeException = "OBJJPlistSerializeException";
 708var kCFPropertyList280NorthMagicNumber = "280NPLIST";
 709function objj_data()
 710{
 711    this.string = "";
 712    this._plistObject = NULL;
 713    this.bytes = NULL;
 714    this.base64 = NULL;
 715}
 716var objj_markedStream = function(aString)
 717{
 718    var index = aString.indexOf(';');
 719    this._magicNumber = aString.substr(0, index);
 720    this._location = aString.indexOf(';', ++index);
 721    this._version = aString.substring(index, this._location++);
 722    this._string = aString;
 723}
 724objj_markedStream.prototype.magicNumber = function()
 725{
 726    return this._magicNumber;
 727}
 728objj_markedStream.prototype.version = function()
 729{
 730    return this._version;
 731}
 732objj_markedStream.prototype.getMarker = function()
 733{
 734    var string = this._string,
 735        location = this._location;
 736    if (location >= string.length)
 737        return NULL;
 738    var next = string.indexOf(';', location);
 739    if (next < 0)
 740        return NULL;
 741    var marker = string.substring(location, next);
 742    this._location = next + 1;
 743    return marker;
 744}
 745objj_markedStream.prototype.getString = function()
 746{
 747    var string = this._string,
 748        location = this._location;
 749    if (location >= string.length)
 750        return NULL;
 751    var next = string.indexOf(';', location);
 752    if (next < 0)
 753        return NULL;
 754    var size = parseInt(string.substring(location, next)),
 755        text = string.substr(next + 1, size);
 756    this._location = next + 1 + size;
 757    return text;
 758}
 759function CPPropertyListCreateData(aPlistObject, aFormat)
 760{
 761    if (aFormat == kCFPropertyListXMLFormat_v1_0)
 762        return CPPropertyListCreateXMLData(aPlistObject);
 763    if (aFormat == kCFPropertyList280NorthFormat_v1_0)
 764        return CPPropertyListCreate280NorthData(aPlistObject);
 765    return NULL;
 766}
 767function CPPropertyListCreateFromData(aData, aFormat)
 768{
 769    if (!aFormat)
 770    {
 771        if (aData instanceof objj_data)
 772        {
 773            var string = aData.string ? aData.string : objj_msgSend(aData, "string");
 774            if (string.substr(0, kCFPropertyList280NorthMagicNumber.length) == kCFPropertyList280NorthMagicNumber)
 775                aFormat = kCFPropertyList280NorthFormat_v1_0;
 776            else
 777                aFormat = kCFPropertyListXMLFormat_v1_0;
 778        }
 779        else
 780            aFormat = kCFPropertyListXMLFormat_v1_0;
 781    }
 782    if (aFormat == kCFPropertyListXMLFormat_v1_0)
 783        return CPPropertyListCreateFromXMLData(aData);
 784    if (aFormat == kCFPropertyList280NorthFormat_v1_0)
 785        return CPPropertyListCreateFrom280NorthData(aData);
 786    return NULL;
 787}
 788var _CPPropertyListSerializeObject = function(aPlist, serializers)
 789{
 790    var type = typeof aPlist,
 791        valueOf = aPlist.valueOf(),
 792        typeValueOf = typeof valueOf;
 793    if (type != typeValueOf)
 794    {
 795        type = typeValueOf;
 796        aPlist = valueOf;
 797    }
 798    if (type == "string")
 799        return serializers["string"](aPlist, serializers);
 800    else if (aPlist === true || aPlist === false)
 801        return serializers["boolean"](aPlist, serializers);
 802    else if (type == "number")
 803    {
 804        var integer = FLOOR(aPlist);
 805        if (integer == aPlist)
 806            return serializers["integer"](aPlist, serializers);
 807        else
 808            return serializers["real"](aPlist, serializers);
 809    }
 810    else if (aPlist.slice)
 811        return serializers["array"](aPlist, serializers);
 812    else
 813        return serializers["dictionary"](aPlist, serializers);
 814}
 815var XML_XML = "xml",
 816    XML_DOCUMENT = "#document",
 817    PLIST_PLIST = "plist",
 818    PLIST_KEY = "key",
 819    PLIST_DICTIONARY = "dict",
 820    PLIST_ARRAY = "array",
 821    PLIST_STRING = "string",
 822    PLIST_BOOLEAN_TRUE = "true",
 823    PLIST_BOOLEAN_FALSE = "false",
 824    PLIST_NUMBER_REAL = "real",
 825    PLIST_NUMBER_INTEGER = "integer",
 826    PLIST_DATA = "data";
 827var _plist_traverseNextNode = function(anXMLNode, stayWithin, stack)
 828{
 829    var node = anXMLNode;
 830    node = (node.firstChild); if (node != NULL && ((node.nodeType) == 8 || (node.nodeType) == 3)) while ((node = (node.nextSibling)) && ((node.nodeType) == 8 || (node.nodeType) == 3)) ;;
 831    if (node)
 832        return node;
 833    if ((String(anXMLNode.nodeName)) == PLIST_ARRAY || (String(anXMLNode.nodeName)) == PLIST_DICTIONARY)
 834        stack.pop();
 835    else
 836    {
 837        if (node == stayWithin)
 838            return NULL;
 839        node = anXMLNode;
 840        while ((node = (node.nextSibling)) && ((node.nodeType) == 8 || (node.nodeType) == 3)) ;;
 841        if (node)
 842            return node;
 843    }
 844    node = anXMLNode;
 845    while (node)
 846    {
 847        var next = node;
 848        while ((next = (next.nextSibling)) && ((next.nodeType) == 8 || (next.nodeType) == 3)) ;;
 849        if (next)
 850            return next;
 851        var node = (node.parentNode);
 852        if (stayWithin && node == stayWithin)
 853            return NULL;
 854        stack.pop();
 855    }
 856    return NULL;
 857}
 858function CPPropertyListCreateFromXMLData(XMLNodeOrData)
 859{
 860    var XMLNode = XMLNodeOrData;
 861    if (XMLNode.string)
 862    {
 863        if (window.ActiveXObject)
 864        {
 865            XMLNode = new ActiveXObject("Microsoft.XMLDOM");
 866            XMLNode.loadXML(XMLNodeOrData.string.substr(XMLNodeOrData.string.indexOf(".dtd\">") + 6));
 867        }
 868        else
 869            XMLNode = (new DOMParser().parseFromString(XMLNodeOrData.string, "text/xml").documentElement);
 870    }
 871    while (((String(XMLNode.nodeName)) == XML_DOCUMENT) || ((String(XMLNode.nodeName)) == XML_XML))
 872        XMLNode = (XMLNode.firstChild); if (XMLNode != NULL && ((XMLNode.nodeType) == 8 || (XMLNode.nodeType) == 3)) while ((XMLNode = (XMLNode.nextSibling)) && ((XMLNode.nodeType) == 8 || (XMLNode.nodeType) == 3)) ;;
 873    if (((XMLNode.nodeType) == 10))
 874        while ((XMLNode = (XMLNode.nextSibling)) && ((XMLNode.nodeType) == 8 || (XMLNode.nodeType) == 3)) ;;
 875    if (!((String(XMLNode.nodeName)) == PLIST_PLIST))
 876        return NULL;
 877    var key = "",
 878        object = NULL,
 879        plistObject = NULL,
 880        plistNode = XMLNode,
 881        containers = [],
 882        currentContainer = NULL;
 883    while (XMLNode = _plist_traverseNextNode(XMLNode, plistNode, containers))
 884    {
 885        var count = containers.length;
 886        if (count)
 887            currentContainer = containers[count - 1];
 888        if ((String(XMLNode.nodeName)) == PLIST_KEY)
 889        {
 890            key = ((String((XMLNode.firstChild).nodeValue)));
 891            while ((XMLNode = (XMLNode.nextSibling)) && ((XMLNode.nodeType) == 8 || (XMLNode.nodeType) == 3)) ;;
 892        }
 893        switch (String((String(XMLNode.nodeName))))
 894        {
 895            case PLIST_ARRAY: object = []
 896                                        containers.push(object);
 897                                        break;
 898            case PLIST_DICTIONARY: object = new objj_dictionary();
 899                                        containers.push(object);
 900                                        break;
 901            case PLIST_NUMBER_REAL: object = parseFloat(((String((XMLNode.firstChild).nodeValue))));
 902                                        break;
 903            case PLIST_NUMBER_INTEGER: object = parseInt(((String((XMLNode.firstChild).nodeValue))));
 904                                        break;
 905            case PLIST_STRING: object = _decodeHTMLComponent((XMLNode.firstChild) ? ((String((XMLNode.firstChild).nodeValue))) : "");
 906                                        break;
 907            case PLIST_BOOLEAN_TRUE: object = true;
 908                                        break;
 909            case PLIST_BOOLEAN_FALSE: object = false;
 910                                        break;
 911            case PLIST_DATA: object = new objj_data();
 912                                        object.bytes = (XMLNode.firstChild) ? base64_decode_to_array(((String((XMLNode.firstChild).nodeValue))), true) : [];
 913                                        break;
 914            default: objj_exception_throw(new objj_exception(OBJJPlistParseException, "*** " + (String(XMLNode.nodeName)) + " tag not recognized in Plist."));
 915        }
 916        if (!plistObject)
 917            plistObject = object;
 918        else if (currentContainer)
 919            if (currentContainer.slice)
 920                currentContainer.push(object);
 921            else
 922                { if ((currentContainer)._buckets[key] == NULL) { (currentContainer)._keys.push(key); ++(currentContainer).count; } if (((currentContainer)._buckets[key] = object) == NULL) --(currentContainer).count;};
 923    }
 924    return plistObject;
 925}
 926function CPPropertyListCreateXMLData(aPlist)
 927{
 928    var data = new objj_data();
 929    data.string = "";
 930    data.string += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
 931    data.string += "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">";
 932    data.string += "<plist version = \"1.0\">";
 933    _CPPropertyListAppendXMLData(data, aPlist, "");
 934    data.string += "</plist>";
 935    return data;
 936}
 937var _CPArrayAppendXMLData = function(XMLData, anArray)
 938{
 939    var i = 0,
 940        count = anArray.length;
 941    XMLData.string += "<array>";
 942    for (; i < count; ++i)
 943        _CPPropertyListAppendXMLData(XMLData, anArray[i]);
 944    XMLData.string += "</array>";
 945}
 946var _CPDictionaryAppendXMLData = function(XMLData, aDictionary)
 947{
 948    var keys = aDictionary._keys,
 949        i = 0,
 950        count = keys.length;
 951    XMLData.string += "<dict>";
 952    for (; i < count; ++i)
 953    {
 954        XMLData.string += "<key>" + keys[i] + "</key>";
 955        _CPPropertyListAppendXMLData(XMLData, ((aDictionary)._buckets[keys[i]]));
 956    }
 957    XMLData.string += "</dict>";
 958}
 959var _encodeHTMLComponent = function(aString)
 960{
 961    return aString.replace('<', "&lt;").replace('>', "&gt;").replace('\"', "&quot;").replace('\'', "&apos;").replace('&', "&amp;");
 962}
 963var _decodeHTMLComponent = function(aString)
 964{
 965    return aString.replace("&lt;", '<').replace("&gt;", '>').replace("&quot;", '\"').replace("&apos;", '\'').replace("&amp;", '&');
 966}
 967var _CPPropertyListAppendXMLData = function(XMLData, aPlist)
 968{
 969    var type = typeof aPlist,
 970        valueOf = aPlist.valueOf(),
 971        typeValueOf = typeof valueOf;
 972    if (type != typeValueOf)
 973    {
 974        type = typeValueOf;
 975        aPlist = valueOf;
 976    }
 977    if (type == "string")
 978        XMLData.string += "<string>" + _encodeHTMLComponent(aPlist) + "</string>";
 979    else if (aPlist === true)
 980        XMLData.string += "<true/>";
 981    else if (aPlist === false)
 982        XMLData.string += "<false/>";
 983    else if (type == "number")
 984    {
 985        var integer = FLOOR(aPlist);
 986        if (integer == aPlist)
 987            XMLData.string += "<integer>" + aPlist + "</integer>";
 988        else
 989            XMLData.string += "<real>" + aPlist + "</real>";
 990    }
 991    else if (aPlist.slice)
 992        _CPArrayAppendXMLData(XMLData, aPlist);
 993    else if (aPlist._keys)
 994        _CPDictionaryAppendXMLData(XMLData, aPlist);
 995    else
 996        objj_exception_throw(new objj_exception(OBJJPlistSerializeException, "*** unknown plist ("+aPlist+") type: " + type));
 997}
 998var ARRAY_MARKER = "A",
 999    DICTIONARY_MARKER = "D",
1000    FLOAT_MARKER = "f",
1001    INTEGER_MARKER = "d",
1002    STRING_MARKER = "S",
1003    TRUE_MARKER = "T",
1004    FALSE_MARKER = "F",
1005    KEY_MARKER = "K",
1006    END_MARKER = "E";
1007function CPPropertyListCreateFrom280NorthData(aData)
1008{
1009    var stream = new objj_markedStream(aData.string),
1010        marker = NULL,
1011        key = "",
1012        object = NULL,
1013        plistObject = NULL,
1014        containers = [],
1015        currentContainer = NULL;
1016    while (marker = stream.getMarker())
1017    {
1018        if (marker === END_MARKER)
1019        {
1020            containers.pop();
1021            continue;
1022        }
1023        var count = containers.length;
1024        if (count)
1025            currentContainer = containers[count - 1];
1026        if (marker === KEY_MARKER)
1027        {
1028            key = stream.getString();
1029            marker = stream.getMarker();
1030        }
1031        switch (marker)
1032        {
1033            case ARRAY_MARKER: object = []
1034                                    containers.push(object);
1035                                    break;
1036            case DICTIONARY_MARKER: object = new objj_dictionary();
1037                                    containers.push(object);
1038                                    break;
1039            case FLOAT_MARKER: object = parseFloat(stream.getString());
1040                                    break;
1041            case INTEGER_MARKER: object = parseInt(stream.getString());
1042                                    break;
1043            case STRING_MARKER: object = stream.getString();
1044                                    break;
1045            case TRUE_MARKER: object = true;
1046                                    break;
1047            case FALSE_MARKER: object = false;
1048                                    break;
1049            default: objj_exception_throw(new objj_exception(OBJJPlistParseException, "*** " + marker + " marker not recognized in Plist."));
1050        }
1051        if (!plistObject)
1052            plistObject = object;
1053        else if (currentContainer)
1054            if (currentContainer.slice)
1055                currentContainer.push(object);
1056            else
1057                { if ((currentContainer)._buckets[key] == NULL) { (currentContainer)._keys.push(key); ++(currentContainer).count; } if (((currentContainer)._buckets[key] = object) == NULL) --(currentContainer).count;};
1058    }
1059    return plistObject;
1060}
1061function CPPropertyListCreate280NorthData(aPlist)
1062{
1063    var data = new objj_data();
1064    data.string = kCFPropertyList280NorthMagicNumber + ";1.0;" + _CPPropertyListSerializeObject(aPlist, _CPPropertyList280NorthSerializers);
1065    return data;
1066}
1067var _CPPropertyList280NorthSerializers = {};
1068_CPPropertyList280NorthSerializers["string"] = function(aString)
1069{
1070    return STRING_MARKER + ';' + aString.length + ';' + aString;
1071}
1072_CPPropertyList280NorthSerializers["boolean"] = function(aBoolean)
1073{
1074    return (aBoolean ? TRUE_MARKER : FALSE_MARKER) + ';';
1075}
1076_CPPropertyList280NorthSerializers["integer"] = function(anInteger)
1077{
1078    var string = "" + anInteger;
1079    return INTEGER_MARKER + ';' + string.length + ';' + string;
1080}
1081_CPPropertyList280NorthSerializers["real"] = function(aFloat)
1082{
1083    var string = "" + aFloat;
1084    return FLOAT_MARKER + ';' + string.length + ';' + string;
1085}
1086_CPPropertyList280NorthSerializers["array"] = function(anArray, serializers)
1087{
1088    var index = 0,
1089        count = anArray.length,
1090        string = ARRAY_MARKER + ';';
1091    for (; index < count; ++index)
1092        string += _CPPropertyListSerializeObject(anArray[index], serializers);
1093    return string + END_MARKER + ';';
1094}
1095_CPPropertyList280NorthSerializers["dictionary"] = function(aDictionary, serializers)
1096{
1097    var keys = aDictionary._keys,
1098        index = 0,
1099        count = keys.length,
1100        string = DICTIONARY_MARKER +';';
1101    for (; index < count; ++index)
1102    {
1103        var key = keys[index];
1104        string += KEY_MARKER + ';' + key.length + ';' + key;
1105        string += _CPPropertyListSerializeObject(((aDictionary)._buckets[key]), serializers);
1106    }
1107    return string + END_MARKER + ';';
1108}
1109var OBJJ_PLATFORMS = ["browser", "objj"];
1110var OBJJFileNotFoundException = "OBJJFileNotFoundException",
1111    OBJJExecutableNotFoundException = "OBJJExecutableNotFoundException";
1112var objj_files = { },
1113    objj_bundles = { },
1114    objj_bundlesForClass = { },
1115    objj_searches = { };
1116var OBJJ_NO_FILE = {};
1117if (typeof OBJJ_INCLUDE_PATHS === "undefined")
1118    OBJJ_INCLUDE_PATHS = ["Frameworks", "SomethingElse"];
1119var OBJJ_BASE_URI = "";
1120if (window.opera) {
1121var DOMBaseElement = document.getElementsByTagName("base")[0];
1122if (DOMBaseElement)
1123    OBJJ_BASE_URI = (DOMBaseElement.getAttribute('href')).substr(0, (DOMBaseElement.getAttribute('href')).lastIndexOf('/') + 1);
1124}
1125function objj_file()
1126{
1127    this.path = NULL;
1128    this.bundle = NULL;
1129    this.included = NO;
1130    this.contents = NULL;
1131    this.fragments = NULL;
1132}
1133function objj_bundle()
1134{
1135    this.path = NULL;
1136    this.info = NULL;
1137    this.__address = (OBJECT_COUNT++);
1138}
1139function objj_getBundleWithPath(aPath)
1140{
1141    return objj_bundles[aPath];
1142}
1143function objj_setBundleForPath(aPath, aBundle)
1144{
1145    objj_bundles[aPath] = aBundle;
1146}
1147function objj_bundleForClass(aClass)
1148{
1149    return objj_bundlesForClass[aClass.name];
1150}
1151function objj_addClassForBundle(aClass, aBundle)
1152{
1153    objj_bundlesForClass[aClass.name] = aBundle;
1154}
1155function objj_request_file(aFilePath, shouldSearchLocally, aCallback)
1156{
1157    new objj_search(aFilePath, shouldSearchLocally, aCallback).attemptNextSearchPath();
1158}
1159var objj_search = function(aFilePath, shouldSearchLocally, aCallback)
1160{
1161    this.filePath = aFilePath;
1162    this.bundle = NULL;
1163    this.bundleObservers = [];
1164    this.searchPath = NULL;
1165    this.searchedPaths = [];
1166    this.includePathsIndex = shouldSearchLocally ? -1 : 0;
1167    this.searchRequest = NULL;
1168    this.didCompleteCallback = aCallback;
1169}
1170objj_search.prototype.nextSearchPath = function()
1171{
1172    var path = objj_standardize_path((this.includePathsIndex == -1 ? "" : OBJJ_INCLUDE_PATHS[this.includePathsIndex] + '/') + this.filePath);
1173    ++this.includePathsIndex;
1174    return path;
1175}
1176objj_search.prototype.attemptNextSearchPath = function()
1177{
1178    var searchPath = this.nextSearchPath();
1179    file = objj_files[searchPath];
1180    objj_alert("Will attempt to find " + this.filePath + " at " + searchPath);
1181    if (file)
1182    {
1183        objj_alert("The file request at " + this.filePath + " has already been downloaded at " + searchPath);
1184        if (this.didCompleteCallback)
1185            this.didCompleteCallback(file);
1186        return;
1187    }
1188    var existingSearch = objj_searches[searchPath];
1189    if (existingSearch)
1190    {
1191        if (this.didCompleteCallback)
1192            existingSearch.didCompleteCallback = this.didCompleteCallback;
1193        return;
1194    }
1195    this.searchedPaths.push(this.searchPath = searchPath);
1196    var infoPath = objj_standardize_path((searchPath).substr(0, (searchPath).lastIndexOf('/') + 1) + "Info.plist"),
1197        bundle = objj_bundles[infoPath];
1198    if (bundle)
1199    {
1200        this.bundle = bundle;
1201        this.request(searchPath, this.didReceiveSearchResponse);
1202    }
1203    else
1204    {
1205        var existingBundleSearch = objj_searches[infoPath];
1206        if (existingBundleSearch)
1207        {
1208            --this.includePathsIndex;
1209            this.searchedPaths.pop();
1210             if (this.searchedPaths.length)
1211                 this.searchPath = this.searchedPaths[this.searchedPaths.length - 1];
1212             else
1213                 this.searchPath = NULL;
1214            existingBundleSearch.bundleObservers.push(this);
1215            return;
1216        }
1217        else
1218        {
1219            this.bundleObservers.push(this);
1220            this.request(infoPath, this.didReceiveBundleResponse);
1221            if (!this.searchReplaced)
1222                this.searchRequest = this.request(searchPath, this.didReceiveSearchResponse);
1223        }
1224    }
1225}
1226if (window.ActiveXObject) {
1227objj_search.responseCallbackLock = NO;
1228objj_search.responseCallbackQueue = [];
1229objj_search.removeResponseCallbackForFilePath = function(aFilePath)
1230{
1231    var queue = objj_search.responseCallbackQueue,
1232        index = queue.length;
1233    while (index--)
1234        if (queue[index][3] == aFilePath)
1235        {
1236            queue.splice(index, 1);
1237            return;
1238        }
1239}
1240objj_search.serializeResponseCallback = function(aMethod, aSearch, aResponse, aFilePath)
1241{
1242    var queue = objj_search.responseCallbackQueue;
1243    queue.push([aMethod, aSearch, aResponse, aFilePath]);
1244    if (objj_search.responseCallbackLock)
1245        return;
1246    objj_search.responseCallbackLock = YES;
1247    while (queue.length)
1248    {
1249        var callback = queue[0];
1250        queue.splice(0, 1);
1251        callback[0].apply(callback[1], [callback[2]]);
1252    }
1253    objj_search.responseCallbackLock = NO;
1254}
1255}
1256objj_search.prototype.request = function(aFilePath, aMethod)
1257{
1258    var search = this,
1259        isPlist = aFilePath.substr(aFilePath.length - 6, 6) == ".plist",
1260        request = objj_request_xmlhttp(),
1261        response = objj_response_xmlhttp();
1262    response.filePath = aFilePath;
1263    request.onreadystatechange = function()
1264    {
1265        if (request.readyState == 4)
1266        {
1267            if (response.success = (request.status != 404 && request.responseText && request.responseText.length) ? YES : NO)
1268            {
1269                if (window.files_total)
1270                {
1271                    if (!window.files_loaded)
1272                        window.files_loaded = 0;
1273                    window.files_loaded += request.responseText.length;
1274                    if (window.update_progress)
1275                        window.update_progress(window.files_loaded / window.files_total);
1276                }
1277                if (isPlist)
1278                    response.xml = objj_standardize_xml(request);
1279                else
1280                    response.text = request.responseText;
1281            }
1282            if (window.ActiveXObject)
1283                objj_search.serializeResponseCallback(aMethod, search, response, aFilePath);
1284            else
1285                aMethod.apply(search, [response]);
1286        }
1287    }
1288    objj_searches[aFilePath] = this;
1289    if (request.overrideMimeType && isPlist)
1290        request.overrideMimeType('text/xml');
1291    if (window.opera && aFilePath.charAt(0) != '/')
1292        aFilePath = OBJJ_BASE_URI + aFilePath;
1293    try
1294    {
1295        request.open("GET", aFilePath, YES);
1296        request.send("");
1297    }
1298    catch (anException)
1299    {
1300        response.success = NO;
1301        if (window.ActiveXObject)
1302            objj_search.serializeResponseCallback(aMethod, search, response, aFilePath);
1303        else
1304            aMethod.apply(search, [response]);
1305    }
1306    return request;
1307}
1308objj_search.prototype.didReceiveSearchResponse = function(aResponse)
1309{
1310    if (!this.bundle)
1311    {
1312        this.cachedSearchResponse = aResponse;
1313        return;
1314    }
1315    if (aResponse.success)
1316    {
1317        file = new objj_file();
1318        file.path = aResponse.filePath;
1319        file.bundle = this.bundle
1320        file.contents = aResponse.text;
1321        this.complete(file);
1322    }
1323    else if (this.includePathsIndex < OBJJ_INCLUDE_PATHS.length)
1324    {
1325        this.bundle = NULL;
1326        this.attemptNextSearchPath();
1327    }
1328    else
1329        objj_exception_throw(new objj_exception(OBJJFileNotFoundException, "*** Could not locate file named \"" + this.filePath + "\" in search paths."));
1330}
1331objj_search.prototype.didReceiveBundleResponse = function(aResponse)
1332{
1333    var bundle = new objj_bundle();
1334    bundle.path = aResponse.filePath;
1335    if (aResponse.success)
1336        bundle.info = CPPropertyListCreateFromXMLData(aResponse.xml);
1337    else
1338        bundle.info = new objj_dictionary();
1339    objj_bundles[aResponse.filePath] = bundle;
1340    var executablePath = ((bundle.info)._buckets["CPBundleExecutable"]);
1341    if (executablePath)
1342    {
1343        var platform = NULL,
1344            platforms = ((bundle.info)._buckets["CPBundlePlatforms"]),
1345            index = 0,
1346            count = OBJJ_PLATFORMS.length,
1347            innerCount = platforms.length;
1348        for(; index < count; ++index)
1349        {
1350            var innerIndex = 0,
1351                currentPlatform = OBJJ_PLATFORMS[index];
1352            for (; innerIndex < innerCount; ++innerIndex)
1353                if(currentPlatform === platforms[innerIndex])
1354                {
1355                    platform = currentPlatform;
1356                    break;
1357                }
1358        }
1359        executablePath = platform + ".platform/" + executablePath;
1360        this.request((aResponse.filePath).substr(0, (aResponse.filePath).lastIndexOf('/') + 1) + executablePath, this.didReceiveExecutableResponse);
1361        var directory = (aResponse.filePath).substr(0, (aResponse.filePath).lastIndexOf('/') + 1),
1362            replacedFiles = ((bundle.info)._buckets["CPBundleReplacedFiles"]),
1363            index = 0,
1364            count = replacedFiles.length;
1365        for (; index < count; ++index)
1366        {
1367            objj_searches[directory + replacedFiles[index]] = this;
1368            if (directory + replacedFiles[index] == this.searchPath)
1369            {
1370                this.searchReplaced = YES;
1371                if (!this.cachedSearchResponse && this.searchRequest)
1372                    this.searchRequest.abort();
1373                if (window.ActiveXObject)
1374                    objj_search.removeResponseCallbackForFilePath(this.searchPath);
1375            }
1376        }
1377    }
1378    this.bundle = bundle;
1379    var observers = this.bundleObservers,
1380        index = 0,
1381        count = observers.length;
1382    for(; index < count; ++index)
1383    {
1384        var observer = observers[index];
1385        if (observer != this)
1386            observer.attemptNextSearchPath();
1387        else if (this.cachedSearchResponse && !this.searchReplaced)
1388            this.didReceiveSearchResponse(this.cachedSearchResponse);
1389    }
1390    this.bundleObservers = [];
1391}
1392objj_search.prototype.didReceiveExecutableResponse = function(aResponse)
1393{
1394    if (!aResponse.success)
1395        objj_exception_throw(new objj_exception(OBJJExecutableNotFoundException, "*** The specified executable could not be located at \"" + this.filePath + "\"."));
1396    var files = objj_decompile(aResponse.text, this.bundle),
1397        index = 0,
1398        count = files.length,
1399        length = this.filePath.length;
1400    for (; index < count; ++index)
1401    {
1402        var file = files[index],
1403            path = file.path;
1404        if (this.filePath == path.substr(path.length - length))
1405            this.complete(file);
1406        else
1407            objj_files[path] = file;
1408    }
1409}
1410objj_search.prototype.complete = function(aFile)
1411{
1412    var index = 0,
1413        count = this.searchedPaths.length;
1414    for (; index < count; ++index)
1415    {
1416        objj_files[this.searchedPaths[index]] = aFile;
1417    }
1418    if (this.didCompleteCallback)
1419        this.didCompleteCallback(aFile);
1420}
1421function objj_standardize_path(aPath)
1422{
1423    if (aPath.indexOf("/./") != -1 && aPath.indexOf("//") != -1 && aPath.indexOf("/../") != -1)
1424        return aPath;
1425    var index = 0,
1426        components = aPath.split('/');
1427    for(;index < components.length; ++index)
1428        if(components[index] == "..")
1429        {
1430            components.splice(index - 1, 2);
1431            index -= 2;
1432        }
1433        else if(index != 0 && !components[index].length || components[index] == '.' || components[index] == "..")
1434            components.splice(index--, 1);
1435    return components.join('/');
1436}
1437if (window.ActiveXObject) {
1438var objj_standardize_xml = function(aRequest)
1439{
1440    var XMLData = new ActiveXObject("Microsoft.XMLDOM");
1441    XMLData.loadXML(aRequest.responseText.substr(aRequest.responseText.indexOf(".dtd\">") + 6));
1442    return XMLData;
1443}
1444} else {
1445var objj_standardize_xml = function(aRequest)
1446{
1447    return aRequest.responseXML;
1448}
1449}
1450function objj_response_xmlhttp()
1451{
1452    return new Object;
1453}
1454if (window.XMLHttpRequest) {
1455var objj_request_xmlhttp = function()
1456{
1457    return new XMLHttpRequest();
1458}
1459} else if (window.ActiveXObject) {
1460var MSXML_XMLHTTP_OBJECTS = [ "Microsoft.XMLHTTP", "Msxml2.XMLHTTP", "Msxml2.XMLHTTP.3.0", "Msxml2.XMLHTTP.6.0" ],
1461    index = MSXML_XMLHTTP_OBJECTS.length;
1462while (index--)
1463{
1464    try
1465    {
1466        new ActiveXO

Large files files are truncated, but you can click here to view the full file