win = new Window("dialog", "高光修复");
win.orientation = "column";
b1L = 150;
b2L = 260;
leftGr = win.add("group");
leftGr.orientation = "column";
baton259 = leftGr.add("group");
baton259.alignment = "left";
Generate1 = baton259.add("button", undefined, "CBR 方式");
Generate1.preferredSize.width = b1L;
baton289 = leftGr.add("group");
baton289.alignment = "left";
Generate2 = baton289.add("button", undefined, "CRW 方式");
Generate2.preferredSize.width = b1L;
Generate1.onClick = function() {
    historyState = "Ultimate Retouch - CBR Method";
    if (app) {
        ErrStrs = {};
        ErrStrs.USER_CANCELED = localize("$$$/ScriptingSupport/Errors/UserCancelled");
        var historyStateNow = -1;
        do {
            historyStateNow++
        } while (app.activeDocument.activeHistoryState != app.activeDocument.historyStates[historyStateNow])
        try {
            app.activeDocument.suspendHistory(historyState, "Frezze()");
        } catch (e) {
            if (e.number != 8007) {
                alert(e + " : " + e.line);
            }
        }
    }

    function Frezze() {
        function HLRESTORE() {
            function step1(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                var ref1 = new ActionReference();
                ref1.putClass(PSClass.Layer);
                desc1.putReference(PSString.Null, ref1);
                desc1.putInteger(PSKey.LayerID, 81);
                executeAction(PSEvent.Make, desc1, dialogMode);
            }

            function step2(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                var ref1 = new ActionReference();
                ref1.putEnumerated(PSClass.Layer, PSType.Ordinal, PSEnum.Target);
                desc1.putReference(PSString.Null, ref1);
                var desc2 = new ActionDescriptor();
                desc2.putString(PSKey.Name, "temp");
                desc1.putObject(PSKey.To, PSClass.Layer, desc2);
                executeAction(PSEvent.Set, desc1, dialogMode);
            }

            function step3(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                var ref1 = new ActionReference();
                ref1.putEnumerated(PSClass.Layer, PSType.Ordinal, PSEnum.Target);
                desc1.putReference(PSString.Null, ref1);
                var desc2 = new ActionDescriptor();
                desc2.putString(PSKey.Name, "CBR Method");
                desc1.putObject(PSKey.To, PSClass.Layer, desc2);
                executeAction(PSEvent.Set, desc1, dialogMode);
            }

            function step4(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                var ref1 = new ActionReference();
                ref1.putEnumerated(PSClass.Layer, PSType.Ordinal, PSEnum.Target);
                desc1.putReference(PSString.Null, ref1);
                var desc2 = new ActionDescriptor();
                desc2.putEnumerated(PSKey.Color, PSKey.Color, PSEnum.Blue);
                desc1.putObject(PSKey.To, PSClass.Layer, desc2);
                executeAction(PSEvent.Set, desc1, dialogMode);
            }

            function step5(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                desc1.putBoolean(PSKey.Duplicate, true);
                executeAction(sTID("mergeVisible"), desc1, dialogMode);
            }

            function step6(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                var ref1 = new ActionReference();
                ref1.putClass(PSClass.Layer);
                desc1.putReference(PSString.Null, ref1);
                desc1.putInteger(PSKey.LayerID, 33);
                executeAction(PSEvent.Make, desc1, dialogMode);
            }

            function step7(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                var ref1 = new ActionReference();
                ref1.putEnumerated(PSClass.Layer, PSType.Ordinal, PSEnum.Target);
                desc1.putReference(PSString.Null, ref1);
                var desc2 = new ActionDescriptor();
                desc2.putString(PSKey.Name, "Highlights Restore");
                desc1.putObject(PSKey.To, PSClass.Layer, desc2);
                executeAction(PSEvent.Set, desc1, dialogMode);
            }

            function step8(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                var desc2 = new ActionDescriptor();
                var ref1 = new ActionReference();
                ref1.putEnumerated(PSClass.Channel, PSClass.Channel, PSEnum.Blue);
                ref1.putEnumerated(PSClass.Layer, PSType.Ordinal, PSEnum.Merged);
                desc2.putReference(PSKey.To, ref1);
                desc1.putObject(PSKey.With, PSClass.Calculation, desc2);
                executeAction(sTID("applyImageEvent"), desc1, dialogMode);
            }

            function step9(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                executeAction(PSEvent.Invert, undefined, dialogMode);
            }

            function step10(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                desc1.putEnumerated(PSString.presetKind, PSString.presetKindType, PSString.presetKindCustom);
                var list1 = new ActionList();
                var desc2 = new ActionDescriptor();
                var ref1 = new ActionReference();
                ref1.putEnumerated(PSClass.Channel, PSClass.Channel, PSEnum.Composite);
                desc2.putReference(PSClass.Channel, ref1);
                var list2 = new ActionList();
                var desc3 = new ActionDescriptor();
                desc3.putDouble(PSKey.Horizontal, 0);
                desc3.putDouble(PSKey.Vertical, 101);
                list2.putObject(PSClass.Point, desc3);
                var desc4 = new ActionDescriptor();
                desc4.putDouble(PSKey.Horizontal, 137);
                desc4.putDouble(PSKey.Vertical, 255);
                list2.putObject(PSClass.Point, desc4);
                desc2.putList(PSKey.Curve, list2);
                list1.putObject(PSClass.CurvesAdjustment, desc2);
                desc1.putList(PSKey.Adjustment, list1);
                executeAction(PSEvent.Curves, desc1, dialogMode);
            }

            function step11(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                desc1.putUnitDouble(PSKey.Radius, PSUnit.Pixels, 4);
                executeAction(sTID("gaussianBlur"), desc1, dialogMode);
            }

            function step12(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                var ref1 = new ActionReference();
                ref1.putEnumerated(PSClass.Layer, PSType.Ordinal, PSEnum.Target);
                desc1.putReference(PSString.Null, ref1);
                var desc2 = new ActionDescriptor();
                desc2.putEnumerated(PSKey.Mode, PSType.BlendMode, PSEnum.ColorBurn);
                desc1.putObject(PSKey.To, PSClass.Layer, desc2);
                executeAction(PSEvent.Set, desc1, dialogMode);
            }

            function step13(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                executeAction(sTID("mergeLayersNew"), desc1, dialogMode);
            }

            function step14(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                desc1.putClass(PSKey.New, PSClass.Channel);
                var ref1 = new ActionReference();
                ref1.putEnumerated(PSClass.Channel, PSClass.Channel, PSClass.Mask);
                desc1.putReference(PSKey.At, ref1);
                desc1.putEnumerated(PSKey.Using, PSType.UserMaskOptions, PSEnum.HideAll);
                executeAction(PSEvent.Make, desc1, dialogMode);
            }

            function step15(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                var ref1 = new ActionReference();
                ref1.putClass(PSClass.PaintbrushTool);
                desc1.putReference(PSString.Null, ref1);
                executeAction(PSEvent.Select, desc1, dialogMode);
            }

            function step16(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                var ref1 = new ActionReference();
                ref1.putProperty(PSKey.Color, PSEnum.ForegroundColor);
                desc1.putReference(PSString.Null, ref1);
                var desc2 = new ActionDescriptor();
                desc2.putUnitDouble(PSKey.Hue, PSUnit.Angle, 0);
                desc2.putDouble(PSKey.Start, 0);
                desc2.putDouble(PSKey.Brightness, 100);
                desc1.putObject(PSKey.To, PSClass.HSBColor, desc2);
                desc1.putString(PSKey.Source, "photoshopPicker");
                executeAction(PSEvent.Set, desc1, dialogMode);
            }

            function step17(enabled, withDialog) {
                if (enabled != undefined && !enabled) {
                    return;
                }
                var dialogMode = withDialog ? DialogModes.ALL : DialogModes.NO;
                var desc1 = new ActionDescriptor();
                var ref1 = new ActionReference();
                ref1.putProperty(PSKey.Color, PSEnum.BackgroundColor);
                desc1.putReference(PSString.Null, ref1);
                var desc2 = new ActionDescriptor();
                desc2.putUnitDouble(PSKey.Hue, PSUnit.Angle, 0);
                desc2.putDouble(PSKey.Start, 0);
                desc2.putDouble(PSKey.Brightness, 0);
                desc1.putObject(PSKey.To, PSClass.HSBColor, desc2);
                desc1.putString(PSKey.Source, "photoshopPicker");
                executeAction(PSEvent.Set, desc1, dialogMode);
            }
            step1();
            step2();
            step3();
            step4();
            step5();
            step6();
            step7();
            step8();
            step9();
            step10();
            step11();
            step12();
            step13();
            step14();
            step15();
            step16();
            step17();
        }
        cTID = function(s) {
            return app.charIDToTypeID(s);
        };
        sTID = function(s) {
            return app.stringIDToTypeID(s);
        };
        HLRESTORE.loadSymbols = function() {
            var dbgLevel = $.level;
            $.level = 0;
            try {
                PSConstants;
                return;
            } catch (e) {

            } finally {
                $.level = dbgLevel;
            }
            var needDefs = true;
            $.level = 0;
            try {
                PSClass;
                needDefs = false;
            } catch (e) {

            } finally {
                $.level = dbgLevel;
            }
            if (needDefs) {
                PSClass = function() {

                };
                PSEnum = function() {

                };
                PSEvent = function() {

                };
                PSForm = function() {

                };
                PSKey = function() {

                };
                PSType = function() {

                };
                PSUnit = function() {

                };
                PSString = function() {

                };
            }
            PSClass.Calculation = cTID("Clcl");
            PSClass.Channel = cTID("Chnl");
            PSClass.CurvesAdjustment = cTID("CrvA");
            PSClass.HSBColor = cTID("HSBC");
            PSClass.Layer = cTID("Lyr ");
            PSClass.Mask = cTID("Msk ");
            PSClass.PaintbrushTool = cTID("PbTl");
            PSClass.Point = cTID("Pnt ");
            PSEnum.BackgroundColor = cTID("BckC");
            PSEnum.Blue = cTID("Bl  ");
            PSEnum.ColorBurn = cTID("CBrn");
            PSEnum.Composite = cTID("Cmps");
            PSEnum.ForegroundColor = cTID("FrgC");
            PSEnum.HideAll = cTID("HdAl");
            PSEnum.Merged = cTID("Mrgd");
            PSEnum.Target = cTID("Trgt");
            PSEvent.Curves = cTID("Crvs");
            PSEvent.Invert = cTID("Invr");
            PSEvent.Make = cTID("Mk  ");
            PSEvent.Select = cTID("slct");
            PSEvent.Set = cTID("setd");
            PSKey.Adjustment = cTID("Adjs");
            PSKey.At = cTID("At  ");
            PSKey.Brightness = cTID("Brgh");
            PSKey.Color = cTID("Clr ");
            PSKey.Curve = cTID("Crv ");
            PSKey.Duplicate = cTID("Dplc");
            PSKey.Horizontal = cTID("Hrzn");
            PSKey.Hue = cTID("H   ");
            PSKey.LayerID = cTID("LyrI");
            PSKey.Mode = cTID("Md  ");
            PSKey.Name = cTID("Nm  ");
            PSKey.New = cTID("Nw  ");
            PSKey.Radius = cTID("Rds ");
            PSKey.Source = cTID("Srce");
            PSKey.Start = cTID("Strt");
            PSKey.To = cTID("T   ");
            PSKey.Using = cTID("Usng");
            PSKey.Vertical = cTID("Vrtc");
            PSKey.With = cTID("With");
            PSString.Null = sTID("null");
            PSString.presetKind = sTID("presetKind");
            PSString.presetKindCustom = sTID("presetKindCustom");
            PSString.presetKindType = sTID("presetKindType");
            PSType.BlendMode = cTID("BlnM");
            PSType.Ordinal = cTID("Ordn");
            PSType.UserMaskOptions = cTID("UsrM");
            PSUnit.Angle = cTID("#Ang");
            PSUnit.Pixels = cTID("#Pxl");
        };
        HLRESTORE.loadSymbols();
        HLRESTORE.main = function() {
            HLRESTORE();
        };
        HLRESTORE.main();
        var idsetd = charIDToTypeID("setd");
        var desc1020 = new ActionDescriptor();
        var idnull = charIDToTypeID("null");
        var ref430 = new ActionReference();
        var idLyr = charIDToTypeID("Lyr ");
        var idOrdn = charIDToTypeID("Ordn");
        var idTrgt = charIDToTypeID("Trgt");
        ref430.putEnumerated(idLyr, idOrdn, idTrgt);
        desc1020.putReference(idnull, ref430);
        var idT = charIDToTypeID("T   ");
        var desc1021 = new ActionDescriptor();
        var idMd = charIDToTypeID("Md  ");
        var idBlnM = charIDToTypeID("BlnM");
        var idLmns = charIDToTypeID("Lmns");
        desc1021.putEnumerated(idMd, idBlnM, idLmns);
        var idLyr = charIDToTypeID("Lyr ");
        desc1020.putObject(idT, idLyr, desc1021);
        executeAction(idsetd, desc1020, DialogModes.NO);
        close = true;
        win.close();
    }
};
Generate2.onClick = function() {
    historyState = "Ultimate Retouch - CRW Method";
    if (app) {
        ErrStrs = {};
        ErrStrs.USER_CANCELED = localize("$$$/ScriptingSupport/Errors/UserCancelled");
        var historyStateNow = -1;
        do {
            historyStateNow++
        } while (app.activeDocument.activeHistoryState != app.activeDocument.historyStates[historyStateNow])
        try {
            app.activeDocument.suspendHistory(historyState, "Frezze()");
        } catch (e) {
            if (e.number != 8007) {
                alert(e + " : " + e.line);
            }
        }
    }

    function Frezze() {
        if (typeof jamEngine !== "object") {
            var jamEngine = {};

            function() {
                function putInReference(ref, containers) {
                    if (containers.constructor === Array) {
                        var count = containers.length;
                        for (var i = 0; i < count; i += 1) {
                            var container = that.parseCompact(containers[i]);
                            var desiredClassId = that.uniIdStrToId(container[0]);
                            var typedValue = that.parseCompact(container[1]);
                            var form = typedValue[0];
                            var value = typedValue[1];
                            switch (form) {
                                case "<class>":
                                    ref.putClass(desiredClassId);
                                    break;
                                case "<enumerated>":
                                    var enumerated = that.parseCompact(value);
                                    ref.putEnumerated(desiredClassId, that.uniIdStrToId(enumerated[0]), that.uniIdStrToId(enumerated[1]));
                                    break;
                                case "<identifier>":
                                    ref.putIdentifier(desiredClassId, value);
                                    break;
                                case "<index>":
                                    ref.putIndex(desiredClassId, value);
                                    break;
                                case "<name>":
                                    ref.putName(desiredClassId, value);
                                    break;
                                case "<offset>":
                                    ref.putOffset(desiredClassId, value);
                                    break;
                                case "<property>":
                                    ref.putProperty(desiredClassId, that.uniIdStrToId(value));
                                    break;
                                default:
                                    throw new Error("[jamEngine putInReference] Unknown reference form: " + form)
                                    break;
                            }
                        }
                    } else {
                        throw new Error("[jamEngine putInReference] JavaScript array expected")
                    }
                }

                function putInList(list, items) {
                    if (items.constructor === Array) {
                        var count = items.length;
                        for (var i = 0; i < count; i += 1) {
                            var item = that.parseCompact(items[i]);
                            var type = item[0];
                            var value = item[1];
                            switch (type) {
                                case "<boolean>":
                                    list.putBoolean(value);
                                    break;
                                case "<class>":
                                    list.putClass(that.uniIdStrToId(value));
                                    break;
                                case "<data>":
                                    list.putData(value);
                                    break;
                                case "<double>":
                                    list.putDouble(value);
                                    break;
                                case "<enumerated>":
                                    var enumerated = that.parseCompact(value);
                                    list.putEnumerated(that.uniIdStrToId(enumerated[0]), that.uniIdStrToId(enumerated[1]));
                                    break;
                                case "<integer>":
                                    list.putInteger(value);
                                    break;
                                case "<largeInteger>":
                                    list.putLargeInteger(value);
                                    break;
                                case "<list>":
                                    var actionList = new ActionList();
                                    putInList(actionList, value);
                                    list.putList(actionList);
                                    break;
                                case "<object>":
                                    var object = that.parseCompact(value);
                                    if (object[1]) {
                                        var actionDescriptor = new ActionDescriptor();
                                        putInDescriptor(actionDescriptor, object[1]);
                                        list.putObject(that.uniIdStrToId(object[0]), actionDescriptor);
                                    } else {
                                        list.putClass(that.uniIdStrToId(object[0]));
                                    }
                                    break;
                                case "<path>":
                                    var fileRef = new File(value);
                                    list.putPath(fileRef);
                                    break;
                                case "<reference>":
                                    var actionReference = new ActionReference();
                                    putInReference(actionReference, value);
                                    list.putReference(actionReference);
                                    break;
                                case "<string>":
                                    list.putString(value);
                                    break;
                                case "<unitDouble>":
                                    var unitDouble = that.parseCompact(value);
                                    list.putUnitDouble(that.uniIdStrToId(unitDouble[0]), unitDouble[1]);
                                    break;
                                default:
                                    throw new Error("[jamEngine putInList] Unknown list type: " + type)
                                    break;
                            }
                        }
                    } else {
                        throw new Error("[jamEngine putInList] JavaScript array expected")
                    }
                }

                function putInDescriptor(desc, members) {
                    if (members.constructor === Object) {
                        for (var key in members) {
                            if (members.hasOwnProperty(key)) {
                                var keyID = that.uniIdStrToId(key);
                                var member = that.parseCompact(members[key]);
                                var type = member[0];
                                var value = member[1];
                                switch (type) {
                                    case "<boolean>":
                                        desc.putBoolean(keyID, value);
                                        break;
                                    case "<class>":
                                        desc.putClass(keyID, that.uniIdStrToId(value));
                                        break;
                                    case "<data>":
                                        desc.putData(keyID, value);
                                        break;
                                    case "<double>":
                                        desc.putDouble(keyID, value);
                                        break;
                                    case "<enumerated>":
                                        var enumerated = that.parseCompact(value);
                                        desc.putEnumerated(keyID, that.uniIdStrToId(enumerated[0]), that.uniIdStrToId(enumerated[1]));
                                        break;
                                    case "<integer>":
                                        desc.putInteger(keyID, value);
                                        break;
                                    case "<largeInteger>":
                                        desc.putLargeInteger(keyID, value);
                                        break;
                                    case "<list>":
                                        var actionList = new ActionList();
                                        putInList(actionList, value);
                                        desc.putList(keyID, actionList);
                                        break;
                                    case "<object>":
                                        var object = that.parseCompact(value);
                                        if (object[1]) {
                                            var actionDescriptor = new ActionDescriptor();
                                            putInDescriptor(actionDescriptor, object[1]);
                                            desc.putObject(keyID, that.uniIdStrToId(object[0]), actionDescriptor);
                                        } else {
                                            desc.putClass(keyID, that.uniIdStrToId(object[0]));
                                        }
                                        break;
                                    case "<path>":
                                        var fileRef = new File(value);
                                        desc.putPath(keyID, fileRef);
                                        break;
                                    case "<reference>":
                                        var actionReference = new ActionReference();
                                        putInReference(actionReference, value);
                                        desc.putReference(keyID, actionReference);
                                        break;
                                    case "<string>":
                                        desc.putString(keyID, value);
                                        break;
                                    case "<unitDouble>":
                                        var unitDouble = that.parseCompact(value);
                                        desc.putUnitDouble(keyID, that.uniIdStrToId(unitDouble[0]), unitDouble[1]);
                                        break;
                                    default:
                                        throw new Error("[jamEngine putInDescriptor] Unknown descriptor type: " + type)
                                        break;
                                }
                            }
                        }
                    } else {
                        throw new Error("[jamEngine putInDescriptor] JavaScript object expected")
                    }
                }

                function getFromId(context, parentContext) {
                    var kind = context[0];
                    var id = context[1];
                    if (id < smallestHashValue) {
                        uniIdStr = app.typeIDToStringID(id);
                    } else {
                        uniIdStr = "'" + app.typeIDToCharID(id) + "'";
                        if (that.meaningfulIds) {
                            if (uniIdStr in contextRules) {
                                function resolveIdStr(candidates) {
                                    var idStr = "";
                                    for (var parentString in candidates) {
                                        if (candidates.hasOwnProperty(parentString)) {
                                            if (parentContext[1] === that.uniIdStrToId(parentString)) {
                                                idStr = candidates[parentString];
                                                break;
                                            }
                                        }
                                    }
                                    return idStr;
                                }
                                var resolvedIdStr = "";
                                var rule = contextRules[uniIdStr];
                                if (parentContext) {
                                    switch (kind) {
                                        case "<key>":
                                            if (parentContext[0] === "<class>" && "<classKey>" in rule) {
                                                resolvedIdStr = resolveIdStr(rule["<classKey>"]);
                                            } else {
                                                if (parentContext[0] === "<event>" && "<eventKey>" in rule) {
                                                    resolvedIdStr = resolveIdStr(rule["<eventKey>"]);
                                                }
                                            }
                                            break;
                                        case "<enumValue>":
                                            if (parentContext[0] === "<enumType>" && "<typeValue>" in rule) {
                                                resolvedIdStr = resolveIdStr(rule["<typeValue>"]);
                                            }
                                            break;
                                    }
                                }
                                if (resolvedIdStr !== "") {
                                    uniIdStr = resolvedIdStr;
                                } else {
                                    if (kind in rule) {
                                        uniIdStr = rule[kind];
                                    }
                                }
                            } else {
                                var stringIDStr = app.typeIDToStringID(id);
                                if (stringIDStr !== "") {
                                    uniIdStr = stringIDStr;
                                }
                            }
                        }
                    }
                    return uniIdStr;
                }

                function getFromReference(ref) {
                    var propertyId = 0;
                    var arr = [];
                    do {
                        try {
                            var desiredClassId = ref.getDesiredClass();
                        } catch (e) {
                            break;
                        }
                        if (propertyId !== 0) {
                            var propertyCompact = that.buildCompact("<property>", getFromId(["<key>", propertyId], ["<class>", desiredClassId]));
                            arr.push(that.buildCompact(getFromId(["<class>", propertyClassId]), propertyCompact));
                            propertyId = 0;
                        }
                        var aFormID = ref.getForm();
                        switch (aFormID) {
                            case ReferenceFormType.CLASSTYPE:
                                desiredCompact = that.buildCompact("<class>", null);
                                break;
                            case ReferenceFormType.ENUMERATED:
                                var enumTypeContext = ["<enumType>", ref.getEnumeratedType()];
                                var enumValueContext = ["<enumValue>", ref.getEnumeratedValue()];
                                desiredCompact = that.buildCompact("<enumerated>", that.buildCompact(getFromId(enumTypeContext), getFromId(enumValueContext, enumTypeContext)));
                                break;
                            case ReferenceFormType.IDENTIFIER:
                                desiredCompact = that.buildCompact("<identifier>", ref.getIdentifier());
                                break;
                            case ReferenceFormType.INDEX:
                                desiredCompact = that.buildCompact("<index>", ref.getIndex());
                                break;
                            case ReferenceFormType.NAME:
                                desiredCompact = that.buildCompact("<name>", ref.getName());
                                break;
                            case ReferenceFormType.OFFSET:
                                desiredCompact = that.buildCompact("<offset>", ref.getOffset());
                                break;
                            case ReferenceFormType.PROPERTY:
                                if (desiredClassId === propertyClassId) {
                                    propertyId = ref.getProperty();
                                } else {
                                    desiredCompact = that.buildCompact("<property>", getFromId(["<key>", ref.getProperty()], ["<class>", desiredClassId]));
                                }
                                break;
                            default:
                                throw new Error("[jamEngine getFromReference] Unknown reference form type: " + aFormID)
                                break;
                        }
                        if (desiredClassId !== propertyClassId) {
                            arr.push(that.buildCompact(getFromId(["<class>", desiredClassId]), desiredCompact));
                        }
                        ref = ref.getContainer();
                    } while (ref)
                    return arr;
                }

                function getFromList(list) {
                    var arr = [];
                    var itemCount = list.count;
                    for (var itemIndex = 0; itemIndex < itemCount; itemIndex += 1) {
                        try {
                            typeID = list.getType(itemIndex);
                        } catch (e) {
                            continue;
                        }
                        switch (typeID) {
                            case DescValueType.BOOLEANTYPE:
                                itemCompact = that.buildCompact("<boolean>", list.getBoolean(itemIndex));
                                break;
                            case DescValueType.CLASSTYPE:
                                itemCompact = that.buildCompact("<class>", getFromId(["<class>", list.getClass(itemIndex)]));
                                break;
                            case DescValueType.DOUBLETYPE:
                                itemCompact = that.buildCompact("<double>", list.getDouble(itemIndex));
                                break;
                            case DescValueType.ENUMERATEDTYPE:
                                var enumTypeContext = ["<enumType>", list.getEnumerationType(itemIndex)];
                                var enumValueContext = ["<enumValue>", list.getEnumerationValue(itemIndex)];
                                itemCompact = that.buildCompact("<enumerated>", that.buildCompact(getFromId(enumTypeContext), getFromId(enumValueContext, enumTypeContext)));
                                break;
                            case DescValueType.INTEGERTYPE:
                                itemCompact = that.buildCompact("<integer>", list.getInteger(itemIndex));
                                break;
                            case DescValueType.LISTTYPE:
                                itemCompact = that.buildCompact("<list>", getFromList(list.getList(itemIndex)));
                                break;
                            case DescValueType.OBJECTTYPE:
                                var objectTypeContext = ["<class>", list.getObjectType(itemIndex)];
                                var objectValue = list.getObjectValue(itemIndex);
                                itemCompact = that.buildCompact("<object>", that.buildCompact(getFromId(objectTypeContext), getFromDescriptor(objectValue, objectTypeContext)));
                                break;
                            case DescValueType.ALIASTYPE:
                                try {
                                    var fileRef = list.getPath(itemIndex);
                                    itemCompact = that.buildCompact("<path>", fileRef.fsName);
                                } catch (e) {
                                    itemCompact = that.buildCompact("<path>", incompatiblePlatformPath);
                                }
                                break;
                            case DescValueType.REFERENCETYPE:
                                itemCompact = that.buildCompact("<reference>", getFromReference(list.getReference(itemIndex)));
                                break;
                            case DescValueType.STRINGTYPE:
                                itemCompact = that.buildCompact("<string>", list.getString(itemIndex));
                                break;
                            case DescValueType.UNITDOUBLE:
                                var unitTypeContext = ["<unit>", list.getUnitDoubleType(itemIndex)];
                                var doubleValue = list.getUnitDoubleValue(itemIndex);
                                itemCompact = that.buildCompact("<unitDouble>", that.buildCompact(getFromId(unitTypeContext), doubleValue));
                                break;
                            default:
                                try {
                                    isRawType = typeID === DescValueType.RAWTYPE;
                                } catch (e) {

                                }
                                try {
                                    isLargeIntegerType = typeID === DescValueType.LARGEINTEGERTYPE;
                                } catch (e) {

                                }
                                if (isRawType) {
                                    itemCompact = that.buildCompact("<data>", list.getData(itemIndex));
                                } else if (isLargeIntegerType) {
                                    itemCompact = that.buildCompact("<largeInteger>", list.getLargeInteger(itemIndex));
                                } else {
                                    throw new Error("[jamEngine getFromList] Unknown descriptor value type: " + typeID)
                                }
                                break;
                        }
                        arr[itemIndex] = itemCompact;
                    }
                    return arr;
                }

                function getFromDescriptor(desc, parentContext) {
                    if (desc) {
                        var obj = {};
                        try {
                            keyCount = desc.count;
                        } catch (e) {
                            return null;
                        }
                        for (var keyIndex = 0; keyIndex < keyCount; keyIndex += 1) {
                            var keyID = desc.getKey(keyIndex);
                            var keyString = getFromId(["<key>", keyID], parentContext);
                            try {
                                typeID = desc.getType(keyID);
                            } catch (e) {
                                continue;
                            }
                            switch (typeID) {
                                case DescValueType.BOOLEANTYPE:
                                    keyCompact = that.buildCompact("<boolean>", desc.getBoolean(keyID));
                                    break;
                                case DescValueType.CLASSTYPE:
                                    keyCompact = that.buildCompact("<class>", getFromId(["<class>", desc.getClass(keyID)]));
                                    break;
                                case DescValueType.DOUBLETYPE:
                                    keyCompact = that.buildCompact("<double>", desc.getDouble(keyID));
                                    break;
                                case DescValueType.ENUMERATEDTYPE:
                                    var enumTypeContext = ["<enumType>", desc.getEnumerationType(keyID)];
                                    var enumValueContext = ["<enumValue>", desc.getEnumerationValue(keyID)];
                                    keyCompact = that.buildCompact("<enumerated>", that.buildCompact(getFromId(enumTypeContext), getFromId(enumValueContext, enumTypeContext)));
                                    break;
                                case DescValueType.INTEGERTYPE:
                                    keyCompact = that.buildCompact("<integer>", desc.getInteger(keyID));
                                    break;
                                case DescValueType.LISTTYPE:
                                    keyCompact = that.buildCompact("<list>", getFromList(desc.getList(keyID)));
                                    break;
                                case DescValueType.OBJECTTYPE:
                                    var objectTypeContext = ["<class>", desc.getObjectType(keyID)];
                                    var objectValue = desc.getObjectValue(keyID);
                                    keyCompact = that.buildCompact("<object>", that.buildCompact(getFromId(objectTypeContext), getFromDescriptor(objectValue, objectTypeContext)));
                                    break;
                                case DescValueType.ALIASTYPE:
                                    try {
                                        var fileRef = desc.getPath(keyID);
                                        keyCompact = that.buildCompact("<path>", fileRef.fsName);
                                    } catch (e) {
                                        keyCompact = that.buildCompact("<path>", incompatiblePlatformPath);
                                    }
                                    break;
                                case DescValueType.REFERENCETYPE:
                                    keyCompact = that.buildCompact("<reference>", getFromReference(desc.getReference(keyID)));
                                    break;
                                case DescValueType.STRINGTYPE:
                                    keyCompact = that.buildCompact("<string>", desc.getString(keyID));
                                    break;
                                case DescValueType.UNITDOUBLE:
                                    var unitTypeContext = ["<unit>", desc.getUnitDoubleType(keyID)];
                                    var doubleValue = desc.getUnitDoubleValue(keyID);
                                    keyCompact = that.buildCompact("<unitDouble>", that.buildCompact(getFromId(unitTypeContext), doubleValue));
                                    break;
                                default:
                                    try {
                                        isRawType = typeID === DescValueType.RAWTYPE;
                                    } catch (e) {

                                    }
                                    try {
                                        isLargeIntegerType = typeID === DescValueType.LARGEINTEGERTYPE;
                                    } catch (e) {

                                    }
                                    if (isRawType) {
                                        keyCompact = that.buildCompact("<data>", desc.getData(keyID));
                                    } else if (isLargeIntegerType) {
                                        keyCompact = that.buildCompact("<largeInteger>", desc.getLargeInteger(keyID));
                                    } else {
                                        throw new Error("[jamEngine getFromDescriptor] Unknown descriptor value type: " + typeID)
                                    }
                                    break;
                            }
                            obj[keyString] = keyCompact;
                        }
                        return obj;
                    } else {
                        return null;
                    }
                }

                function getReferenceClassId(ref) {
                    classId = 0;
                    do {
                        try {
                            var desiredClassId = ref.getDesiredClass();
                        } catch (e) {
                            break;
                        }
                        if (desiredClassId !== propertyClassId) {
                            classId = desiredClassId;
                            break;
                        }
                        ref = ref.getContainer();
                    } while (ref)
                    return classId;
                }

                function simplifyRef(ref) {
                    var simplifiedRef = [];
                    for (var i = 0; i < ref.length; i += 1) {
                        var element = ref[i];
                        var simplifiedElement = {};
                        var desiredClass = element[0];
                        var form = element[1][0];
                        var value = element[1][1];
                        switch (form) {
                            case "<class>":
                            case "<identifier>":
                            case "<index>":
                            case "<name>":
                            case "<offset>":
                            case "<property":
                                simplifiedElement[desiredClass] = value;
                                break;
                            case "<enumerated>":
                                simplifiedElement[desiredClass] = value[1];
                                break;
                            default:
                                throw new Error("[jamEngine simplifyRef] Unexpected element form: " + form)
                                break;
                        }
                        simplifiedRef.push(simplifiedElement);
                    }
                    return simplifiedRef;
                }

                function simplifyItem(item, hook) {
                    var type = item[0];
                    var value = item[1];
                    switch (type) {
                        case "<boolean>":
                        case "<class>":
                        case "<data>":
                        case "<double>":
                        case "<integer>":
                        case "<largeInteger>":
                        case "<path>":
                        case "<string>":
                            simplifiedItem = value;
                            break;
                        case "<list>":
                            simplifiedItem = simplifyList(value, hook);
                            break;
                        case "<enumerated>":
                        case "<unitDouble>":
                            simplifiedItem = value[1];
                            break;
                        case "<object>":
                            simplifiedItem = simplifyDesc(value[1], hook);
                            break;
                        case "<reference>":
                            simplifiedItem = simplifyRef(value);
                            break;
                        default:
                            throw new Error("[jamEngine simplifyItem] Unexpected item type: " + type)
                            break;
                    }
                    return simplifiedItem;
                }

                function simplifyList(list, hook) {
                    var simplifiedList = [];
                    for (var i = 0; i < list.length; i += 1) {
                        simplifiedList.push(simplifyItem(list[i], hook));
                    }
                    return simplifiedList;
                }

                function simplifyDesc(desc, hook) {
                    var getDefaultValue = function(desc, key) {
                        return simplifyItem(desc[key], hook);
                    };
                    var simplifiedDesc = {};
                    for (var key in desc) {
                        if (desc.hasOwnProperty(key)) {
                            var value = undefined;
                            if (typeof hook === "function") {
                                value = hook(desc, key, getDefaultValue);
                            }
                            if (typeof value === "undefined") {
                                value = simplifyItem(desc[key], hook);
                            }
                            simplifiedDesc[key] = value;
                        }
                    }
                    return simplifiedDesc;
                }
                jamEngine.meaningfulIds = false;
                jamEngine.parseFriendly = false;
                jamEngine.displayDialogs = DialogModes.ERROR;
                var conflictingStringIdStrs = {
                    "'Algn'": ["align", "alignment"],
                    "'AntA'": ["antiAlias", "antiAliasedPICTAcquire"],
                    "'BckL'": ["backgroundLayer", "backgroundLevel"],
                    "'BlcG'": ["blackGenerationType", "blackGenerationCurve"],
                    "'BlcL'": ["blackLevel", "blackLimit"],
                    "'Blks'": ["blacks", "blocks"],
                    "'BlrM'": ["blurMethod", "blurMore"],
                    "'BrgC'": ["brightnessEvent", "brightnessContrast"],
                    "'BrsD'": ["brushDetail", "brushesDefine"],
                    "'Brsh'": ["brush", "brushes"],
                    "'Clcl'": ["calculation", "calculations"],
                    "'ClrP'": ["colorPalette", "coloredPencil"],
                    "'Cnst'": ["constant", "constrain"],
                    "'CntC'": ["centerCropMarks", "conteCrayon"],
                    "'Cntr'": ["center", "contrast"],
                    "'CrtD'": ["createDroplet", "createDuplicate"],
                    "'CstP'": ["customPalette", "customPhosphors"],
                    "'Cstm'": ["custom", "customPattern"],
                    "'Drkn'": ["darken", "darkness"],
                    "'Dstr'": ["distort", "distortion", "distribute", "distribution"],
                    "'Dstt'": ["desaturate", "destWhiteMax"],
                    "'FlIn'": ["fileInfo", "fillInverse"],
                    "'Gd  '": ["good", "guide"],
                    "'GnrP'": ["generalPreferences", "generalPrefs", "preferencesClass"],
                    "'GrSt'": ["grainStippled", "graySetup"],
                    "'Grdn'": ["gradientClassEvent", "gridMinor"],
                    "'Grn '": ["grain", "green"],
                    "'Grns'": ["graininess", "greens"],
                    "'HstP'": ["historyPreferences", "historyPrefs"],
                    "'HstS'": ["historyState", "historyStateSourceType"],
                    "'ImgP'": ["imageCachePreferences", "imagePoint"],
                    "'In  '": ["in", "stampIn"],
                    "'IntW'": ["interfaceWhite", "intersectWith"],
                    "'Intr'": ["interfaceIconFrameDimmed", "interlace", "interpolation", "intersect"],
                    "'JPEG'": ["JPEG", "JPEGFormat"],
                    "'LghD'": ["lightDirection", "lightDirectional"],
                    "'LghO'": ["lightOmni", "lightenOnly"],
                    "'LghS'": ["lightSource", "lightSpot"],
                    "'Lns '": ["lens", "lines"],
                    "'Mgnt'": ["magenta", "magentas"],
                    "'MrgL'": ["mergeLayers", "mergedLayers"],
                    "'Mxm '": ["maximum", "maximumQuality"],
                    "'NTSC'": ["NTSC", "NTSCColors"],
                    "'NmbL'": ["numberOfLayers", "numberOfLevels"],
                    "'PlgP'": ["pluginPicker", "pluginPrefs"],
                    "'Pncl'": ["pencilEraser", "pencilWidth"],
                    "'Pnt '": ["paint", "point"],
                    "'Prsp'": ["perspective", "perspectiveIndex"],
                    "'PrvM'": ["previewMacThumbnail", "previewMagenta"],
                    "'Pstr'": ["posterization", "posterize"],
                    "'RGBS'": ["RGBSetup", "RGBSetupSource"],
                    "'Rds '": ["radius", "reds"],
                    "'ScrD'": ["scratchDisks", "screenDot"],
                    "'ShdI'": ["shadingIntensity", "shadowIntensity"],
                    "'ShpC'": ["shapeCurveType", "shapingCurve"],
                    "'ShrE'": ["sharpenEdges", "shearEd"],
                    "'Shrp'": ["sharpen", "sharpness"],
                    "'SplC'": ["splitChannels", "supplementalCategories"],
                    "'Spot'": ["spot", "spotColor"],
                    "'SprS'": ["separationSetup", "sprayedStrokes"],
                    "'StrL'": ["strokeLength", "strokeLocation"],
                    "'Strt'": ["saturation", "start"],
                    "'TEXT'": ["char", "textType"],
                    "'TIFF'": ["TIFF", "TIFFFormat"],
                    "'TglO'": ["toggleOptionsPalette", "toggleOthers"],
                    "'TrnG'": ["transparencyGamutPreferences", "transparencyGrid", "transparencyGridSize"],
                    "'TrnS'": ["transferSpec", "transparencyShape", "transparencyStop"],
                    "'Trns'": ["transparency", "transparent"],
                    "'TxtC'": ["textClickPoint", "textureCoverage"],
                    "'TxtF'": ["textureFile", "textureFill"],
                    "'UsrM'": ["userMaskEnabled", "userMaskOptions"],
                    "'c@#^'": ["inherits", "pInherits"],
                    "'comp'": ["comp", "sInt64"],
                    "'doub'": ["floatType", "IEEE64BitFloatingPoint", "longFloat"],
                    "'long'": ["integer", "longInteger", "sInt32"],
                    "'magn'": ["magnitude", "uInt32"],
                    "'null'": ["null", "target"],
                    "'shor'": ["sInt16", "sMInt", "shortInteger"],
                    "'sing'": ["IEEE32BitFloatingPoint", "sMFloat", "shortFloat"]
                };
                jamEngine.getConflictingStringIdStrs = function(charIdStr) {
                    return conflictingStringIdStrs[charIdStr] || null;
                };
                jamEngine.uniIdStrToId = function(uniIdStr) {
                    var id = 0;
                    if (typeof uniIdStr === "string") {
                        if (uniIdStr.length === 6 && uniIdStr.charAt(0) === "'" && uniIdStr.charAt(5) === "'") {
                            id = app.charIDToTypeID(uniIdStr.substring(1, 5));
                        } else {
                            id = app.stringIDToTypeID(uniIdStr);
                        }
                    }
                    return id;
                };
                var smallestHashValue = app.charIDToTypeID("    ");
                jamEngine.idToUniIdStrs = function(id) {
                    var charIdStr = "";
                    var stringIdStr = app.typeIDToStringID(id);
                    if (id >= smallestHashValue) {
                        charIdStr = "'" + app.typeIDToCharID(id) + "'";
                        if (stringIdStr !== "") {
                            if (charIdStr in conflictingStringIdStrs) {
                                stringIdStr = conflictingStringIdStrs[charIdStr];
                            }
                        }
                    }
                    return [charIdStr, stringIdStr];
                };
                jamEngine.equivalentUniIdStrs = function(uniIdStr1, uniIdStr2) {
                    return this.uniIdStrToId(uniIdStr1) === this.uniIdStrToId(uniIdStr2);
                };
                var contextRules = {
                    "'Algn'": {
                        "<classKey>": {
                            bevelEmboss: "align",
                            frameFX: "align",
                            gradientFill: "align",
                            gradientLayer: "align",
                            patternFill: "align",
                            patternLayer: "align"
                        },
                        "<event>": "align",
                        "<key>": "alignment"
                    },
                    "'AntA'": {
                        "<class>": "antiAliasedPICTAcquire",
                        "<key>": "antiAlias"
                    },
                    "'BckL'": {
                        "<class>": "backgroundLayer",
                        "<key>": "backgroundLevel"
                    },
                    "'BlcG'": {
                        "<enumType>": "blackGenerationType",
                        "<key>": "blackGenerationCurve"
                    },
                    "'BlcL'": {
                        "<classKey>": {
                            "'GEfc'": "blackLevel",
                            CMYKSetup: "blackLimit"
                        },
                        "<eventKey>": {
                            reticulation: "blackLevel"
                        }
                    },
                    "'Blks'": {
                        "<typeValue>": {
                            colors: "blacks",
                            extrudeType: "blocks"
                        }
                    },
                    "'BlrM'": {
                        "<enumType>": "blurMethod",
                        "<event>": "blurMore",
                        "<key>": "blurMethod"
                    },
                    "'BrgC'": {
                        "<class>": "brightnessContrast",
                        "<event>": "brightnessContrast"
                    },
                    "'BrsD'": {
                        "<enumValue>": "brushesDefine",
                        "<key>": "brushDetail"
                    },
                    "'Brsh'": {
                        "<class>": "brush",
                        "<key>": "brushes"
                    },
                    "'Clcl'": {
                        "<class>": "calculation",
                        "<enumValue>": "calculations",
                        "<key>": "calculation"
                    },
                    "'ClrP'": {
                        "<typeValue>": {
                            "'GEft'": "coloredPencil"
                        },
                        "<enumType>": "colorPalette",
                        "<event>": "coloredPencil"
                    },
                    "'Cnst'": {
                        "<classKey>": {
                            channelMatrix: "constant"
                        },
                        "<unknown>": "constrain"
                    },
                    "'CntC'": {
                        "<typeValue>": {
                            "'GEft'": "conteCrayon"
                        },
                        "<event>": "conteCrayon",
                        "<key>": "centerCropMarks"
                    },
                    "'Cntr'": {
                        "<classKey>": {
                            "'GEfc'": "contrast",
                            brightnessContrast: "contrast",
                            document: "center",
                            polygon: "center",
                            quadrilateral: "center"
                        },
                        "<eventKey>": {
                            adaptCorrect: "contrast",
                            brightnessEvent: "contrast",
                            grain: "contrast",
                            halftoneScreen: "contrast",
                            sumie: "contrast",
                            tornEdges: "contrast",
                            waterPaper: "contrast"
                        },
                        "<enumValue>": "center"
                    },
                    "'CrtD'": {
                        "<enumValue>": "createDuplicate",
                        "<event>": "createDroplet"
                    },
                    "'CstP'": {
                        "<class>": "customPhosphors",
                        "<key>": "customPalette"
                    },
                    "'Cstm'": {
                        "<enumValue>": "customPattern",
                        "<event>": "custom",
                        "<key>": "custom"
                    },
                    "'Drkn'": {
                        "<enumValue>": "darken",
                        "<key>": "darkness"
                    },
                    "'Dstr'": {
                        "<classKey>": {
                            "'GEfc'": "distortion"
                        },
                        "<eventKey>": {
                            glass: "distortion",
                            addNoise: "distribution"
                        },
                        "<enumType>": "distribution",
                        "<enumValue>": "distort",
                        "<event>": "distribute"
                    },
                    "'Dstt'": {
                        "<enumValue>": "desaturate",
                        "<event>": "desaturate",
                        "<key>": "destWhiteMax"
                    },
                    "'FlIn'": {
                        "<typeValue>": {
                            fillColor: "fillInverse",
                            menuItemType: "fileInfo"
                        },
                        "<class>": "fileInfo",
                        "<key>": "fileInfo"
                    },
                    "'Gd  '": {
                        "<class>": "guide",
                        "<enumValue>": "good"
                    },
                    "'GnrP'": {
                        "<class>": "preferencesClass",
                        "<enumValue>": "generalPreferences",
                        "<key>": "generalPrefs"
                    },
                    "'GrSt'": {
                        "<class>": "graySetup",
                        "<enumValue>": "grainStippled",
                        "<key>": "graySetup"
                    },
                    "'Grdn'": {
                        "<class>": "gradientClassEvent",
                        "<event>": "gradientClassEvent",
                        "<key>": "gridMinor"
                    },
                    "'Grn '": {
                        "<typeValue>": {
                            "'GEft'": "grain"
                        },
                        "<classKey>": {
                            "'GEfc'": "grain",
                            RGBColor: "green",
                            blackAndWhite: "green",
                            channelMatrix: "green",
                            channelMixer: "green"
                        },
                        "<eventKey>": {
                            blackAndWhite: "green",
                            channelMixer: "green",
                            filmGrain: "grain"
                        },
                        "<enumValue>": "green",
                        "<event>": "grain"
                    },
                    "'Grns'": {
                        "<enumValue>": "greens",
                        "<key>": "graininess"
                    },
                    "'HstP'": {
                        "<enumValue>": "historyPreferences",
                        "<key>": "historyPrefs"
                    },
                    "'HstS'": {
                        "<class>": "historyState",
                        "<enumType>": "historyStateSourceType"
                    },
                    "'ImgP'": {
                        "<class>": "imagePoint",
                        "<enumValue>": "imageCachePreferences"
                    },
                    "'In  '": {
                        "<enumValue>": "stampIn",
                        "<key>": "in"
                    },
                    "'IntW'": {
                        "<event>": "intersectWith",
                        "<key>": "interfaceWhite"
                    },
                    "'Intr'": {
                        "<typeValue>": {
                            shapeOperation: "intersect"
                        },
                        "<classKey>": {
                            GIFFormat: "interlace",
                            SaveForWeb: "interlace",
                            application: "interfaceIconFrameDimmed",
                            computedBrush: "interpolation",
                            dBrush: "interpolation",
                            gradientClassEvent: "interpolation",
                            photoshopEPSFormat: "interpolation",
                            sampledBrush: "interpolation"
                        },
                        "<eventKey>": {
                            convertMode: "interpolation",
                            imageSize: "interpolation",
                            transform: "interpolation"
                        },
                        "<event>": "intersect"
                    },
                    "'JPEG'": {
                        "<class>": "JPEGFormat",
                        "<enumValue>": "JPEG"
                    },
                    "'LghD'": {
                        "<enumType>": "lightDirection",
                        "<enumValue>": "lightDirectional",
                        "<key>": "lightDirection"
                    },
                    "'LghO'": {
                        "<typeValue>": {
                            diffuseMode: "lightenOnly",
                            lightType: "lightOmni"
                        }
                    },
                    "'LghS'": {
                        "<class>": "lightSource",
                        "<enumValue>": "lightSpot",
                        "<key>": "lightSource"
                    },
                    "'Lns '": {
                        "<enumType>": "lens",
                        "<enumValue>": "lines",
                        "<key>": "lens"
                    },
                    "'Mgnt'": {
                        "<typeValue>": {
                            channel: "magenta",
                            colors: "magentas",
                            guideGridColor: "magenta"
                        },
                        "<key>": "magenta"
                    },
                    "'MrgL'": {
                        "<enumValue>": "mergedLayers",
                        "<event>": "mergeLayers"
                    },
                    "'Mxm '": {
                        "<enumValue>": "maximumQuality",
                        "<event>": "maximum",
                        "<key>": "maximum"
                    },
                    "'NTSC'": {
                        "<enumValue>": "NTSC",
                        "<event>": "NTSCColors"
                    },
                    "'NmbL'": {
                        "<classKey>": {
                            "'GEfc'": "numberOfLevels",
                            document: "numberOfLayers"
                        },
                        "<eventKey>": {
                            cutout: "numberOfLevels"
                        }
                    },
                    "'PlgP'": {
                        "<class>": "pluginPrefs",
                        "<enumValue>": "pluginPicker",
                        "<key>": "pluginPrefs"
                    },
                    "'Pncl'": {
                        "<enumValue>": "pencilEraser",
                        "<key>": "pencilWidth"
                    },
                    "'Pnt '": {
                        "<typeValue>": {
                            textType: "point"
                        },
                        "<class>": "point",
                        "<event>": "paint"
                    },
                    "'Prsp'": {
                        "<enumValue>": "perspective",
                        "<key>": "perspectiveIndex"
                    },
                    "'PrvM'": {
                        "<enumValue>": "previewMagenta",
                        "<key>": "previewMacThumbnail"
                    },
                    "'Pstr'": {
                        "<class>": "posterize",
                        "<event>": "posterize",
                        "<key>": "posterization"
                    },
                    "'RGBS'": {
                        "<enumType>": "RGBSetupSource",
                        "<key>": "RGBSetup"
                    },
                    "'Rds '": {
                        "<enumValue>": "reds",
                        "<key>": "radius"
                    },
                    "'ScrD'": {
                        "<enumValue>": "screenDot",
                        "<key>": "scratchDisks"
                    },
                    "'ShdI'": {
                        "<classKey>": {
                            "'GEfc'": "shadowIntensity"
                        },
                        "<eventKey>": {
                            watercolor: "shadowIntensity"
                        },
                        "<unknown>": "shadingIntensity"
                    },
                    "'ShpC'": {
                        "<classKey>": {
                            application: "shapingCurve"
                        },
                        "<class>": "shapingCurve",
                        "<key>": "shapeCurveType"
                    },
                    "'ShrE'": {
                        "<event>": "sharpenEdges",
                        "<key>": "shearEd"
                    },
                    "'Shrp'": {
                        "<event>": "sharpen",
                        "<key>": "sharpness"
                    },
                    "'SplC'": {
                        "<event>": "splitChannels",
                        "<key>": "supplementalCategories"
                    },
                    "'Spot'": {
                        "<enumValue>": "spotColor",
                        "<key>": "spot"
                    },
                    "'SprS'": {
                        "<typeValue>": {
                            "'GEft'": "sprayedStrokes"
                        },
                        "<enumValue>": "separationSetup",
                        "<event>": "sprayedStrokes"
                    },
                    "'StrL'": {
                        "<enumType>": "strokeLocation",
                        "<key>": "strokeLength"
                    },
                    "'Strt'": {
                        "<classKey>": {
                            currentToolOptions: "saturation",
                            fileNamingRules: "start",
                            HSBColorClass: "saturation",
                            hueSatAdjustment: "saturation",
                            hueSatAdjustmentV2: "saturation",
                            lineClass: "start",
                            range: "start",
                            vibrance: "saturation"
                        },
                        "<eventKey>": {
                            replaceColor: "saturation",
                            variations: "saturation",
                            vibrance: "saturation"
                        },
                        "<enumValue>": "saturation"
                    },
                    "'TEXT'": {
                        "<enumType>": "textType",
                        "<key>": "textType"
                    },
                    "'TIFF'": {
                        "<class>": "TIFFFormat",
                        "<enumValue>": "TIFF"
                    },
                    "'TglO'": {
                        "<enumValue>": "toggleOptionsPalette",
                        "<key>": "toggleOthers"
                    },
                    "'TrnG'": {
                        "<classKey>": {
                            application: "transparencyGrid",
                            transparencyPrefs: "transparencyGridSize"
                        },
                        "<enumType>": "transparencyGridSize",
                        "<enumValue>": "transparencyGamutPreferences"
                    },
                    "'TrnS'": {
                        "<classKey>": {
                            bevelEmboss: "transparencyShape",
                            dropShadow: "transparencyShape",
                            innerGlow: "transparencyShape",
                            innerShadow: "transparencyShape",
                            outerGlow: "transparencyShape"
                        },
                        "<class>": "transparencyStop",
                        "<unknown>": "transferSpec"
                    },
                    "'Trns'": {
                        "<enumValue>": "transparent",
                        "<key>": "transparency"
                    },
                    "'TxtC'": {
                        "<classKey>": {
                            "'GEfc'": "textureCoverage",
                            textLayer: "textClickPoint"
                        },
                        "<eventKey>": {
                            underpainting: "textureCoverage"
                        }
                    },
                    "'TxtF'": {
                        "<event>": "textureFill",
                        "<key>": "textureFile"
                    },
                    "'UsrM'": {
                        "<enumType>": "userMaskOptions",
                        "<key>": "userMaskEnabled"
                    },
                    "'null'": {
                        "<class>": "null",
                        "<enumValue>": "null",
                        "<event>": "null",
                        "<key>": "target"
                    }
                };
                var incompatiblePlatformPath = "";
                var getEventId = app.stringIDToTypeID("get");
                var targetKeyId = app.stringIDToTypeID("target");
                var propertyClassId = app.stringIDToTypeID("property");
                jamEngine.jsonToActionDescriptor = function(descriptorObj) {
                    that = this;
                    if (descriptorObj) {
                        actionDescriptor = new ActionDescriptor();
                        putInDescriptor(actionDescriptor, descriptorObj);
                    }
                    return actionDescriptor;
                };
                jamEngine.jsonToActionReference = function(referenceArr) {
                    that = this;
                    if (referenceArr) {
                        actionReference = new ActionReference();
                        putInReference(actionReference, referenceArr);
                    }
                    return actionReference;
                };
                jamEngine.eventIdAndActionDescriptorToJson = function(eventId, actionDescriptor) {
                    that = this;
                    var eventIdContext = ["<event>", eventId];
                    return {
                        "<event>": getFromId(eventIdContext),
                        "<descriptor>": getFromDescriptor(actionDescriptor, eventIdContext)
                    };
                };
                jamEngine.classIdAndActionDescriptorToJson = function(classId, actionDescriptor) {
                    that = this;
                    var classIdContext = ["<class>", classId];
                    return {
                        "<class>": getFromId(classIdContext),
                        "<descriptor>": getFromDescriptor(actionDescriptor, classIdContext)
                    };
                };
                jamEngine.actionReferenceToJson = function(actionReference) {
                    that = this;
                    return getFromReference(actionReference);
                };
                jamEngine.jsonPlay = function(eventUniIdStr, descriptorObj, displayDialogs) {
                    var eventId = this.uniIdStrToId(eventUniIdStr);
                    var desc = this.jsonToActionDescriptor(descriptorObj);
                    if (eventId === getEventId) {
                        var ref = desc.getReference(targetKeyId);
                        parentContext = ["<class>", getReferenceClassId(ref)];
                    } else {
                        parentContext = ["<event>", eventId];
                    }
                    return getFromDescriptor(app.executeAction(eventId, desc, displayDialogs || this.displayDialogs), parentContext);
                };
                jamEngine.jsonGet = function(referenceArr) {
                    var ref = this.jsonToActionReference(referenceArr);
                    return getFromDescriptor(app.executeActionGet(ref), ["<class>", getReferenceClassId(ref)]);
                };
                jamEngine.normalizeJsonItem = function(item, options) {
                    function normalizeItem(item) {
                        var explicit = that.parseCompact(item);
                        var type = explicit[0];
                        var value = explicit[1];
                        switch (type) {
                            case "<boolean>":
                            case "<data>":
                            case "<double>":
                            case "<identifier>":
                            case "<index>":
                            case "<integer>":
                            case "<largeInteger>":
                            case "<name>":
                            case "<offset>":
                            case "<path>":
                            case "<string>":
                                normalizedValue = value;
                                break;
                            case "<class>":
                                normalizedValue = value && getFromId(["<class>", that.uniIdStrToId(value)]);
                                break;
                            case "<enumerated>":
                                var enumerated = that.parseCompact(value);
                                var enumTypeContext = ["<enumType>", that.uniIdStrToId(enumerated[0])];
                                var enumValueContext = ["<enumValue>", that.uniIdStrToId(enumerated[1])];
                                normalizedValue = that.buildCompact(getFromId(enumTypeContext), getFromId(enumValueContext, enumTypeContext));
                                break;
                            case "<list>":
                                normalizedValue = [];
                                for (var i = 0; i < value.length; i += 1) {
                                    normalizedValue.push(normalizeItem(value[i]));
                                }
                                break;
                            case "<object>":
                                var object = that.parseCompact(value);
                                var objectClassContext = ["<class>", that.uniIdStrToId(object[0])];
                                var objectDescriptor = object[1];
                                if (objectDescriptor === null) {
                                    normalizedDescriptor = null;
                                } else {
                                    normalizedDescriptor = {};
                                    for (var key in objectDescriptor) {
                                        if (objectDescriptor.hasOwnProperty(key)) {
                                            var objectKeyContext = ["<key>", that.uniIdStrToId(key)];
                                            normalizedDescriptor[getFromId(objectKeyContext, objectClassContext)] = normalizeItem(objectDescriptor[key]);
                                        }
                                    }
                                }
                                normalizedValue = that.buildCompact(getFromId(objectClassContext), normalizedDescriptor);
                                break;
                            case "<property>":
                                normalizedValue = getFromId(["<key>", that.uniIdStrToId(value)]);
                                break;
                            case "<reference>":
                                normalizedValue = [];
                                for (var i = 0; i < value.length; i += 1) {
                                    var container = that.parseCompact(value[i]);
                                    normalizedValue.push(that.buildCompact(getFromId(["<class>", that.uniIdStrToId(container[0])]), normalizeItem(container[1])));
                                }
                                break;
                            case "<unitDouble>":
                                var unitDouble = that.parseCompact(value);
                                var unitTypeContext = ["<unit>", that.uniIdStrToId(unitDouble[0])];
                                normalizedValue = that.buildCompact(getFromId(unitTypeContext), unitDouble[1]);
                                break;
                            default:
                                throw new Error("[jamEngine.normalizeJsonItem] Unknown item type: " + type)
                                break;
                        }
                        return that.buildCompact(type, normalizedValue);
                    }
                    that = this;
                    var saveMeaningfulIds = this.meaningfulIds;
                    var saveParseFriendly = this.parseFriendly;
                    if (options && options.constructor === Object) {
                        if (typeof options.meaningfulIds !== "undefined") {
                            this.meaningfulIds = options.meaningfulIds;
                        }
                        if (typeof options.parseFriendly !== "undefined") {
                            this.parseFriendly = options.parseFriendly;
                        }
                    }
                    var normalizedItem = normalizeItem(item);
                    this.meaningfulIds = saveMeaningfulIds;
                    this.parseFriendly = saveParseFriendly;
                    return normalizedItem;
                };
                jamEngine.simplifyObject = function(object, hookFunction) {
                    return simplifyDesc(this.normalizeJsonItem(object, {
                        meaningfulIds: true,
                        parseFriendly: true
                    })[1][1], hookFunction);
                };
                jamEngine.simplifyList = function(list, hookFunction) {
                    return simplifyList(this.normalizeJsonItem(list, {
                        meaningfulIds: true,
                        parseFriendly: true
                    })[1], hookFunction);
                };
                jamEngine.parseCompact = function(compact) {
                    var result = [];
                    if (compact.constructor === Object) {
                        var keys = [];
                        for (var k in compact) {
                            if (compact.hasOwnProperty(k)) {
                                keys.push(k);
                            }
                        }
                        if (keys.length === 1) {
                            result[0] = keys[0];
                            result[1] = compact[keys[0]];
                        } else {
                            throw new Error("[jamEngine.parseCompact] Syntax error: " + compact.toSource())
                        }
                    } else if (compact.constructor === Array) {
                        if (compact.length === 2) {
                            result[0] = compact[0];
                            result[1] = compact[1];
                        } else {
                            throw new Error("[jamEngine.parseCompact] Syntax error: " + compact.toSource())
                        }
                    } else {
                        throw new Error("[jamEngine.parseCompact] JavaScript object or array expected")
                    }
                    return result;
                };
                jamEngine.compactToExplicit = function(compact, typeKey, valueKey) {
                    var explicit = {};
                    var typeValue = this.parseCompact(compact);
                    explicit[typeKey || "<type>"] = typeValue[0];
                    explicit[valueKey || "<value>"] = typeValue[1];
                    return explicit;
                };
                jamEngine.buildCompact = function(type, value) {
                    if (typeof type === "string") {
                        if (this.parseFriendly) {
                            compact = [type, value];
                        } else {
                            compact = {};
                            compact[type] = value;
                        }
                    } else {
                        throw new Error("[jamEngine.buildCompact] String expected")
                    }
                    return compact;
                };
                jamEngine.explicitToCompact = function(explicit, typeKey, valueKey) {
                    if (explicit.constructor === Object) {
                        compact = this.buildCompact(explicit[typeKey || "<type>"], explicit[valueKey || "<value>"]);
                    } else {
                        throw new Error("[jamEngine.explicitToCompact] JavaScript object expected")
                    }
                    return compact;
                };
                for (var charIdStr in conflictingStringIdStrs) {
                    if (conflictingStringIdStrs.hasOwnProperty(charIdStr)) {
                        var stringIdStrs = conflictingStringIdStrs[charIdStr];
                        for (var index = stringIdStrs.length - 1; index >= 0; index--) {
                            var stringIdStr = stringIdStrs[index];
                            if (!(app.charIDToTypeID(charIdStr.substring(1, 5)) === app.stringIDToTypeID(stringIdStr))) {
                                stringIdStrs.splice(index, 1);
                            }
                        }
                        if (stringIdStrs.length < 2) {
                            delete conflictingStringIdStrs[charIdStr];
                        }
                    }
                }
                for (var charIdStr in contextRules) {
                    if (contextRules.hasOwnProperty(charIdStr)) {
                        if (charIdStr in conflictingStringIdStrs) {
                            var rule = contextRules[charIdStr];
                            for (var kind in rule) {
                                if (rule.hasOwnProperty(kind)) {
                                    switch (kind) {
                                        case "<class>":
                                        case "<event>":
                                        case "<enumType>":
                                        case "<enumValue>":
                                        case "<key>":
                                        case "<unknown>":
                                            if (app.charIDToTypeID(charIdStr.substring(1, 5)) != app.stringIDToTypeID(rule[kind])) {
                                                throw new Error("[jamEngine] \"" + charIdStr + "\" and \"" + rule[kind] + "\" are not equivalent ID strings")
                                            }
                                            break;
                                        case "<classKey>":
                                        case "<eventKey>":
                                        case "<typeValue>":
                                            for (var parent in rule[kind]) {
                                                if (rule[kind].hasOwnProperty(parent)) {
                                                    if (app.charIDToTypeID(charIdStr.substring(1, 5)) != app.stringIDToTypeID(rule[kind][parent])) {
                                                        throw new Error("[jamEngine] \"" + charIdStr + "\" and \"" + rule[kind][parent] + "\" are not equivalent ID strings")
                                                    }
                                                }
                                            }
                                            break;
                                    }
                                }
                            }
                        } else {
                            delete contextRules[charIdStr];
                        }
                    }
                }
            }
        }
        jamEngine.meaningfulIds = false;
        jamEngine.parseFriendly = false;
        try {
            jamEngine.jsonPlay("'Mk  '", {
                "'null'": {
                    "<reference>": [{
                        "'Lyr '": {
                            "<class>": null
                        }
                    }]
                },
                "'LyrI'": {
                    "<integer>": 77
                }
            }, DialogModes.NO);
            jamEngine.jsonPlay("'MrgV'", {
                "'Dplc'": {
                    "<boolean>": true
                }
            }, DialogModes.NO);
            jamEngine.jsonPlay("'setd'", {
                "'null'": {
                    "<reference>": [{
                        "'Lyr '": {
                            "<enumerated>": {
                                "'Ordn'": "'Trgt'"
                            }
                        }
                    }]
                },
                "'T   '": {
                    "<object>": {
                        "'Lyr '": {
                            "'Nm  '": {
                                "<string>": "CRW Method"
                            }
                        }
                    }
                }
            }, DialogModes.NO);
            jamEngine.jsonPlay("'setd'", {
                "'null'": {
                    "<reference>": [{
                        "'Lyr '": {
                            "<enumerated>": {
                                "'Ordn'": "'Trgt'"
                            }
                        }
                    }]
                },
                "'T   '": {
                    "<object>": {
                        "'Lyr '": {
                            "'Clr '": {
                                "<enumerated>": {
                                    "'Clr '": "'Bl  '"
                                }
                            }
                        }
                    }
                }
            }, DialogModes.NO);
            jamEngine.jsonPlay("Adobe Camera Raw Filter", {
                "'CMod'": {
                    "<string>": "Filter"
                },
                "'Sett'": {
                    "<enumerated>": {
                        "'Sett'": "'Cst '"
                    }
                },
                "'WBal'": {
                    "<enumerated>": {
                        "'WBal'": "'AsSh'"
                    }
                },
                "'Temp'": {
                    "<integer>": 0
                },
                "'Tint'": {
                    "<integer>": 0
                },
                "'CtoG'": {
                    "<boolean>": false
                },
                "'Strt'": {
                    "<integer>": 0
                },
                "'Shrp'": {
                    "<integer>": 0
                },
                "'LNR '": {
                    "<integer>": 0
                },
                "'CNR '": {
                    "<integer>": 0
                },
                "'VigA'": {
                    "<integer>": 0
                },
                "'BlkB'": {
                    "<integer>": 0
                },
                "'RHue'": {
                    "<integer>": 0
                },
                "'RSat'": {
                    "<integer>": 0
                },
                "'GHue'": {
                    "<integer>": 0
                },
                "'GSat'": {
                    "<integer>": 0
                },
                "'BHue'": {
                    "<integer>": 0
                },
                "'BSat'": {
                    "<integer>": 0
                },
                "'Vibr'": {
                    "<integer>": 0
                },
                "'HA_R'": {
                    "<integer>": 0
                },
                "'HA_O'": {
                    "<integer>": 0
                },
                "'HA_Y'": {
                    "<integer>": 0
                },
                "'HA_G'": {
                    "<integer>": 0
                },
                "'HA_A'": {
                    "<integer>": 0
                },
                "'HA_B'": {
                    "<integer>": 0
                },
                "'HA_P'": {
                    "<integer>": 0
                },
                "'HA_M'": {
                    "<integer>": 0
                },
                "'SA_R'": {
                    "<integer>": 0
                },
                "'SA_O'": {
                    "<integer>": 0
                },
                "'SA_Y'": {
                    "<integer>": 0
                },
                "'SA_G'": {
                    "<integer>": 0
                },
                "'SA_A'": {
                    "<integer>": 0
                },
                "'SA_B'": {
                    "<integer>": 0
                },
                "'SA_P'": {
                    "<integer>": 0
                },
                "'SA_M'": {
                    "<integer>": 0
                },
                "'LA_R'": {
                    "<integer>": 0
                },
                "'LA_O'": {
                    "<integer>": 0
                },
                "'LA_Y'": {
                    "<integer>": 0
                },
                "'LA_G'": {
                    "<integer>": 0
                },
                "'LA_A'": {
                    "<integer>": 0
                },
                "'LA_B'": {
                    "<integer>": 0
                },
                "'LA_P'": {
                    "<integer>": 0
                },
                "'LA_M'": {
                    "<integer>": 0
                },
                "'STSH'": {
                    "<integer>": 0
                },
                "'STSS'": {
                    "<integer>": 0
                },
                "'STHH'": {
                    "<integer>": 0
                },
                "'STHS'": {
                    "<integer>": 0
                },
                "'STB '": {
                    "<integer>": 0
                },
                "'PC_S'": {
                    "<integer>": 0
                },
                "'PC_D'": {
                    "<integer>": 0
                },
                "'PC_L'": {
                    "<integer>": 0
                },
                "'PC_H'": {
                    "<integer>": 0
                },
                "'PC_1'": {
                    "<integer>": 25
                },
                "'PC_2'": {
                    "<integer>": 50
                },
                "'PC_3'": {
                    "<integer>": 75
                },
                "'ShpR'": {
                    "<double>": 1
                },
                "'ShpD'": {
                    "<integer>": 25
                },
                "'ShpM'": {
                    "<integer>": 0
                },
                "'PCVA'": {
                    "<integer>": 0
                },
                "'GRNA'": {
                    "<integer>": 0
                },
                "'LPEn'": {
                    "<integer>": 0
                },
                "'MDis'": {
                    "<integer>": 0
                },
                "'PerV'": {
                    "<integer>": 0
                },
                "'PerH'": {
                    "<integer>": 0
                },
                "'PerR'": {
                    "<double>": 0
                },
                "'PerS'": {
                    "<integer>": 100
                },
                "'PerA'": {
                    "<integer>": 0
                },
                "'PerU'": {
                    "<integer>": 0
                },
                "'PerX'": {
                    "<double>": 0
                },
                "'PerY'": {
                    "<double>": 0
                },
                "'AuCA'": {
                    "<integer>": 0
                },
                "'Ex12'": {
                    "<double>": 0
                },
                "'Cr12'": {
                    "<integer>": 0
                },
                "'Hi12'": {
                    "<integer>": -50
                },
                "'Sh12'": {
                    "<integer>": 0
                },
                "'Wh12'": {
                    "<integer>": 0
                },
                "'Bk12'": {
                    "<integer>": 0
                },
                "'Cl12'": {
                    "<integer>": 0
                },
                "'DfPA'": {
                    "<integer>": 0
                },
                "'DPHL'": {
                    "<integer>": 30
                },
                "'DPHH'": {
                    "<integer>": 70
                },
                "'DfGA'": {
                    "<integer>": 0
                },
                "'DPGL'": {
                    "<integer>": 40
                },
                "'DPGH'": {
                    "<integer>": 60
                },
                "'Dhze'": {
                    "<integer>": 0
                },
                "'TMMs'": {
                    "<integer>": 0
                },
                "'Crv '": {
                    "<list>": [{
                        "<integer>": 0
                    }, {
                        "<integer>": 0
                    }, {
                        "<integer>": 255
                    }, {
                        "<integer>": 255
                    }]
                },
                "'CrvR'": {
                    "<list>": [{
                        "<integer>": 0
                    }, {
                        "<integer>": 0
                    }, {
                        "<integer>": 255
                    }, {
                        "<integer>": 255
                    }]
                },
                "'CrvG'": {
                    "<list>": [{
                        "<integer>": 0
                    }, {
                        "<integer>": 0
                    }, {
                        "<integer>": 255
                    }, {
                        "<integer>": 255
                    }]
                },
                "'CrvB'": {
                    "<list>": [{
                        "<integer>": 0
                    }, {
                        "<integer>": 0
                    }, {
                        "<integer>": 255
                    }, {
                        "<integer>": 255
                    }]
                },
                "'CamP'": {
                    "<string>": "Embedded"
                },
                "'CP_D'": {
                    "<string>": "54650A341B5B5CCAE8442D0B43A92BCE"
                },
                "'PrVe'": {
                    "<integer>": 167772160
                },
                "'Rtch'": {
                    "<string>": ""
                },
                "'REye'": {
                    "<string>": ""
                },
                "'LCs '": {
                    "<string>": ""
                },
                "'Upri'": {
                    "<string>": "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"Adobe XMP Core 5.6-c140 79.160451, 2017/05/06-01:08:21        \">\n <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n  <rdf:Description rdf:about=\"\"\n    xmlns:crs=\"http://ns.adobe.com/camera-raw-settings/1.0/\"\n   crs:UprightVersion=\"151388160\"\n   crs:UprightCenterMode=\"0\"\n   crs:UprightCenterNormX=\"0.5\"\n   crs:UprightCenterNormY=\"0.5\"\n   crs:UprightFocalMode=\"0\"\n   crs:UprightFocalLength35mm=\"35\"\n   crs:UprightPreview=\"False\"\n   crs:UprightTransformCount=\"6\"/>\n </rdf:RDF>\n</x:xmpmeta>\n"
                },
                "'GuUr'": {
                    "<string>": "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"Adobe XMP Core 5.6-c140 79.160451, 2017/05/06-01:08:21        \">\n <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n  <rdf:Description rdf:about=\"\"\n    xmlns:crs=\"http://ns.adobe.com/camera-raw-settings/1.0/\"\n   crs:UprightFourSegmentsCount=\"0\"/>\n </rdf:RDF>\n</x:xmpmeta>\n"
                },
                "'Look'": {
                    "<string>": ""
                },
                "'Pset'": {
                    "<string>": ""
                }
            }, DialogModes.NO);
            jamEngine.jsonPlay("'Mk  '", {
                "'Nw  '": {
                    "<class>": "'Chnl'"
                },
                "'At  '": {
                    "<reference>": [{
                        "'Chnl'": {
                            "<enumerated>": {
                                "'Chnl'": "'Msk '"
                            }
                        }
                    }]
                },
                "'Usng'": {
                    "<enumerated>": {
                        "'UsrM'": "'HdAl'"
                    }
                }
            }, DialogModes.NO);
            jamEngine.jsonPlay("'slct'", {
                "'null'": {
                    "<reference>": [{
                        "'PbTl'": {
                            "<class>": null
                        }
                    }]
                }
            }, DialogModes.NO);
            jamEngine.jsonPlay("'setd'", {
                "'null'": {
                    "<reference>": [{
                        "'Clr '": {
                            "<property>": "'FrgC'"
                        }
                    }]
                },
                "'T   '": {
                    "<object>": {
                        "'HSBC'": {
                            "'H   '": {
                                "<unitDouble>": {
                                    "'#Ang'": 0
                                }
                            },
                            "'Strt'": {
                                "<double>": 0
                            },
                            "'Brgh'": {
                                "<double>": 100
                            }
                        }
                    }
                },
                "'Srce'": {
                    "<string>": "photoshopPicker"
                }
            }, DialogModes.NO);
            jamEngine.jsonPlay("'setd'", {
                "'null'": {
                    "<reference>": [{
                        "'Clr '": {
                            "<property>": "'BckC'"
                        }
                    }]
                },
                "'T   '": {
                    "<object>": {
                        "'HSBC'": {
                            "'H   '": {
                                "<unitDouble>": {
                                    "'#Ang'": 0
                                }
                            },
                            "'Strt'": {
                                "<double>": 0
                            },
                            "'Brgh'": {
                                "<double>": 0
                            }
                        }
                    }
                },
                "'Srce'": {
                    "<string>": "photoshopPicker"
                }
            }, DialogModes.NO);
        } catch (e) {
            if (e.number !== 8007) {
                try {
                    jamEngine.jsonPlay("'Stop'", {
                        "'Msge'": {
                            "<string>": e.message.replace(/^.*\n- /, "")
                        }
                    }, DialogModes.ALL);
                } catch (e) {

                }
            }
        }
        close = true;
        win.close();
    }
};
win.onClose = function() {
    close = true;
};
win.show();
while (close === false) {
    app.refresh();
}