mirror of
https://github.com/OMGeeky/andors-trail.git
synced 2026-02-23 15:38:29 +01:00
Merge branch 'revamped_editor'
This commit is contained in:
@@ -1,340 +0,0 @@
|
||||
function IncludeJavascript(jsFile) {
|
||||
document.write('<script type="text/javascript" src="' + jsFile + '"></scr' + 'ipt>');
|
||||
}
|
||||
|
||||
IncludeJavascript("FieldList.js");
|
||||
IncludeJavascript("DataStore.js");
|
||||
IncludeJavascript("ImageSelector.js");
|
||||
IncludeJavascript("EditorTabs.js");
|
||||
IncludeJavascript("EditorFunctions.js");
|
||||
IncludeJavascript("ImportExport.js");
|
||||
|
||||
IncludeJavascript("Editor_ActorCondition.js");
|
||||
IncludeJavascript("Editor_Quest.js");
|
||||
IncludeJavascript("Editor_Item.js");
|
||||
IncludeJavascript("Editor_Droplist.js");
|
||||
IncludeJavascript("Editor_Conversation.js");
|
||||
IncludeJavascript("Editor_Monster.js");
|
||||
|
||||
IncludeJavascript("inc/jquery.dynatree.min.js");
|
||||
IncludeJavascript("inc/mustache.js");
|
||||
|
||||
|
||||
var model;
|
||||
var imageSelector;
|
||||
var tabs;
|
||||
var questlogDialog;
|
||||
var onHitConditionsDialog;
|
||||
var equipConditionsDialog;
|
||||
var droplistItemDialog;
|
||||
var phraseRewardDialog;
|
||||
|
||||
function loadResourceFile(filename, onSuccess) {
|
||||
var url = document.location.href;
|
||||
url = url.substring(0, url.lastIndexOf('/'));
|
||||
url = url.substring(0, url.lastIndexOf('/'));
|
||||
url += "/AndorsTrail/res/" + filename;
|
||||
//var url = "http://andors-trail.googlecode.com/git/AndorsTrail/res/" + filename;
|
||||
$.get(url, function(data) {
|
||||
onSuccess(data);
|
||||
}, 'text')
|
||||
.error(function() { alert("Error loading " + url); });
|
||||
}
|
||||
|
||||
function openTabForObject(obj, dataStore) {
|
||||
tabs.openTabForObject(obj, dataStore.objectTypename, obj[dataStore.nameField]);
|
||||
}
|
||||
|
||||
function bindObjectsToItemList(itemListDiv, dataStore) {
|
||||
itemListDiv.children().remove();
|
||||
var createListItem = function(obj) {
|
||||
var item = $( Mustache.to_html( $('#listitem').html(), { name: obj[dataStore.nameField] } ) );
|
||||
if (dataStore.iconField) {
|
||||
var elem = $( 'img', item );
|
||||
imageSelector.setImage( elem , obj[dataStore.iconField] , 0.7);
|
||||
}
|
||||
return item;
|
||||
};
|
||||
var addToList = function(obj) {
|
||||
var item = createListItem(obj);
|
||||
item.click(function() { openTabForObject(obj, dataStore); });
|
||||
itemListDiv.append(item);
|
||||
item.hide().fadeIn('slow');
|
||||
};
|
||||
dataStore.items.forEach(addToList);
|
||||
dataStore.onAdded = addToList;
|
||||
dataStore.onDeserialized = function() {
|
||||
bindObjectsToItemList(itemListDiv, dataStore);
|
||||
// TODO: Should also close all tabs.
|
||||
};
|
||||
dataStore.onPropertyChanged = function(obj, propertyName, value) {
|
||||
var listItem = $("li:eq(" + dataStore.items.indexOf(obj) + ")", itemListDiv);
|
||||
listItem.html( createListItem(obj).html() );
|
||||
if (propertyName == dataStore.nameField) {
|
||||
//TODO: Should this really be in the same function?
|
||||
// (splitting the left part from the tab controls would reduce coupling, which would be a good thing.)
|
||||
tabs.renameTabForObject(obj, value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function bindEditorType(dataStore, div, createObjectEditor, newObjectCreator) {
|
||||
tabs.registerEditorType(dataStore.objectTypename, createObjectEditor);
|
||||
|
||||
bindObjectsToItemList( $( "ul", div ), dataStore );
|
||||
|
||||
$( "#add", div )
|
||||
.button()
|
||||
.click(function() {
|
||||
var obj = newObjectCreator();
|
||||
dataStore.add(obj);
|
||||
openTabForObject( obj, dataStore );
|
||||
});
|
||||
|
||||
$( "#clear", div )
|
||||
.button()
|
||||
.click(function() {
|
||||
if (confirm("Are you sure?")) {
|
||||
dataStore.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addExampleModelItems(model) {
|
||||
model.actorConditions.add({id: "bless", name: "Bless", isPositive: true, iconID: "actorconditions_1:38", category: 0, hasAbilityEffect: 1, attackChance: 15, blockChance: 5});
|
||||
model.actorConditions.add({id: "poison_weak", name: "Weak Poison", iconID: "actorconditions_1:60", category: 3, hasRoundEffect: 1, round_visualEffectID: 2, round_boostHP_Min: -1, round_boostHP_Max: -1});
|
||||
|
||||
model.quests.add({id: "testQuest", name: "Test quest", stages: [ { progress: 10, logText: "Stage 10"} , { progress: 20, logText: "Stage 20", finishesQuest: 1 } ] });
|
||||
|
||||
model.items.add({id: "item0", iconID: "items_weapons:0", name: "Longsword", category: 'lsword', baseMarketCost: 51, hasEquipEffect: 1, equip_attackChance: 10, equip_attackDamage_Min: 2, equip_attackDamage_Max: 4, equip_attackCost: 4});
|
||||
model.items.add({id: "dmg_ring1", iconID: "items_jewelry:0", name: "Ring of damage +1", category: 'ring', baseMarketCost: 62, hasEquipEffect: 1, equip_attackDamage_Min: 1, equip_attackDamage_Max: 1});
|
||||
|
||||
model.droplists.add({id: "merchant1", items: [ { itemID: 'dmg_ring1', quantity_Min: 4, quantity_Max: 5, chance: 100 } , { itemID: 'item0', quantity_Min: 1, quantity_Max: 1, chance: 100 } ] } );
|
||||
|
||||
model.dialogue.add({id: "mikhail_default", message: 'Anything else I can help you with?', replies: [ { text: 'Do you have any tasks for me?', nextPhraseID: 'mikhail_tasks' }, { text: 'Is there anything else you can tell me about Andor?', nextPhraseID: 'mikhail_andor1' } ]});
|
||||
model.dialogue.add({id: 'mikhail_andor1', message: 'As I said, Andor went out yesterday and hasn\'t been back since. I\'m starting to worry about him. Please go look for your brother, he said he would only be out a short while.'});
|
||||
model.dialogue.add({id: 'mikhail_tasks', message: 'Oh yes, there were some things I need help with, bread and rats. Which one would you like to talk about?'});
|
||||
|
||||
model.monsters.add({id: "small_ant", name: "Small ant", iconID: "monsters_insects:2", maxHP: 30, size: '1x1'});
|
||||
model.monsters.add({id: "red_ant", name: "Red ant", iconID: "monsters_insects:3", maxHP: 20, size: '1x1'});
|
||||
model.monsters.add({id: "wasp", name: "Wasp", iconID: "monsters_insects:1", maxHP: 10, size: '1x1'});
|
||||
}
|
||||
|
||||
function startEditor() {
|
||||
|
||||
model = {
|
||||
actorConditions: new DataStore({
|
||||
objectTypename: 'actorcondition'
|
||||
,fieldList: new FieldList("[id|name|iconID|category|isStacking|isPositive|"
|
||||
+ "hasRoundEffect|round_visualEffectID|round_boostHP_Min|round_boostHP_Max|round_boostAP_Min|round_boostAP_Max|"
|
||||
+ "hasFullRoundEffect|fullround_visualEffectID|fullround_boostHP_Min|fullround_boostHP_Max|fullround_boostAP_Min|fullround_boostAP_Max|"
|
||||
+ "hasAbilityEffect|boostMaxHP|boostMaxAP|moveCostPenalty|attackCost|attackChance|criticalChance|criticalMultiplier|attackDamage_Min|attackDamage_Max|blockChance|damageResistance|"
|
||||
+ "];"
|
||||
)
|
||||
,idField: 'id'
|
||||
,nameField: 'name'
|
||||
,iconField: 'iconID'
|
||||
})
|
||||
,quests: new DataStore({
|
||||
objectTypename: 'quest'
|
||||
,fieldList: new FieldList("[id|name|showInLog|stages[progress|logText|rewardExperience|finishesQuest|]|];")
|
||||
,idField: 'id'
|
||||
,nameField: 'name'
|
||||
})
|
||||
,items: new DataStore({
|
||||
objectTypename: 'item'
|
||||
,fieldList: new FieldList("[id|iconID|name|category|displaytype|hasManualPrice|baseMarketCost|"
|
||||
+ "hasEquipEffect|equip_boostMaxHP|equip_boostMaxAP|equip_moveCostPenalty|equip_attackCost|equip_attackChance|equip_criticalChance|equip_criticalMultiplier|equip_attackDamage_Min|equip_attackDamage_Max|equip_blockChance|equip_damageResistance|equip_conditions[condition|magnitude|]|"
|
||||
+ "hasUseEffect|use_boostHP_Min|use_boostHP_Max|use_boostAP_Min|use_boostAP_Max|use_conditionsSource[condition|magnitude|duration|chance|]|"
|
||||
+ "hasHitEffect|hit_boostHP_Min|hit_boostHP_Max|hit_boostAP_Min|hit_boostAP_Max|hit_conditionsSource[condition|magnitude|duration|chance|]|hit_conditionsTarget[condition|magnitude|duration|chance|]|"
|
||||
+ "hasKillEffect|kill_boostHP_Min|kill_boostHP_Max|kill_boostAP_Min|kill_boostAP_Max|kill_conditionsSource[condition|magnitude|duration|chance|]|"
|
||||
+ "];"
|
||||
)
|
||||
,idField: 'id'
|
||||
,nameField: 'name'
|
||||
,iconField: 'iconID'
|
||||
})
|
||||
,droplists: new DataStore({
|
||||
objectTypename: 'droplist'
|
||||
,fieldList: new FieldList("[id|items[itemID|quantity_Min|quantity_Max|chance|]|];")
|
||||
,idField: 'id'
|
||||
,nameField: 'id'
|
||||
})
|
||||
,dialogue: new DataStore({
|
||||
objectTypename: 'dialogue'
|
||||
,fieldList: new FieldList("[id|message|rewards[rewardType|rewardID|value|]|replies[text|nextPhraseID|requires_Progress|requires_itemID|requires_Quantity|requires_Type|]|];")
|
||||
,idField: 'id'
|
||||
,nameField: 'id'
|
||||
})
|
||||
,monsters: new DataStore({
|
||||
objectTypename: 'monster'
|
||||
,fieldList: new FieldList("[id|iconID|name|tags|size|monsterClass|unique|faction|maxHP|maxAP|moveCost|attackCost|attackChance|criticalChance|criticalMultiplier|attackDamage_Min|attackDamage_Max|blockChance|damageResistance|droplistID|phraseID|"
|
||||
+ "hasHitEffect|onHit_boostHP_Min|onHit_boostHP_Max|onHit_boostAP_Min|onHit_boostAP_Max|onHit_conditionsSource[condition|magnitude|duration|chance|]|onHit_conditionsTarget[condition|magnitude|duration|chance|]|"
|
||||
+ "];"
|
||||
)
|
||||
,idField: 'id'
|
||||
,nameField: 'name'
|
||||
,iconField: 'iconID'
|
||||
})
|
||||
,itemCategories: new DataStore({
|
||||
objectTypename: 'itemcategory'
|
||||
,fieldList: new FieldList("[id|name|actionType|inventorySlot|size|];")
|
||||
,idField: 'id'
|
||||
,nameField: 'name'
|
||||
})
|
||||
};
|
||||
|
||||
addExampleModelItems(model);
|
||||
|
||||
|
||||
|
||||
|
||||
imageSelector = new ImageSelector("../AndorsTrail/res/drawable/", $( "#dialog-images" ) );
|
||||
imageSelector.add(new TilesetImage("actorconditions_1", {x:14, y:8}, undefined, [ 'conditions' ] ));
|
||||
imageSelector.add(new TilesetImage("actorconditions_2", {x:3, y:1}, undefined, [ 'conditions' ] ));
|
||||
imageSelector.add(new TilesetImage("items_armours", {x:14, y:3}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_armours_3", {x:10, y:4}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_armours_2", {x:7, y:1}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_weapons", {x:14, y:6}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_weapons_3", {x:13, y:5}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_weapons_2", {x:7, y:1}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_jewelry", {x:14, y:1}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_rings_1", {x:10, y:3}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_necklaces_1", {x:10, y:3}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_consumables", {x:14, y:5}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_books", {x:11, y:1}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_misc", {x:14, y:4}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_misc_2", {x:20, y:12}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_misc_3", {x:20, y:12}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("items_misc_4", {x:20, y:4}, undefined, [ 'items' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_armor1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_demon1", {x: 1, y:1}, {x:64, y:64}, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_dogs", {x: 7, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_eye1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_eye2", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_eye3", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_eye4", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_ghost1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_hydra1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_insects", {x: 6, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_liches", {x: 4, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_mage", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_mage2", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_man1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_men", {x: 9, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_men2", {x: 10, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_misc", {x: 12, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_rats", {x: 5, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_rogue1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_skeleton1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_skeleton2", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_snakes", {x: 6, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_cyclops", {x: 1, y:1}, {x:64, y:96}, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_warrior1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_wraiths", {x: 3, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_zombie1", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_zombie2", {x: 1, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_karvis1", {x: 2, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_karvis2", {x: 9, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_rltiles1", {x:20, y:8}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_rltiles2", {x:20, y:9}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_rltiles3", {x:10, y:3}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_redshrike1", {x:6, y:1}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_ld1", {x:20, y:12}, undefined, [ 'monsters' ] ));
|
||||
imageSelector.add(new TilesetImage("monsters_ld2", {x:20, y:12}, undefined, [ 'monsters' ] ));
|
||||
|
||||
|
||||
|
||||
$( "#left #tools" ).accordion({ fillSpace: true });
|
||||
|
||||
tabs = new EditorTabs( $( "#center #tabs" ) );
|
||||
|
||||
|
||||
bindEditorType(model.actorConditions, $( "#tools #actorconditionlist" ), createActorConditionEditor, function() {
|
||||
return {name: "New Condition", id: 'new_condition' };
|
||||
});
|
||||
bindEditorType(model.quests, $( "#tools #questlist" ), createQuestEditor, function() {
|
||||
return {name: "New Quest", id: 'new_quest' };
|
||||
});
|
||||
bindEditorType(model.items, $( "#tools #itemlist" ), createItemEditor, function() {
|
||||
return {name: "New Item", id: "new_item", category: 'other' };
|
||||
});
|
||||
bindEditorType(model.droplists, $( "#tools #droplist" ), createDroplistEditor, function() {
|
||||
return {id: "new_droplist" };
|
||||
});
|
||||
bindEditorType(model.dialogue, $( "#tools #conversationlist" ), createConversationEditor, function() {
|
||||
return {id: "new_conversation" };
|
||||
});
|
||||
bindEditorType(model.monsters, $( "#tools #monsterlist" ), createMonsterEditor, function() {
|
||||
return {id: "new_monster", name: "New Monster", maxAP: 10, attackCost: 5, moveCost: 5 };
|
||||
});
|
||||
|
||||
|
||||
|
||||
$( "#buttons #import" ).button().click( showImportDialog );
|
||||
$( "#buttons #export" ).button().click( showExportDialog );
|
||||
|
||||
|
||||
var defaultButtons = {
|
||||
Close: function() { $( this ).dialog( "close" ); }
|
||||
};
|
||||
|
||||
prepareImportExportDialogs(defaultButtons);
|
||||
|
||||
questlogDialog = $( "#templates #dialog-questlog" )
|
||||
.dialog({
|
||||
title: "Quest log item",
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 450,
|
||||
buttons: defaultButtons
|
||||
});
|
||||
|
||||
onHitConditionsDialog = $( "#templates #dialog-onHitConditions" )
|
||||
.dialog({
|
||||
title: "Actor status conditon",
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 350,
|
||||
buttons: defaultButtons
|
||||
});
|
||||
|
||||
equipConditionsDialog = $( "#templates #dialog-equipConditions" )
|
||||
.dialog({
|
||||
title: "Actor status conditon",
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 350,
|
||||
buttons: defaultButtons
|
||||
});
|
||||
|
||||
droplistItemDialog = $( "#templates #dialog-droplistItem" )
|
||||
.dialog({
|
||||
title: "Droplist item",
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 350,
|
||||
buttons: defaultButtons
|
||||
});
|
||||
|
||||
phraseRewardDialog = $( "#templates #dialog-phrasereward" )
|
||||
.dialog({
|
||||
title: "Phrase reward",
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 350,
|
||||
buttons: defaultButtons
|
||||
});
|
||||
|
||||
loadResourceFile( 'values/content_itemcategories.xml', function(data) {
|
||||
var allContent = '';
|
||||
$( data ).find("string").each(function() {
|
||||
allContent = allContent + $(this).text();
|
||||
});
|
||||
model.itemCategories.deserialize(allContent);
|
||||
model.itemCategories.items.forEach(function(c) {
|
||||
$("#editItem select#category").append( $("<option>").val(c.id).text(c.name) );
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,162 +0,0 @@
|
||||
|
||||
var DataStore_Data_fieldValue = '[^\\{\\}\\|]*';
|
||||
var DataStore_Data_arrayObject = '\\{(' + DataStore_Data_fieldValue + '\\|)*\\}\\s*';
|
||||
var DataStore_Data_arrayObjectPattern = new RegExp(DataStore_Data_arrayObject, 'g');
|
||||
var DataStore_Data_arrayField = '\\{\\s*(' + DataStore_Data_arrayObject + ')*\\s*\\}';
|
||||
var DataStore_Data_field = '(' + DataStore_Data_fieldValue + '|' + DataStore_Data_arrayField + ')\\|';
|
||||
var DataStore_Data_pattern = new RegExp(DataStore_Data_field, 'gm');
|
||||
var DataStore_Data_line = "^(\\{(" + DataStore_Data_field + ")*\\};)$";
|
||||
var DataStore_Data_linePattern = new RegExp(DataStore_Data_line, 'gm');
|
||||
|
||||
var showErrorMessages = true;
|
||||
|
||||
var specialEncodings = [
|
||||
{
|
||||
decoded: "'", decoded_Regex: /'/gm,
|
||||
encoded: "\\'", encoded_Regex: /\\'/gm
|
||||
},
|
||||
{
|
||||
decoded: "\n", decoded_Regex: /\n/gm,
|
||||
encoded: "\\n", encoded_Regex: /\\n/gm
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
function DataStore(input) {
|
||||
this.objectTypename = input.objectTypename;
|
||||
this.fieldList = input.fieldList;
|
||||
this.nameField = input.nameField ? input.nameField : 'name';
|
||||
this.idField = input.idField ? input.idField : 'id';
|
||||
this.iconField = input.iconField;
|
||||
this.items = [];
|
||||
|
||||
this.add = function(obj) {
|
||||
if (this.items.indexOf(obj) < 0) {
|
||||
this.items.push(obj);
|
||||
this.onAdded(obj);
|
||||
}
|
||||
}
|
||||
this.get = function(index) { return this.items[index]; }
|
||||
this.clear = function() {
|
||||
this.items = [];
|
||||
if (this.onDeserialized) { this.onDeserialized(); }
|
||||
}
|
||||
this.findById = function(id) {
|
||||
for (var i = 0; i < this.items.length; ++i) {
|
||||
var item = this.items[i];
|
||||
if (item[this.idField] == id) return item;
|
||||
}
|
||||
}
|
||||
|
||||
this.onAdded = function(obj) { }
|
||||
this.onPropertyChanged = function(obj, propertyName, value) { }
|
||||
this.onDeserialized = function() { }
|
||||
|
||||
this.deserialize = function(str) {
|
||||
var header = findHeader(str);
|
||||
if (!header) {
|
||||
alert("Could not find header row, cannot deserialize");
|
||||
return;
|
||||
}
|
||||
this.fieldList = header;
|
||||
this.items = deserializeObjectList(header, str);
|
||||
this.onDeserialized();
|
||||
}
|
||||
this.serialize = function() {
|
||||
return serializeObjectList(this.fieldList, this.items);
|
||||
}
|
||||
}
|
||||
|
||||
function deserializeObject(fieldList, data) {
|
||||
var match = data.match(DataStore_Data_pattern);
|
||||
if (!match) return;
|
||||
|
||||
if (match.length != fieldList._fields.length) {
|
||||
if (showErrorMessages) {
|
||||
alert("Error parsing data object. Expected " + fieldList._fields.length + " fields, but found " + match.length + " fields.\ndata = \"" + data + "\"");
|
||||
showErrorMessages = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var obj = {};
|
||||
for (var i = 0; i < fieldList._fields.length; ++i) {
|
||||
var s = match[i].match(DataStore_Data_field)[1]; // Strip trailing pipe
|
||||
|
||||
var f = fieldList._fields[i];
|
||||
var v = s;
|
||||
var fieldName = fieldList.getFieldName(i);
|
||||
if (f instanceof FieldList) {
|
||||
fieldName = f._name;
|
||||
v = [];
|
||||
var objects = s.match(DataStore_Data_arrayObjectPattern);
|
||||
if (objects) {
|
||||
for (var j = 0; j < objects.length; ++j) {
|
||||
v[j] = deserializeObject(f, objects[j]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(var j = 0; j < specialEncodings.length; ++j) {
|
||||
var e = specialEncodings[j];
|
||||
v = v.replace(e.encoded_Regex, e.decoded);
|
||||
}
|
||||
}
|
||||
obj[fieldName] = v;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function deserializeObjectList(fieldList, data) {
|
||||
var result = [];
|
||||
if(!data) return result;
|
||||
var match = data.match(DataStore_Data_linePattern);
|
||||
if(!match) return result;
|
||||
for(var i = 0; i < match.length; ++i) {
|
||||
result[i] = deserializeObject(fieldList, match[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function serializeObject(fieldList, obj) {
|
||||
if (!obj) return "";
|
||||
var result = "{";
|
||||
|
||||
for(var i = 0; i < fieldList._fields.length; ++i) {
|
||||
var fieldName = fieldList.getFieldName(i);
|
||||
var f = fieldList._fields[i];
|
||||
var v = obj[fieldName];
|
||||
if (f instanceof FieldList) {
|
||||
if (v && v.length > 0) {
|
||||
result += "{";
|
||||
if (v.length > 1) { result += "\n"; }
|
||||
for(var j = 0; j < v.length; ++j) {
|
||||
if (v.length > 1) { result += "\t"; }
|
||||
result += serializeObject(f, v[j]);
|
||||
if (v.length > 1) { result += "\n"; }
|
||||
}
|
||||
if (v.length > 1) { result += "\t"; }
|
||||
result += "}";
|
||||
}
|
||||
} else if (v != undefined) {
|
||||
v = "" + v;
|
||||
for(var j = 0; j < specialEncodings.length; ++j) {
|
||||
var e = specialEncodings[j];
|
||||
v = v.replace(e.decoded_Regex, e.encoded);
|
||||
}
|
||||
result += v;
|
||||
}
|
||||
result += "|";
|
||||
}
|
||||
result += "}";
|
||||
return result;
|
||||
}
|
||||
|
||||
function serializeObjectList(fieldList, obj) {
|
||||
var result = fieldList.getHeader() + ";\n";
|
||||
if(!obj) return result;
|
||||
|
||||
for(var i = 0; i < obj.length; ++i) {
|
||||
result += serializeObject(fieldList, obj[i]) + ";\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
|
||||
function changeHidesElement(changedElement, elementToHide, visibilityEvaluator) {
|
||||
changedElement.change(function () {
|
||||
if (visibilityEvaluator()) {
|
||||
elementToHide.fadeIn("slow");
|
||||
} else {
|
||||
elementToHide.fadeOut("slow");
|
||||
}
|
||||
});
|
||||
elementToHide.toggle(visibilityEvaluator());
|
||||
}
|
||||
|
||||
function checkboxHidesElement(checkbox, element, visibleCondition) {
|
||||
var visible = bool(visibleCondition);
|
||||
checkbox.attr("checked", visible);
|
||||
var evaluator = function() { return checkbox.attr("checked"); };
|
||||
changeHidesElement(checkbox, element, evaluator);
|
||||
}
|
||||
|
||||
function checkboxShowsElement(checkbox, element, visibleCondition) {
|
||||
var visible = !bool(visibleCondition);
|
||||
checkbox.attr("checked", visible);
|
||||
var evaluator = function() { return !checkbox.attr("checked"); };
|
||||
changeHidesElement(checkbox, element, evaluator);
|
||||
}
|
||||
|
||||
function bool(v) {
|
||||
if (typeof(v) == 'undefined') return false;
|
||||
if (v == '') return false;
|
||||
if (v == '0') return false;
|
||||
if (v == 'false') return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function setInputFieldsToObjectValues(div, obj) {
|
||||
div.find("input,select,textarea").each(function() {
|
||||
$(this).val(obj[$(this).attr("id")]);
|
||||
});
|
||||
div.find("input:checkbox").each(function() {
|
||||
$(this).attr("checked", bool(obj[$(this).attr("id")]));
|
||||
});
|
||||
}
|
||||
|
||||
function bindInputFieldChangesToObject(div, obj) {
|
||||
div.find("input,select,textarea").unbind("change").change(function() {
|
||||
obj[$(this).attr("id")] = $(this).val();
|
||||
});
|
||||
div.find("input:checkbox").unbind("change").change(function() {
|
||||
obj[$(this).attr("id")] = $(this).attr("checked") ? 1 : 0;
|
||||
});
|
||||
}
|
||||
|
||||
function applyEditorBindingsForObject(div, obj) {
|
||||
div.find("input").addClass("ui-widget-content ui-corner-all");
|
||||
setInputFieldsToObjectValues(div, obj);
|
||||
bindInputFieldChangesToObject(div, obj);
|
||||
}
|
||||
|
||||
function applyCommonEditorBindings(div, obj, dataStore) {
|
||||
applyEditorBindingsForObject(div, obj);
|
||||
if (dataStore) {
|
||||
div.find("input").change(function() {
|
||||
dataStore.onPropertyChanged(obj, $(this).attr('id'), $(this).val());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function bindFieldToDataStore(field, dataStore) {
|
||||
var dataCallback = function(request, response) {
|
||||
var result = [];
|
||||
var pattern = new RegExp(request.term, "i");
|
||||
dataStore.items.forEach(function(obj) {
|
||||
var id = obj[dataStore.idField];
|
||||
var name = obj[dataStore.nameField];
|
||||
var displayName = name + " (" + id + ")";
|
||||
if (displayName.match(pattern)) {
|
||||
result.push({label: displayName, value: id});
|
||||
}
|
||||
});
|
||||
response(result);
|
||||
};
|
||||
field.autocomplete( "destroy" ).autocomplete({
|
||||
source: dataCallback,
|
||||
minLength: 0,
|
||||
select: function(event, ui) {
|
||||
field.val(ui.item.value);
|
||||
field.change();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function shortenString(str, maxChars) {
|
||||
if (!str) return str;
|
||||
str = str.toString();
|
||||
if (str.length <= maxChars) return str;
|
||||
return str.substring(0, maxChars) + "..";
|
||||
}
|
||||
|
||||
function applyTableEditor(input) {
|
||||
|
||||
var updateRowText = function(row, obj) {
|
||||
$( "td", row ).each(function() {
|
||||
var id = $( this ).attr("id");
|
||||
var val = obj[id];
|
||||
val = val ? val : "";
|
||||
$( this ).text(shortenString(val, 30));
|
||||
});
|
||||
};
|
||||
|
||||
var onItemSelected = input.onItemSelected ? input.onItemSelected : function(obj, row) {
|
||||
var dialog = input.dialog;
|
||||
applyEditorBindingsForObject( dialog, obj );
|
||||
if (input.editorSetup) { input.editorSetup(dialog); }
|
||||
dialog.unbind( "dialogclose" ).bind( "dialogclose", function() {
|
||||
updateRowText(row, obj);
|
||||
});
|
||||
dialog.dialog( "open" );
|
||||
};
|
||||
|
||||
var table = input.table;
|
||||
var addToList = function(obj) {
|
||||
var row = $( "<tr>" );
|
||||
table.find("th").each(function() {
|
||||
var id = $( this ).attr("id");
|
||||
row.append( $( "<td>" ).attr("id", id) );
|
||||
});
|
||||
updateRowText(row, obj);
|
||||
table.append(row);
|
||||
row.click(function() { onItemSelected(obj, row); });
|
||||
return row;
|
||||
};
|
||||
table.parent().find("#add").button().unbind("click").click(function() {
|
||||
var obj = input.templateFunction();
|
||||
input.array.push( obj );
|
||||
if (input.onItemAdded) { input.onItemAdded(obj); }
|
||||
addToList( obj ).click();
|
||||
});
|
||||
table.addClass("ui-corner-all");
|
||||
$( "thead", table ).addClass("ui-widget-header");
|
||||
$( "tbody", table ).empty();
|
||||
input.array.forEach(addToList);
|
||||
}
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
|
||||
function EditorTabs(div) {
|
||||
var mainTabs;
|
||||
var nextTabID;
|
||||
var tabInfos = [];
|
||||
var editorTypes = [];
|
||||
|
||||
// =====================================
|
||||
// Private methods
|
||||
|
||||
var closeTab = function(tabID, index) {
|
||||
tabInfos[tabID] = null;
|
||||
mainTabs.tabs( "remove", index );
|
||||
};
|
||||
|
||||
var closeCurrentTab = function() {
|
||||
var index = mainTabs.tabs('option', 'selected');
|
||||
var tab = findTabFromIndex(index);
|
||||
var tabID = $(tab).data("tabID");
|
||||
if (!tabID) { return; }
|
||||
closeTab(tabID, index);
|
||||
};
|
||||
|
||||
var findTab = function(tabID) { return mainTabs.find('ul li a[href="#tabs-' + tabID + '"]').parent(); }
|
||||
var findTabFromIndex = function(tabIndex) { return mainTabs.find('li')[tabIndex]; }
|
||||
var findTabIndex = function(tab) { return $( "li", mainTabs ).index(tab); }
|
||||
|
||||
var addTab = function(title, tabInfo) {
|
||||
var tabID = nextTabID;
|
||||
tabInfos[tabID] = tabInfo;
|
||||
mainTabs.tabs( "add", "#tabs-" + tabID, title );
|
||||
mainTabs.tabs( "select", -1 );
|
||||
var tab = findTab(tabID);
|
||||
tab.find( ".ui-icon-close" ).click(function() {
|
||||
var index = findTabIndex(tab);
|
||||
closeTab(tabID, index);
|
||||
});
|
||||
tab.data("tabID", tabID);
|
||||
nextTabID++;
|
||||
};
|
||||
|
||||
var findTabIDOfObject = function(obj) {
|
||||
for (var i = 1; i < tabInfos.length; ++i) {
|
||||
if (tabInfos[i] && tabInfos[i].obj == obj) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
var createObjectEditor = function(tabInfo) {
|
||||
var creator = editorTypes[tabInfo.objectType];
|
||||
if (!creator) {
|
||||
alert("unknown objectType: " + tabInfo.objectType);
|
||||
return;
|
||||
}
|
||||
return creator(tabInfo.obj);
|
||||
};
|
||||
|
||||
|
||||
// =====================================
|
||||
// Public methods
|
||||
|
||||
this.registerEditorType = function(objectType, editorCreator) {
|
||||
editorTypes[objectType] = editorCreator;
|
||||
};
|
||||
|
||||
this.renameTabForObject = function(obj, name) {
|
||||
var tabID = findTabIDOfObject(obj);
|
||||
if (!tabID) return;
|
||||
findTab(tabID).find("a").text(name);
|
||||
};
|
||||
|
||||
this.openTabForObject = function(obj, objectType, title) {
|
||||
var tabID = findTabIDOfObject(obj);
|
||||
if (tabID > 0) {
|
||||
var index = findTabIndex(findTab(tabID));
|
||||
mainTabs.tabs( "select", index );
|
||||
return;
|
||||
}
|
||||
addTab(title, {obj: obj, objectType: objectType});
|
||||
};
|
||||
|
||||
mainTabs = div.tabs({
|
||||
tabTemplate: "<li><a href='#{href}'>#{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>",
|
||||
add: function( event, ui ) {
|
||||
var editor = createObjectEditor( tabInfos[nextTabID] );
|
||||
$( ui.panel ).append( editor );
|
||||
mainTabs.tabs('select', ui.index);
|
||||
}
|
||||
});
|
||||
mainTabs.find( ".ui-tabs-nav" ).sortable({ axis: "x" });
|
||||
nextTabID = mainTabs.size() + 1;
|
||||
|
||||
div.keydown(function(e) {
|
||||
if (e.keyCode == 27 /* ESC */ ) { closeCurrentTab(); }
|
||||
});
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
function createActorConditionEditor(obj) {
|
||||
var div = $( "#templates #editActorCondition" ).clone();
|
||||
applyCommonEditorBindings(div, obj, model.actorConditions);
|
||||
checkboxHidesElement(div.find('#hasRoundEffect'), div.find('#hasRoundEffectDisplay'), obj.hasRoundEffect);
|
||||
checkboxHidesElement(div.find('#hasFullRoundEffect'), div.find('#hasFullRoundEffectDisplay'), obj.hasFullRoundEffect);
|
||||
checkboxHidesElement(div.find('#hasAbilityEffect'), div.find('#hasAbilityEffectDisplay'), obj.hasAbilityEffect);
|
||||
checkboxHidesElement(div.find('#hasCritical'), div.find('#hasCriticalDisplay'), obj.criticalChance || obj.criticalMultiplier);
|
||||
imageSelector.imageify(div.find('#actorconditionimage'), div.find('#iconID'), 'conditions');
|
||||
return div;
|
||||
}
|
||||
|
||||
@@ -1,319 +0,0 @@
|
||||
|
||||
|
||||
function createConversationEditor(obj) {
|
||||
var div = $( "#templates #editDialogue" ).clone(true);
|
||||
|
||||
var treeDiv = $ ( "#dialogueTree", div );
|
||||
treeDiv.dynatree({
|
||||
title: "Conversation flow"
|
||||
,imagePath: 'img'
|
||||
});
|
||||
var tree = treeDiv.dynatree("getTree");
|
||||
|
||||
var rootNode = treeDiv.dynatree("getRoot");
|
||||
updatePhraseTreeNodesBelow(tree, rootNode, obj);
|
||||
|
||||
treeDiv.dynatree({
|
||||
onActivate: function(node) {
|
||||
onConversationPhraseSelected(div, node.data.model, tree);
|
||||
}
|
||||
});
|
||||
|
||||
tree.activateKey(obj.id);
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
function getPhraseByPhraseID(phraseID) {
|
||||
if (!phraseID) return;
|
||||
return model.dialogue.findById(phraseID);
|
||||
}
|
||||
|
||||
function onConversationPhraseSelected(div, obj, tree) {
|
||||
var dialoguePhrase = $( "#dialoguePhrase", div );
|
||||
var dialogueReply = $( "#dialogueReply", div );
|
||||
var dialoguePhraseReplies = $( "#dialoguePhraseReplies", div );
|
||||
dialogueReply.hide();
|
||||
dialoguePhrase.hide();
|
||||
dialoguePhraseReplies.hide();
|
||||
if (!obj) return;
|
||||
|
||||
var treeNodeKey = getTreeNodeKey(obj);
|
||||
var treeNode = tree.getNodeByKey(treeNodeKey);
|
||||
if (!treeNode) {
|
||||
treeNode = updatePhraseTreeNodesBelow(tree, tree.getRoot(), obj, true);
|
||||
}
|
||||
|
||||
treeNode.activateSilently();
|
||||
|
||||
applyCommonEditorBindings(div, obj, model.dialogue);
|
||||
|
||||
if (obj.isPhrase) {
|
||||
buildEditorForPhrase(div, obj, tree, treeNode);
|
||||
} else {
|
||||
buildEditorForReply(div, obj, tree, treeNode);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================================
|
||||
// Set up editor for NPC phrases
|
||||
|
||||
function buildEditorForPhrase(div, phrase, tree, treeNode) {
|
||||
var dialoguePhrase = $( "#dialoguePhrase", div );
|
||||
var dialoguePhraseReplies = $( "#dialoguePhraseReplies", div );
|
||||
|
||||
checkboxHidesElement( $( '#hasRewards', dialoguePhrase ), $( '#hasRewardsDisplay', dialoguePhrase ), phrase.rewards);
|
||||
|
||||
var rebuildChildNodes = function() {
|
||||
updatePhraseReplyTreeNodesBelow(tree, treeNode, phrase);
|
||||
}
|
||||
var reloadReplyTable = function() {
|
||||
applyTableEditor({
|
||||
table: $( "#replies", dialoguePhraseReplies ),
|
||||
array: phrase.replies,
|
||||
templateFunction: function() { return createReplyForPhrase(phrase); },
|
||||
onItemSelected: function(obj) {
|
||||
onConversationPhraseSelected(div, obj, tree);
|
||||
},
|
||||
onItemAdded: function(addedObject) {
|
||||
rebuildChildNodes();
|
||||
}
|
||||
});
|
||||
}
|
||||
reloadReplyTable();
|
||||
|
||||
var hasOnlyNextReply = $( '#hasOnlyNextReply', dialoguePhraseReplies );
|
||||
checkboxHidesElement( hasOnlyNextReply, $( '#hasOnlyNextReplyDisplay', dialoguePhraseReplies ), phrase.hasOnlyNextReply);
|
||||
checkboxShowsElement( hasOnlyNextReply, $( '#hasRepliesDisplay', dialoguePhraseReplies ), !phrase.hasOnlyNextReply);
|
||||
|
||||
hasOnlyNextReply.change(function() {
|
||||
if ( $(this).attr("checked") ) {
|
||||
var nextReply = createReplyForPhrase(phrase);
|
||||
nextReply.text = 'N';
|
||||
phrase.replies = [ nextReply ];
|
||||
} else {
|
||||
phrase.replies = [ ];
|
||||
reloadReplyTable();
|
||||
}
|
||||
rebuildChildNodes();
|
||||
});
|
||||
|
||||
var nextPhraseID = $( "#nextPhraseID", dialoguePhraseReplies );
|
||||
nextPhraseID.unbind("change").change(function() {
|
||||
phrase.replies[0].nextPhraseID = $( this ).val();
|
||||
rebuildChildNodes();
|
||||
});
|
||||
if (phrase.hasOnlyNextReply) {
|
||||
nextPhraseID.val(phrase.replies[0].nextPhraseID);
|
||||
}
|
||||
|
||||
var phraseID = $( "#id", dialoguePhrase );
|
||||
phraseID.change(function() {
|
||||
treeNode.data.key = phrase.id;
|
||||
rebuildChildNodes();
|
||||
});
|
||||
|
||||
$( "#followNextReply", dialoguePhraseReplies ).button().unbind('click').click(function() {
|
||||
openNextPhrase(nextPhraseID.val(), div, phrase.replies[0], tree);
|
||||
});
|
||||
|
||||
$( '#message', dialoguePhrase ).change(function() { treeNode.setTitle( getPhraseNodeText(phrase) ); });
|
||||
|
||||
var createNewReward = function() { return { rewardType: 0 }; }
|
||||
var setupEditor = function(div) { }
|
||||
if (!phrase.rewards) phrase.rewards = [];
|
||||
applyTableEditor({
|
||||
table: $( '#rewards', dialoguePhrase ),
|
||||
dialog: phraseRewardDialog,
|
||||
array: phrase.rewards,
|
||||
templateFunction: createNewReward,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
|
||||
dialoguePhrase.show();
|
||||
dialoguePhraseReplies.show();
|
||||
}
|
||||
|
||||
function createReplyForPhrase(phrase) {
|
||||
return {
|
||||
id: phrase.id,
|
||||
isPhrase: false,
|
||||
phrase: phrase
|
||||
};
|
||||
}
|
||||
|
||||
function openNextPhrase(nextPhraseID, div, reply, tree) {
|
||||
var createNewPhrase = true;
|
||||
var phrase;
|
||||
if (nextPhraseID) {
|
||||
phrase = getPhraseByPhraseID(nextPhraseID);
|
||||
if (phrase) {
|
||||
createNewPhrase = false;
|
||||
}
|
||||
} else {
|
||||
nextPhraseID = generatePhraseID(reply.phrase.id);
|
||||
}
|
||||
|
||||
if (createNewPhrase) {
|
||||
phrase = { id: nextPhraseID, isPhrase: true };
|
||||
model.dialogue.add(phrase);
|
||||
}
|
||||
reply.nextPhraseID = nextPhraseID;
|
||||
|
||||
var treeNodeKey = getTreeNodeKey(reply.phrase);
|
||||
var treeNode = tree.getNodeByKey(treeNodeKey);
|
||||
updatePhraseReplyTreeNodesBelow(tree, treeNode, reply.phrase);
|
||||
//alert("followNextReply: " + nextPhraseID);
|
||||
onConversationPhraseSelected(div, phrase, tree);
|
||||
}
|
||||
|
||||
function generatePhraseID(previousPhraseID) {
|
||||
var suffix;
|
||||
var n = 1;
|
||||
|
||||
var match = (/^(.*\D)(\d+)$/g).exec(previousPhraseID);
|
||||
if (match) {
|
||||
suffix = match[1];
|
||||
n = parseInt(match[2]) + 1;
|
||||
} else {
|
||||
suffix = previousPhraseID + "_";
|
||||
}
|
||||
|
||||
for (var i = n; i < 1000; ++i) {
|
||||
var phraseID = suffix + i;
|
||||
if (!getPhraseByPhraseID(phraseID)) return phraseID;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================================
|
||||
// Set up editor for replies
|
||||
|
||||
function buildEditorForReply(div, reply, tree, treeNode) {
|
||||
var dialogueReply = $( "#dialogueReply", div );
|
||||
|
||||
checkboxHidesElement( $( '#requiresItems', dialogueReply ), $( '#requiresItemsDisplay', dialogueReply ), reply.requires_itemID);
|
||||
checkboxHidesElement( $( '#requiresQuest', dialogueReply ), $( '#requiresQuestDisplay', dialogueReply ), reply.requires_Progress);
|
||||
bindFieldToDataStore( $( "#requires_itemID", dialogueReply ), model.items);
|
||||
bindFieldToDataStore( $( "#requires_Progress", dialogueReply ), model.quests);
|
||||
|
||||
var replyLeadsTo = $( "#replyLeadsTo", dialogueReply );
|
||||
replyLeadsTo.val(reply.nextPhraseID);
|
||||
if (!replyLeadsTo.val()) { replyLeadsTo.val(""); }
|
||||
replyLeadsTo.change(function() { nextPhraseID.val( $(this).val() ).change(); });
|
||||
changeHidesElement(replyLeadsTo, $( "#nextPhraseIDDisplay", dialogueReply ) , function() { return replyLeadsTo.val() == ''; } );
|
||||
|
||||
var nextPhraseID = $( "#nextPhraseID", dialogueReply );
|
||||
nextPhraseID.change(function() {
|
||||
updatePhraseTreeNodesBelow(tree, treeNode, getPhraseByPhraseID(reply.nextPhraseID) );
|
||||
});
|
||||
|
||||
$( "#followReply", dialogueReply ).button().unbind('click').click(function() {
|
||||
openNextPhrase(nextPhraseID.val(), div, reply, tree);
|
||||
});
|
||||
|
||||
$( '#text', dialogueReply ).change(function() { treeNode.setTitle( getReplyNodeText(reply) ); });
|
||||
|
||||
dialogueReply.show();
|
||||
}
|
||||
|
||||
|
||||
// ========================================================
|
||||
// Tree node key generators
|
||||
|
||||
function getTreeNodeKey(obj) {
|
||||
if (!obj) return "";
|
||||
if (obj.isPhrase) return obj.id;
|
||||
return getTreeNodeReplyKey(obj);
|
||||
}
|
||||
|
||||
function getTreeNodeReplyKey(obj) {
|
||||
var idx = 0;
|
||||
for (var i = 0; i < obj.phrase.replies.length; ++i) {
|
||||
if (obj.phrase.replies[i] == obj) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return getTreeNodeReplyKeyIndex(obj, idx);
|
||||
}
|
||||
|
||||
function getTreeNodeReplyKeyIndex(obj, idx) {
|
||||
return getTreeNodeKey(obj.phrase) + "__reply_" + idx;
|
||||
}
|
||||
|
||||
|
||||
// ========================================================
|
||||
// Tree node title generators
|
||||
|
||||
function getPhraseNodeText(phrase) {
|
||||
return phrase.message ? shortenString(phrase.message, 30) : "(no phrase text)";
|
||||
}
|
||||
|
||||
function getReplyNodeText(reply) {
|
||||
return reply.text ? shortenString(reply.text, 30) : "(no reply text)";
|
||||
}
|
||||
|
||||
// ========================================================
|
||||
// Tree-building functions
|
||||
|
||||
// (re)Build a NPC phrase node
|
||||
function updatePhraseTreeNodesBelow(tree, parent, phrase, keepExisting) {
|
||||
if (!keepExisting) { parent.removeChildren(); }
|
||||
|
||||
if (!phrase) return;
|
||||
|
||||
phrase.isPhrase = true;
|
||||
var key = getTreeNodeKey(phrase);
|
||||
|
||||
if (tree.getNodeByKey(key)) {
|
||||
parent.addChild({
|
||||
title: '(conversation loop)'
|
||||
,model: phrase
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var phraseNode = parent.addChild({
|
||||
title: getPhraseNodeText(phrase)
|
||||
,key: key
|
||||
,model: phrase
|
||||
,icon: 'phrase.png'
|
||||
});
|
||||
|
||||
if (!phrase.replies) phrase.replies = [];
|
||||
updatePhraseReplyTreeNodesBelow(tree, phraseNode, phrase, phrase.replies);
|
||||
|
||||
phraseNode.expand(true);
|
||||
return phraseNode;
|
||||
}
|
||||
|
||||
// (re)Build all nodes below a NPC phrase (i.e. rebuild all reply nodes)
|
||||
function updatePhraseReplyTreeNodesBelow(tree, phraseNode, phrase) {
|
||||
phraseNode.removeChildren();
|
||||
|
||||
if (!phrase.replies) phrase.replies = [];
|
||||
|
||||
if (phrase.replies.length == 1) {
|
||||
var singleReply = phrase.replies[0];
|
||||
if (singleReply.text == 'N') {
|
||||
phrase.hasOnlyNextReply = true;
|
||||
updatePhraseTreeNodesBelow(tree, phraseNode, getPhraseByPhraseID(singleReply.nextPhraseID) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
phrase.replies.forEach(function(reply, idx) {
|
||||
jQuery.extend(reply, createReplyForPhrase(phrase));
|
||||
var key = getTreeNodeReplyKeyIndex(reply, idx);
|
||||
var replyNode = phraseNode.addChild({
|
||||
title: getReplyNodeText(reply)
|
||||
,key: key
|
||||
,model: reply
|
||||
,icon: 'reply.png'
|
||||
});
|
||||
if (reply.nextPhraseID) {
|
||||
updatePhraseTreeNodesBelow(tree, replyNode, getPhraseByPhraseID(reply.nextPhraseID) );
|
||||
}
|
||||
replyNode.expand(true);
|
||||
});
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
function createDroplistEditor(obj) {
|
||||
var div = $( "#templates #editDroplist" ).clone(true);
|
||||
applyCommonEditorBindings(div, obj, model.droplists);
|
||||
if (!obj.items) obj.items = [];
|
||||
|
||||
applyTableEditor({
|
||||
table: $( "#items", div ),
|
||||
dialog: droplistItemDialog,
|
||||
array: obj.items,
|
||||
templateFunction: function() { return { quantity: 1, chance: 100 } },
|
||||
editorSetup: function(div) {
|
||||
bindFieldToDataStore( $( "#itemID", div ), model.items);
|
||||
}
|
||||
});
|
||||
|
||||
return div;
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
|
||||
function sgn(v) {
|
||||
if (v < 0) return -1;
|
||||
else if (v > 0) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
function createItemEditor(obj) {
|
||||
var div = $( "#templates #editItem" ).clone();
|
||||
applyCommonEditorBindings(div, obj, model.items);
|
||||
checkboxHidesElement(div.find('#hasEquipEffect'), div.find('#hasEquipEffectDisplay'), obj.hasEquipEffect);
|
||||
checkboxHidesElement(div.find('#hasUseEffect'), div.find('#hasUseEffectDisplay'), obj.hasUseEffect);
|
||||
checkboxHidesElement(div.find('#equip_hasCritical'), div.find('#equip_hasCriticalDisplay'), obj.equip_criticalChance || obj.equip_criticalMultiplier);
|
||||
checkboxHidesElement(div.find('#hasHitEffect'), div.find('#hasHitEffectDisplay'), obj.hasHitEffect);
|
||||
checkboxHidesElement(div.find('#hasKillEffect'), div.find('#hasKillEffectDisplay'), obj.hasKillEffect);
|
||||
imageSelector.imageify(div.find('#itemimage'), div.find('#iconID'), 'items');
|
||||
|
||||
var createNewCondition = function() { return { chance: 100, magnitude: 1 }; }
|
||||
if (!obj.equip_conditions) obj.equip_conditions = [];
|
||||
if (!obj.use_conditionsSource) obj.use_conditionsSource = [];
|
||||
if (!obj.hit_conditionsSource) obj.hit_conditionsSource = [];
|
||||
if (!obj.hit_conditionsTarget) obj.hit_conditionsTarget = [];
|
||||
if (!obj.kill_conditionsSource) obj.kill_conditionsSource = [];
|
||||
var setupEditor = function(div) {
|
||||
bindFieldToDataStore( $( "#condition", div ), model.actorConditions);
|
||||
}
|
||||
|
||||
applyTableEditor({
|
||||
table: $( "#equip_conditions", div ),
|
||||
dialog: equipConditionsDialog,
|
||||
array: obj.equip_conditions,
|
||||
templateFunction: createNewCondition,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
applyTableEditor({
|
||||
table: $( "#use_conditionsSource", div ),
|
||||
dialog: onHitConditionsDialog,
|
||||
array: obj.use_conditionsSource,
|
||||
templateFunction: createNewCondition,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
applyTableEditor({
|
||||
table: $( "#hit_conditionsSource", div ),
|
||||
dialog: onHitConditionsDialog,
|
||||
array: obj.hit_conditionsSource,
|
||||
templateFunction: createNewCondition,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
applyTableEditor({
|
||||
table: $( "#hit_conditionsTarget", div ),
|
||||
dialog: onHitConditionsDialog,
|
||||
array: obj.hit_conditionsTarget,
|
||||
templateFunction: createNewCondition,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
applyTableEditor({
|
||||
table: $( "#kill_conditionsSource", div ),
|
||||
dialog: onHitConditionsDialog,
|
||||
array: obj.kill_conditionsSource,
|
||||
templateFunction: createNewCondition,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
|
||||
|
||||
var itemCostDependsOn = [];
|
||||
var sv = function(s) {
|
||||
var field = $( s, div );
|
||||
itemCostDependsOn.push(field);
|
||||
return field.val();
|
||||
}
|
||||
var v = function(s) {
|
||||
var val = sv(s);
|
||||
if (!val) return 0;
|
||||
return parseInt(val);
|
||||
}
|
||||
var cb = function(s) {
|
||||
var field = $( s, div );
|
||||
itemCostDependsOn.push(field);
|
||||
return field.attr("checked");
|
||||
}
|
||||
var calculateItemCost = function() {
|
||||
itemCostDependsOn = [];
|
||||
var averageHPBoost = (v("#use_boostHP_Min") + v("#use_boostHP_Max")) / 2;
|
||||
var costBoostHP = Math.round(0.1*sgn(averageHPBoost)*Math.pow(Math.abs(averageHPBoost), 2) + 3*averageHPBoost);
|
||||
var itemUsageCost = costBoostHP;
|
||||
|
||||
var isWeapon = model.itemCategories.findById(sv("#category")).inventorySlot == 0;
|
||||
|
||||
var equip_blockChance = v("#equip_blockChance");
|
||||
var equip_attackChance = v("#equip_attackChance");
|
||||
var equip_attackCost = v("#equip_attackCost");
|
||||
var equip_damageResistance = v("#equip_damageResistance");
|
||||
var equip_attackDamage_Min = v("#equip_attackDamage_Min");
|
||||
var equip_attackDamage_Max = v("#equip_attackDamage_Max");
|
||||
var equip_criticalChance = v("#equip_criticalChance");
|
||||
var equip_criticalMultiplier = v("#equip_criticalMultiplier");
|
||||
var costBC = Math.round(3*Math.pow(Math.max(0,equip_blockChance), 2.5) + 28*equip_blockChance);
|
||||
var costAC = Math.round(0.4*Math.pow(Math.max(0,equip_attackChance), 2.5) - 6*Math.pow(Math.abs(Math.min(0,equip_attackChance)),2.7));
|
||||
var costAP = isWeapon ?
|
||||
Math.round(0.2*Math.pow(10/equip_attackCost, 8) - 25*equip_attackCost)
|
||||
: -3125 * equip_attackCost;
|
||||
var costDR = 1325*equip_damageResistance;
|
||||
var costDMG_Min = isWeapon ?
|
||||
Math.round(10*Math.pow(equip_attackDamage_Min, 2.5))
|
||||
:Math.round(10*Math.pow(equip_attackDamage_Min, 3) + equip_attackDamage_Min*80);
|
||||
var costDMG_Max = isWeapon ?
|
||||
Math.round(2*Math.pow(equip_attackDamage_Max, 2.1))
|
||||
:Math.round(2*Math.pow(equip_attackDamage_Max, 3) + equip_attackDamage_Max*20);
|
||||
var costCC = Math.round(2.2*Math.pow(equip_criticalChance, 3));
|
||||
var costCM = Math.round(50*Math.pow(Math.max(0, equip_criticalMultiplier), 2));
|
||||
if (!cb("#equip_hasCritical")) {
|
||||
costCC = 0;
|
||||
costCM = 0;
|
||||
}
|
||||
var costCombat = costBC + costAC + costAP + costDR + costDMG_Min + costDMG_Max + costCC + costCM;
|
||||
|
||||
var equip_boostMaxHP = v("#equip_boostMaxHP");
|
||||
var equip_boostMaxAP = v("#equip_boostMaxAP");
|
||||
var equip_moveCostPenalty = v("#equip_moveCostPenalty");
|
||||
var costMaxHP = Math.round(30*Math.pow(Math.max(0,equip_boostMaxHP), 1.2) + 70*equip_boostMaxHP);
|
||||
var costMaxAP = Math.round(50*Math.pow(Math.max(0,equip_boostMaxAP), 3) + 750*equip_boostMaxAP);
|
||||
var costMovement = Math.round(510*Math.pow(Math.max(0,-equip_moveCostPenalty), 2.5) - 350*equip_moveCostPenalty);
|
||||
var itemEquipCost = costCombat + costMaxHP + costMaxAP + costMovement;
|
||||
|
||||
if (!cb("#hasEquipEffect")) { itemEquipCost = 0; }
|
||||
if (!cb("#hasUseEffect")) { itemUsageCost = 0; }
|
||||
|
||||
return itemEquipCost + itemUsageCost;
|
||||
}
|
||||
|
||||
var divBaseMarketCost = $( "#baseMarketCost", div );
|
||||
var recalculateStorePrice = function() {
|
||||
var val = parseInt(obj.baseMarketCost);
|
||||
if (!obj.hasManualPrice) {
|
||||
val = calculateItemCost(obj);
|
||||
obj.baseMarketCost = val;
|
||||
divBaseMarketCost.val(val);
|
||||
}
|
||||
$( "#marketCost_Sell", div ).val(Math.round(val * (100 + 15) / 100));
|
||||
$( "#marketCost_Buy", div ).val(Math.round(val * (100 - 15) / 100));
|
||||
};
|
||||
|
||||
divBaseMarketCost.change(recalculateStorePrice);
|
||||
$( "#hasManualPrice", div ).change(function() {
|
||||
if (obj.hasManualPrice) {
|
||||
divBaseMarketCost.removeAttr("readonly");
|
||||
} else {
|
||||
divBaseMarketCost.attr("readonly", "readonly");
|
||||
}
|
||||
recalculateStorePrice();
|
||||
}).change();
|
||||
|
||||
calculateItemCost();
|
||||
jQuery.each(itemCostDependsOn, function(idx, o) {
|
||||
o.change(recalculateStorePrice);
|
||||
});
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
|
||||
function createMonsterEditor(obj) {
|
||||
if (!obj.maxAP) { obj.maxAP = 10; }
|
||||
if (!obj.size) { obj.size = "1x1"; }
|
||||
|
||||
var div = $( "#templates #editMonster" ).clone();
|
||||
applyCommonEditorBindings(div, obj, model.monsters);
|
||||
checkboxHidesElement(div.find('#hasConversation'), div.find('#hasConversationDisplay'), obj.phraseID);
|
||||
checkboxHidesElement(div.find('#hasCombat'), div.find('#hasCombatDisplay'), obj.attackChance);
|
||||
checkboxHidesElement(div.find('#hasCritical'), div.find('#hasCriticalDisplay'), obj.criticalChance || obj.criticalMultiplier);
|
||||
checkboxHidesElement(div.find('#hasHitEffect'), div.find('#hasHitEffectDisplay'), obj.hasHitEffect);
|
||||
imageSelector.imageify(div.find('#monsterimage'), div.find('#iconID'), 'monsters');
|
||||
bindFieldToDataStore( $( "#droplistID", div ), model.droplists );
|
||||
|
||||
var createNewCondition = function() { return { chance: 100, magnitude: 1 }; }
|
||||
if (!obj.onHit_conditionsSource) obj.onHit_conditionsSource = [];
|
||||
if (!obj.onHit_conditionsTarget) obj.onHit_conditionsTarget = [];
|
||||
var setupEditor = function(div) {
|
||||
bindFieldToDataStore( $( "#condition", div ), model.actorConditions );
|
||||
}
|
||||
applyTableEditor({
|
||||
table: $( "#onHit_conditionsSource", div ),
|
||||
dialog: onHitConditionsDialog,
|
||||
array: obj.onHit_conditionsSource,
|
||||
templateFunction: createNewCondition,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
applyTableEditor({
|
||||
table: $( "#onHit_conditionsTarget", div ),
|
||||
dialog: onHitConditionsDialog,
|
||||
array: obj.onHit_conditionsTarget,
|
||||
templateFunction: createNewCondition,
|
||||
editorSetup: setupEditor
|
||||
});
|
||||
|
||||
var expDependsOn = [];
|
||||
var div100 = function(v) { return v / 100; }
|
||||
var v = function(s) {
|
||||
var field = $( s, div );
|
||||
expDependsOn.push(field);
|
||||
var val = field.val();
|
||||
if (!val) return 0;
|
||||
return parseInt(val);
|
||||
}
|
||||
var updateExperience = function() {
|
||||
/*
|
||||
final float avgAttackHP = t.getAttacksPerTurn(maxAP) * div100(t.attackChance) * t.damagePotential.averagef() * (1 + div100(t.criticalChance) * t.criticalMultiplier);
|
||||
final float avgDefenseHP = maxHP * (1 + div100(t.blockChance)) + Constants.EXP_FACTOR_DAMAGERESISTANCE * t.damageResistance;
|
||||
return (int) Math.ceil((avgAttackHP * 3 + avgDefenseHP) * Constants.EXP_FACTOR_SCALING);
|
||||
*/
|
||||
|
||||
expDependsOn = [];
|
||||
|
||||
var EXP_FACTOR_DAMAGERESISTANCE = 9;
|
||||
var EXP_FACTOR_SCALING = 0.7;
|
||||
|
||||
var attacksPerTurn = Math.floor(v("#maxAP") / v("#attackCost"));
|
||||
var avgDamagePotential = (v("#attackDamage_Min") + v("#attackDamage_Max")) / 2;
|
||||
var avgAttackHP = attacksPerTurn * div100(v("#attackChance")) * avgDamagePotential * (1 + div100(v("#criticalChance")) * v("#criticalMultiplier"));
|
||||
var avgDefenseHP = v("#maxHP") * (1 + div100(v("#blockChance"))) + EXP_FACTOR_DAMAGERESISTANCE * v("#damageResistance");
|
||||
var experience = (avgAttackHP * 3 + avgDefenseHP) * EXP_FACTOR_SCALING;
|
||||
|
||||
$( "#experience", div ).val(Math.ceil(experience));
|
||||
};
|
||||
|
||||
updateExperience();
|
||||
jQuery.each(expDependsOn, function(idx, o) {
|
||||
o.change(updateExperience);
|
||||
});
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
function createQuestEditor(obj) {
|
||||
var div = $( "#templates #editQuest" ).clone(true);
|
||||
applyCommonEditorBindings(div, obj, model.quests);
|
||||
if (!obj.stages) obj.stages = [];
|
||||
var array = obj.stages;
|
||||
var createNewStage = function() {
|
||||
var nextProgress;
|
||||
if (array.length > 0) { nextProgress = parseInt(array[array.length - 1].progress) + 10; }
|
||||
if (!nextProgress) { nextProgress = 10; }
|
||||
return { progress: nextProgress };
|
||||
};
|
||||
applyTableEditor({
|
||||
table: $( "#stages", div ),
|
||||
dialog: questlogDialog,
|
||||
array: array,
|
||||
templateFunction: createNewStage
|
||||
});
|
||||
return div;
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
|
||||
var FieldList_Header_fieldName = '[^\\[\\]\\|]*';
|
||||
var FieldList_Header_arrayField = FieldList_Header_fieldName + '\\[(' + FieldList_Header_fieldName + '\\|)*\\]';
|
||||
var FieldList_Header_arrayFieldName = new RegExp(FieldList_Header_fieldName);
|
||||
var FieldList_Header_field = '(' + FieldList_Header_fieldName + '|' + FieldList_Header_arrayField + ')\\|';
|
||||
var FieldList_Header_pattern = new RegExp(FieldList_Header_field, 'g');
|
||||
var FieldList_Header_line = "^(\\[(" + FieldList_Header_field + ")*\\];)$";
|
||||
var FieldList_Header_linePattern = new RegExp(FieldList_Header_line, 'm');
|
||||
|
||||
function FieldList(header, name) {
|
||||
this._name = name ? name : "";
|
||||
this._fields = [];
|
||||
|
||||
var match = header.match(FieldList_Header_pattern);
|
||||
if (!match) return;
|
||||
|
||||
for (var i = 0; i < match.length; ++i) {
|
||||
var s = match[i].match(FieldList_Header_field)[1]; // Strip trailing pipe
|
||||
|
||||
var f = s;
|
||||
if (s.match(FieldList_Header_arrayField)) {
|
||||
var name = s.match(FieldList_Header_arrayFieldName)[0];
|
||||
f = new FieldList(s, name);
|
||||
}
|
||||
this._fields[i] = f;
|
||||
}
|
||||
|
||||
this.getFieldName = function(i) {
|
||||
var f = this._fields[i];
|
||||
if (f instanceof FieldList) {
|
||||
return f._name;
|
||||
} else {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
this.getHeader = function() {
|
||||
var result = this._name + "[";
|
||||
for(var i = 0; i < this._fields.length; ++i) {
|
||||
var f = this._fields[i];
|
||||
if (f instanceof FieldList) {
|
||||
result += f.getHeader();
|
||||
} else {
|
||||
result += f;
|
||||
}
|
||||
result += "|";
|
||||
}
|
||||
result += "]";
|
||||
return result;
|
||||
}
|
||||
|
||||
this.getHeaderLine = function() {
|
||||
return this.getHeader() + ";";
|
||||
}
|
||||
}
|
||||
|
||||
function findHeader(str) {
|
||||
var match = str.match(FieldList_Header_linePattern);
|
||||
if (!match) return;
|
||||
return new FieldList(match[0]);
|
||||
}
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
|
||||
function TilesetImage(name, numTiles, tileSize, tags) {
|
||||
this._name = name;
|
||||
this._numTiles = numTiles ? numTiles : { x: 1, y: 1 };
|
||||
this._tileSize = tileSize ? tileSize : { x: 32, y: 32 };
|
||||
this._tags = tags ? tags : [];
|
||||
|
||||
this.localIDToCoords = function(localID) {
|
||||
return {
|
||||
x: (localID % this._numTiles.x) * this._tileSize.x,
|
||||
y: Math.floor(localID / this._numTiles.x) * this._tileSize.y
|
||||
}
|
||||
}
|
||||
this.coordsToLocalID = function(x, y) {
|
||||
return Math.floor(x / this._tileSize.x)
|
||||
+ this._numTiles.x * Math.floor(y / this._tileSize.y)
|
||||
}
|
||||
}
|
||||
|
||||
var defaultimage = {
|
||||
name: 'defaultimage',
|
||||
localID: 0,
|
||||
path: ''
|
||||
};
|
||||
|
||||
function ImageSelector(imagePath, dialog) {
|
||||
var _tilesets = {};
|
||||
_tilesets[""] = new TilesetImage(defaultimage.name);
|
||||
_tilesets[defaultimage.name] = _tilesets[""];
|
||||
|
||||
var currentInput;
|
||||
|
||||
var get = function(name) { return _tilesets[name]; }
|
||||
|
||||
var parseImageID = function(str) {
|
||||
if (!str || str == "") return defaultimage;
|
||||
var v = str.split(":");
|
||||
if (v.length < 1) return defaultimage;
|
||||
return {
|
||||
name: v[0],
|
||||
localID: v[1],
|
||||
path: imagePath
|
||||
};
|
||||
}
|
||||
|
||||
var getImageID = function(name, localID) {
|
||||
if (!name) return "";
|
||||
return name + ":" + localID;
|
||||
}
|
||||
|
||||
this.setImage = function(imageElem, imageID, scale) {
|
||||
if (!scale) scale = 1;
|
||||
var img = parseImageID(imageID);
|
||||
var tilesetImage = get(img.name);
|
||||
if (!tilesetImage) { tilesetImage = get(""); }
|
||||
var c = tilesetImage.localIDToCoords(img.localID);
|
||||
imageElem.css({
|
||||
"background-image": "url(" +img.path + img.name + ".png)",
|
||||
"background-position": (-c.x)*scale+"px " + (-c.y)*scale+"px",
|
||||
"width": tilesetImage._tileSize.x * scale + "px",
|
||||
"height": tilesetImage._tileSize.y * scale + "px",
|
||||
"cursor": "pointer"
|
||||
});
|
||||
if (scale) {
|
||||
imageElem.css({
|
||||
"background-size":
|
||||
tilesetImage._tileSize.x * tilesetImage._numTiles.x * scale + "px "
|
||||
+ tilesetImage._tileSize.y * tilesetImage._numTiles.y * scale + "px "
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.add = function(tileset) {
|
||||
var name = tileset._name;
|
||||
_tilesets[name] = tileset;
|
||||
dialog.append("<img src=\"" + imagePath + name + ".png\" id=\"" + name + "\" style=\"cursor: pointer;\" />");
|
||||
|
||||
dialog.find("#" + name).click(function(e) {
|
||||
var x = e.pageX - $(this).offset().left;
|
||||
var y = e.pageY - $(this).offset().top;
|
||||
var localID = tileset.coordsToLocalID(x, y);
|
||||
currentInput.val(getImageID(name, localID));
|
||||
currentInput.change(); // Causes the change handler to be run, thus updating the image.
|
||||
dialog.dialog("close");
|
||||
});
|
||||
}
|
||||
|
||||
var showImages = function(showTilesetTag) {
|
||||
jQuery.each(_tilesets, function(idx, t) {
|
||||
if (!idx) return;
|
||||
var visible = t._tags.indexOf(showTilesetTag) >= 0;
|
||||
$( "#" + idx, dialog ).toggle(visible);
|
||||
});
|
||||
}
|
||||
|
||||
this.imageify = function(img, elem, showTilesetTag) {
|
||||
var setImage = this.setImage;
|
||||
elem.change(function() { setImage(img, elem.val()); });
|
||||
img.click(function() {
|
||||
currentInput = elem;
|
||||
showImages(showTilesetTag);
|
||||
dialog.dialog("open");
|
||||
});
|
||||
elem.change();
|
||||
}
|
||||
|
||||
|
||||
dialog.dialog({
|
||||
title: "Select icon",
|
||||
autoOpen: false,
|
||||
modal: true,
|
||||
width: 730,
|
||||
height: 800,
|
||||
position: [30,30],
|
||||
buttons: {
|
||||
Cancel: function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
|
||||
var importDialog;
|
||||
var exportDialog;
|
||||
|
||||
function exportIfExists(dataStore, div) {
|
||||
var exportData = dataStore.serialize();
|
||||
$( "#value" , div ).val(exportData);
|
||||
}
|
||||
|
||||
function importDatastore(dataStore, content) {
|
||||
dataStore.deserialize(content);
|
||||
}
|
||||
|
||||
function prepareImport(dataStore, div) {
|
||||
var importButton = $( "#import", div );
|
||||
var textarea = $( "#value", div );
|
||||
importButton.button().click(function() {
|
||||
if (!textarea.val()) return;
|
||||
importDatastore(dataStore, textarea.val());
|
||||
});
|
||||
textarea.keyup(function() {
|
||||
var disabled = $(this).val() ? false : true;
|
||||
importButton.button( "option", "disabled", disabled );
|
||||
});
|
||||
}
|
||||
|
||||
function showImportDialog() {
|
||||
$( "#import", importDialog ).button( "option", "disabled", true );
|
||||
$( "#value", importDialog ).val("");
|
||||
importDialog.dialog( "open" );
|
||||
}
|
||||
|
||||
function showExportDialog() {
|
||||
exportIfExists(model.actorConditions, $( ".export-actorconditions", exportDialog ));
|
||||
exportIfExists(model.quests, $( ".export-quests", exportDialog ));
|
||||
exportIfExists(model.items, $( ".export-items", exportDialog ));
|
||||
exportIfExists(model.droplists, $( ".export-droplists", exportDialog ));
|
||||
exportIfExists(model.dialogue, $( ".export-dialogue", exportDialog ));
|
||||
exportIfExists(model.monsters, $( ".export-monsters", exportDialog ));
|
||||
exportDialog.dialog( "open" );
|
||||
}
|
||||
|
||||
function prepareImportExportDialogs(buttons) {
|
||||
importDialog = $( "#templates #dialog-import" )
|
||||
.dialog({
|
||||
title: "Import data",
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 840,
|
||||
buttons: buttons
|
||||
});
|
||||
prepareImport(model.actorConditions, $( ".import-actorconditions", importDialog ));
|
||||
prepareImport(model.quests, $( ".import-quests", importDialog ));
|
||||
prepareImport(model.items, $( ".import-items", importDialog ));
|
||||
prepareImport(model.droplists, $( ".import-droplists", importDialog ));
|
||||
prepareImport(model.dialogue, $( ".import-dialogue", importDialog ));
|
||||
prepareImport(model.monsters, $( ".import-monsters", importDialog ));
|
||||
$( "#importsections", importDialog ).accordion({ autoHeight: false });
|
||||
|
||||
exportDialog = $( "#templates #dialog-export" )
|
||||
.dialog({
|
||||
title: "Export data",
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
width: 840,
|
||||
buttons: buttons
|
||||
});
|
||||
|
||||
$( "#exportsections", exportDialog ).accordion({ autoHeight: false });
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 751 B |
159
AndorsTrailEdit/inc/angular.min.js
vendored
Normal file
159
AndorsTrailEdit/inc/angular.min.js
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
AngularJS v1.0.3
|
||||
(c) 2010-2012 Google, Inc. http://angularjs.org
|
||||
License: MIT
|
||||
*/
|
||||
(function(U,ca,p){'use strict';function m(b,a,c){var d;if(b)if(N(b))for(d in b)d!="prototype"&&d!="length"&&d!="name"&&b.hasOwnProperty(d)&&a.call(c,b[d],d);else if(b.forEach&&b.forEach!==m)b.forEach(a,c);else if(L(b)&&wa(b.length))for(d=0;d<b.length;d++)a.call(c,b[d],d);else for(d in b)b.hasOwnProperty(d)&&a.call(c,b[d],d);return b}function lb(b){var a=[],c;for(c in b)b.hasOwnProperty(c)&&a.push(c);return a.sort()}function ec(b,a,c){for(var d=lb(b),e=0;e<d.length;e++)a.call(c,b[d[e]],d[e]);return d}
|
||||
function mb(b){return function(a,c){b(c,a)}}function xa(){for(var b=Z.length,a;b;){b--;a=Z[b].charCodeAt(0);if(a==57)return Z[b]="A",Z.join("");if(a==90)Z[b]="0";else return Z[b]=String.fromCharCode(a+1),Z.join("")}Z.unshift("0");return Z.join("")}function x(b){m(arguments,function(a){a!==b&&m(a,function(a,d){b[d]=a})});return b}function G(b){return parseInt(b,10)}function ya(b,a){return x(new (x(function(){},{prototype:b})),a)}function D(){}function ma(b){return b}function I(b){return function(){return b}}
|
||||
function t(b){return typeof b=="undefined"}function v(b){return typeof b!="undefined"}function L(b){return b!=null&&typeof b=="object"}function F(b){return typeof b=="string"}function wa(b){return typeof b=="number"}function na(b){return Sa.apply(b)=="[object Date]"}function J(b){return Sa.apply(b)=="[object Array]"}function N(b){return typeof b=="function"}function oa(b){return b&&b.document&&b.location&&b.alert&&b.setInterval}function R(b){return F(b)?b.replace(/^\s*/,"").replace(/\s*$/,""):b}function fc(b){return b&&
|
||||
(b.nodeName||b.bind&&b.find)}function Ta(b,a,c){var d=[];m(b,function(b,g,i){d.push(a.call(c,b,g,i))});return d}function gc(b,a){var c=0,d;if(J(b)||F(b))return b.length;else if(L(b))for(d in b)(!a||b.hasOwnProperty(d))&&c++;return c}function za(b,a){if(b.indexOf)return b.indexOf(a);for(var c=0;c<b.length;c++)if(a===b[c])return c;return-1}function Ua(b,a){var c=za(b,a);c>=0&&b.splice(c,1);return a}function V(b,a){if(oa(b)||b&&b.$evalAsync&&b.$watch)throw B("Can't copy Window or Scope");if(a){if(b===
|
||||
a)throw B("Can't copy equivalent objects or arrays");if(J(b)){for(;a.length;)a.pop();for(var c=0;c<b.length;c++)a.push(V(b[c]))}else for(c in m(a,function(b,c){delete a[c]}),b)a[c]=V(b[c])}else(a=b)&&(J(b)?a=V(b,[]):na(b)?a=new Date(b.getTime()):L(b)&&(a=V(b,{})));return a}function hc(b,a){var a=a||{},c;for(c in b)b.hasOwnProperty(c)&&c.substr(0,2)!=="$$"&&(a[c]=b[c]);return a}function ha(b,a){if(b===a)return!0;if(b===null||a===null)return!1;if(b!==b&&a!==a)return!0;var c=typeof b,d;if(c==typeof a&&
|
||||
c=="object")if(J(b)){if((c=b.length)==a.length){for(d=0;d<c;d++)if(!ha(b[d],a[d]))return!1;return!0}}else if(na(b))return na(a)&&b.getTime()==a.getTime();else{if(b&&b.$evalAsync&&b.$watch||a&&a.$evalAsync&&a.$watch||oa(b)||oa(a))return!1;c={};for(d in b){if(d.charAt(0)!=="$"&&!N(b[d])&&!ha(b[d],a[d]))return!1;c[d]=!0}for(d in a)if(!c[d]&&d.charAt(0)!=="$"&&!N(a[d]))return!1;return!0}return!1}function Va(b,a){var c=arguments.length>2?ia.call(arguments,2):[];return N(a)&&!(a instanceof RegExp)?c.length?
|
||||
function(){return arguments.length?a.apply(b,c.concat(ia.call(arguments,0))):a.apply(b,c)}:function(){return arguments.length?a.apply(b,arguments):a.call(b)}:a}function ic(b,a){var c=a;/^\$+/.test(b)?c=p:oa(a)?c="$WINDOW":a&&ca===a?c="$DOCUMENT":a&&a.$evalAsync&&a.$watch&&(c="$SCOPE");return c}function da(b,a){return JSON.stringify(b,ic,a?" ":null)}function nb(b){return F(b)?JSON.parse(b):b}function Wa(b){b&&b.length!==0?(b=E(""+b),b=!(b=="f"||b=="0"||b=="false"||b=="no"||b=="n"||b=="[]")):b=!1;
|
||||
return b}function pa(b){b=u(b).clone();try{b.html("")}catch(a){}return u("<div>").append(b).html().match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+E(b)})}function Xa(b){var a={},c,d;m((b||"").split("&"),function(b){b&&(c=b.split("="),d=decodeURIComponent(c[0]),a[d]=v(c[1])?decodeURIComponent(c[1]):!0)});return a}function ob(b){var a=[];m(b,function(b,d){a.push(Ya(d,!0)+(b===!0?"":"="+Ya(b,!0)))});return a.length?a.join("&"):""}function Za(b){return Ya(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,
|
||||
"=").replace(/%2B/gi,"+")}function Ya(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(a?null:/%20/g,"+")}function jc(b,a){function c(a){a&&d.push(a)}var d=[b],e,g,i=["ng:app","ng-app","x-ng-app","data-ng-app"],f=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;m(i,function(a){i[a]=!0;c(ca.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(m(b.querySelectorAll("."+a),c),m(b.querySelectorAll("."+a+"\\:"),c),m(b.querySelectorAll("["+
|
||||
a+"]"),c))});m(d,function(a){if(!e){var b=f.exec(" "+a.className+" ");b?(e=a,g=(b[2]||"").replace(/\s+/g,",")):m(a.attributes,function(b){if(!e&&i[b.name])e=a,g=b.value})}});e&&a(e,g?[g]:[])}function pb(b,a){b=u(b);a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");var c=qb(a);c.invoke(["$rootScope","$rootElement","$compile","$injector",function(a,b,c,i){a.$apply(function(){b.data("$injector",i);c(b)(a)})}]);return c}function $a(b,a){a=a||"_";return b.replace(kc,
|
||||
function(b,d){return(d?a:"")+b.toLowerCase()})}function qa(b,a,c){if(!b)throw new B("Argument '"+(a||"?")+"' is "+(c||"required"));return b}function ra(b,a,c){c&&J(b)&&(b=b[b.length-1]);qa(N(b),a,"not a function, got "+(b&&typeof b=="object"?b.constructor.name||"Object":typeof b));return b}function lc(b){function a(a,b,e){return a[b]||(a[b]=e())}return a(a(b,"angular",Object),"module",function(){var b={};return function(d,e,g){e&&b.hasOwnProperty(d)&&(b[d]=null);return a(b,d,function(){function a(c,
|
||||
d,e){return function(){b[e||"push"]([c,d,arguments]);return j}}if(!e)throw B("No module: "+d);var b=[],c=[],k=a("$injector","invoke"),j={_invokeQueue:b,_runBlocks:c,requires:e,name:d,provider:a("$provide","provider"),factory:a("$provide","factory"),service:a("$provide","service"),value:a("$provide","value"),constant:a("$provide","constant","unshift"),filter:a("$filterProvider","register"),controller:a("$controllerProvider","register"),directive:a("$compileProvider","directive"),config:k,run:function(a){c.push(a);
|
||||
return this}};g&&k(g);return j})}})}function rb(b){return b.replace(mc,function(a,b,d,e){return e?d.toUpperCase():d}).replace(nc,"Moz$1")}function ab(b,a){function c(){var e;for(var b=[this],c=a,i,f,h,k,j,l;b.length;){i=b.shift();f=0;for(h=i.length;f<h;f++){k=u(i[f]);c?k.triggerHandler("$destroy"):c=!c;j=0;for(e=(l=k.children()).length,k=e;j<k;j++)b.push(ja(l[j]))}}return d.apply(this,arguments)}var d=ja.fn[b],d=d.$original||d;c.$original=d;ja.fn[b]=c}function Q(b){if(b instanceof Q)return b;if(!(this instanceof
|
||||
Q)){if(F(b)&&b.charAt(0)!="<")throw B("selectors not implemented");return new Q(b)}if(F(b)){var a=ca.createElement("div");a.innerHTML="<div> </div>"+b;a.removeChild(a.firstChild);bb(this,a.childNodes);this.remove()}else bb(this,b)}function cb(b){return b.cloneNode(!0)}function sa(b){sb(b);for(var a=0,b=b.childNodes||[];a<b.length;a++)sa(b[a])}function tb(b,a,c){var d=$(b,"events");$(b,"handle")&&(t(a)?m(d,function(a,c){db(b,c,a);delete d[c]}):t(c)?(db(b,a,d[a]),delete d[a]):Ua(d[a],c))}function sb(b){var a=
|
||||
b[Aa],c=Ba[a];c&&(c.handle&&(c.events.$destroy&&c.handle({},"$destroy"),tb(b)),delete Ba[a],b[Aa]=p)}function $(b,a,c){var d=b[Aa],d=Ba[d||-1];if(v(c))d||(b[Aa]=d=++oc,d=Ba[d]={}),d[a]=c;else return d&&d[a]}function ub(b,a,c){var d=$(b,"data"),e=v(c),g=!e&&v(a),i=g&&!L(a);!d&&!i&&$(b,"data",d={});if(e)d[a]=c;else if(g)if(i)return d&&d[a];else x(d,a);else return d}function Ca(b,a){return(" "+b.className+" ").replace(/[\n\t]/g," ").indexOf(" "+a+" ")>-1}function vb(b,a){a&&m(a.split(" "),function(a){b.className=
|
||||
R((" "+b.className+" ").replace(/[\n\t]/g," ").replace(" "+R(a)+" "," "))})}function wb(b,a){a&&m(a.split(" "),function(a){if(!Ca(b,a))b.className=R(b.className+" "+R(a))})}function bb(b,a){if(a)for(var a=!a.nodeName&&v(a.length)&&!oa(a)?a:[a],c=0;c<a.length;c++)b.push(a[c])}function xb(b,a){return Da(b,"$"+(a||"ngController")+"Controller")}function Da(b,a,c){b=u(b);for(b[0].nodeType==9&&(b=b.find("html"));b.length;){if(c=b.data(a))return c;b=b.parent()}}function yb(b,a){var c=Ea[a.toLowerCase()];
|
||||
return c&&zb[b.nodeName]&&c}function pc(b,a){var c=function(c,e){if(!c.preventDefault)c.preventDefault=function(){c.returnValue=!1};if(!c.stopPropagation)c.stopPropagation=function(){c.cancelBubble=!0};if(!c.target)c.target=c.srcElement||ca;if(t(c.defaultPrevented)){var g=c.preventDefault;c.preventDefault=function(){c.defaultPrevented=!0;g.call(c)};c.defaultPrevented=!1}c.isDefaultPrevented=function(){return c.defaultPrevented};m(a[e||c.type],function(a){a.call(b,c)});aa<=8?(c.preventDefault=null,
|
||||
c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function ga(b){var a=typeof b,c;if(a=="object"&&b!==null)if(typeof(c=b.$$hashKey)=="function")c=b.$$hashKey();else{if(c===p)c=b.$$hashKey=xa()}else c=b;return a+":"+c}function Fa(b){m(b,this.put,this)}function eb(){}function Ab(b){var a,c;if(typeof b=="function"){if(!(a=b.$inject))a=[],c=b.toString().replace(qc,""),c=c.match(rc),m(c[1].split(sc),function(b){b.replace(tc,
|
||||
function(b,c,d){a.push(d)})}),b.$inject=a}else J(b)?(c=b.length-1,ra(b[c],"fn"),a=b.slice(0,c)):ra(b,"fn",!0);return a}function qb(b){function a(a){return function(b,c){if(L(b))m(b,mb(a));else return a(b,c)}}function c(a,b){N(b)&&(b=l.instantiate(b));if(!b.$get)throw B("Provider "+a+" must define $get factory method.");return j[a+f]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[];m(a,function(a){if(!k.get(a))if(k.put(a,!0),F(a)){var c=ta(a);b=b.concat(e(c.requires)).concat(c._runBlocks);
|
||||
try{for(var d=c._invokeQueue,c=0,f=d.length;c<f;c++){var h=d[c],g=h[0]=="$injector"?l:l.get(h[0]);g[h[1]].apply(g,h[2])}}catch(n){throw n.message&&(n.message+=" from "+a),n;}}else if(N(a))try{b.push(l.invoke(a))}catch(i){throw i.message&&(i.message+=" from "+a),i;}else if(J(a))try{b.push(l.invoke(a))}catch(j){throw j.message&&(j.message+=" from "+String(a[a.length-1])),j;}else ra(a,"module")});return b}function g(a,b){function c(d){if(typeof d!=="string")throw B("Service name expected");if(a.hasOwnProperty(d)){if(a[d]===
|
||||
i)throw B("Circular dependency: "+h.join(" <- "));return a[d]}else try{return h.unshift(d),a[d]=i,a[d]=b(d)}finally{h.shift()}}function d(a,b,e){var f=[],k=Ab(a),g,n,i;n=0;for(g=k.length;n<g;n++)i=k[n],f.push(e&&e.hasOwnProperty(i)?e[i]:c(i,h));a.$inject||(a=a[g]);switch(b?-1:f.length){case 0:return a();case 1:return a(f[0]);case 2:return a(f[0],f[1]);case 3:return a(f[0],f[1],f[2]);case 4:return a(f[0],f[1],f[2],f[3]);case 5:return a(f[0],f[1],f[2],f[3],f[4]);case 6:return a(f[0],f[1],f[2],f[3],
|
||||
f[4],f[5]);case 7:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6]);case 8:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7]);case 9:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8]);case 10:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8],f[9]);default:return a.apply(b,f)}}return{invoke:d,instantiate:function(a,b){var c=function(){},e;c.prototype=(J(a)?a[a.length-1]:a).prototype;c=new c;e=d(a,c,b);return L(e)?e:c},get:c,annotate:Ab}}var i={},f="Provider",h=[],k=new Fa,j={$provide:{provider:a(c),
|
||||
factory:a(d),service:a(function(a,b){return d(a,["$injector",function(a){return a.instantiate(b)}])}),value:a(function(a,b){return d(a,I(b))}),constant:a(function(a,b){j[a]=b;o[a]=b}),decorator:function(a,b){var c=l.get(a+f),d=c.$get;c.$get=function(){var a=r.invoke(d,c);return r.invoke(b,null,{$delegate:a})}}}},l=g(j,function(){throw B("Unknown provider: "+h.join(" <- "));}),o={},r=o.$injector=g(o,function(a){a=l.get(a+f);return r.invoke(a.$get,a)});m(e(b),function(a){r.invoke(a||D)});return r}function uc(){var b=
|
||||
!0;this.disableAutoScrolling=function(){b=!1};this.$get=["$window","$location","$rootScope",function(a,c,d){function e(a){var b=null;m(a,function(a){!b&&E(a.nodeName)==="a"&&(b=a)});return b}function g(){var b=c.hash(),d;b?(d=i.getElementById(b))?d.scrollIntoView():(d=e(i.getElementsByName(b)))?d.scrollIntoView():b==="top"&&a.scrollTo(0,0):a.scrollTo(0,0)}var i=a.document;b&&d.$watch(function(){return c.hash()},function(){d.$evalAsync(g)});return g}]}function vc(b,a,c,d){function e(a){try{a.apply(null,
|
||||
ia.call(arguments,1))}finally{if(n--,n===0)for(;w.length;)try{w.pop()()}catch(b){c.error(b)}}}function g(a,b){(function ea(){m(q,function(a){a()});s=b(ea,a)})()}function i(){O!=f.url()&&(O=f.url(),m(A,function(a){a(f.url())}))}var f=this,h=a[0],k=b.location,j=b.history,l=b.setTimeout,o=b.clearTimeout,r={};f.isMock=!1;var n=0,w=[];f.$$completeOutstandingRequest=e;f.$$incOutstandingRequestCount=function(){n++};f.notifyWhenNoOutstandingRequests=function(a){m(q,function(a){a()});n===0?a():w.push(a)};
|
||||
var q=[],s;f.addPollFn=function(a){t(s)&&g(100,l);q.push(a);return a};var O=k.href,C=a.find("base");f.url=function(a,b){if(a){if(O!=a)return O=a,d.history?b?j.replaceState(null,"",a):(j.pushState(null,"",a),C.attr("href",C.attr("href"))):b?k.replace(a):k.href=a,f}else return k.href.replace(/%27/g,"'")};var A=[],K=!1;f.onUrlChange=function(a){K||(d.history&&u(b).bind("popstate",i),d.hashchange?u(b).bind("hashchange",i):f.addPollFn(i),K=!0);A.push(a);return a};f.baseHref=function(){var a=C.attr("href");
|
||||
return a?a.replace(/^https?\:\/\/[^\/]*/,""):a};var W={},y="",M=f.baseHref();f.cookies=function(a,b){var d,e,f,k;if(a)if(b===p)h.cookie=escape(a)+"=;path="+M+";expires=Thu, 01 Jan 1970 00:00:00 GMT";else{if(F(b))d=(h.cookie=escape(a)+"="+escape(b)+";path="+M).length+1,d>4096&&c.warn("Cookie '"+a+"' possibly not set or overflowed because it was too large ("+d+" > 4096 bytes)!"),W.length>20&&c.warn("Cookie '"+a+"' possibly not set or overflowed because too many cookies were already set ("+W.length+
|
||||
" > 20 )")}else{if(h.cookie!==y){y=h.cookie;d=y.split("; ");W={};for(f=0;f<d.length;f++)e=d[f],k=e.indexOf("="),k>0&&(W[unescape(e.substring(0,k))]=unescape(e.substring(k+1)))}return W}};f.defer=function(a,b){var c;n++;c=l(function(){delete r[c];e(a)},b||0);r[c]=!0;return c};f.defer.cancel=function(a){return r[a]?(delete r[a],o(a),e(D),!0):!1}}function wc(){this.$get=["$window","$log","$sniffer","$document",function(b,a,c,d){return new vc(b,d,a,c)}]}function xc(){this.$get=function(){function b(b,
|
||||
d){function e(a){if(a!=l){if(o){if(o==a)o=a.n}else o=a;g(a.n,a.p);g(a,l);l=a;l.n=null}}function g(a,b){if(a!=b){if(a)a.p=b;if(b)b.n=a}}if(b in a)throw B("cacheId "+b+" taken");var i=0,f=x({},d,{id:b}),h={},k=d&&d.capacity||Number.MAX_VALUE,j={},l=null,o=null;return a[b]={put:function(a,b){var c=j[a]||(j[a]={key:a});e(c);t(b)||(a in h||i++,h[a]=b,i>k&&this.remove(o.key))},get:function(a){var b=j[a];if(b)return e(b),h[a]},remove:function(a){var b=j[a];if(b){if(b==l)l=b.p;if(b==o)o=b.n;g(b.n,b.p);delete j[a];
|
||||
delete h[a];i--}},removeAll:function(){h={};i=0;j={};l=o=null},destroy:function(){j=f=h=null;delete a[b]},info:function(){return x({},f,{size:i})}}}var a={};b.info=function(){var b={};m(a,function(a,e){b[e]=a.info()});return b};b.get=function(b){return a[b]};return b}}function yc(){this.$get=["$cacheFactory",function(b){return b("templates")}]}function Bb(b){var a={},c="Directive",d=/^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,e=/(([\d\w\-_]+)(?:\:([^;]+))?;?)/,g="Template must have exactly one root element. was: ";
|
||||
this.directive=function f(d,e){F(d)?(qa(e,"directive"),a.hasOwnProperty(d)||(a[d]=[],b.factory(d+c,["$injector","$exceptionHandler",function(b,c){var e=[];m(a[d],function(a){try{var f=b.invoke(a);if(N(f))f={compile:I(f)};else if(!f.compile&&f.link)f.compile=I(f.link);f.priority=f.priority||0;f.name=f.name||d;f.require=f.require||f.controller&&f.name;f.restrict=f.restrict||"A";e.push(f)}catch(k){c(k)}});return e}])),a[d].push(e)):m(d,mb(f));return this};this.$get=["$injector","$interpolate","$exceptionHandler",
|
||||
"$http","$templateCache","$parse","$controller","$rootScope",function(b,h,k,j,l,o,r,n){function w(a,b,c){a instanceof u||(a=u(a));m(a,function(b,c){b.nodeType==3&&(a[c]=u(b).wrap("<span></span>").parent()[0])});var d=s(a,b,a,c);return function(b,c){qa(b,"scope");var e=c?ua.clone.call(a):a;e.data("$scope",b);q(e,"ng-scope");c&&c(e,b);d&&d(b,e,e);return e}}function q(a,b){try{a.addClass(b)}catch(c){}}function s(a,b,c,d){function e(a,c,d,k){for(var g,h,j,n,o,l=0,r=0,q=f.length;l<q;r++)j=c[r],g=f[l++],
|
||||
h=f[l++],g?(g.scope?(n=a.$new(L(g.scope)),u(j).data("$scope",n)):n=a,(o=g.transclude)||!k&&b?g(h,n,j,d,function(b){return function(c){var d=a.$new();return b(d,c).bind("$destroy",Va(d,d.$destroy))}}(o||b)):g(h,n,j,p,k)):h&&h(a,j.childNodes,p,k)}for(var f=[],k,g,h,j=0;j<a.length;j++)g=new ea,k=O(a[j],[],g,d),g=(k=k.length?C(k,a[j],g,b,c):null)&&k.terminal||!a[j].childNodes.length?null:s(a[j].childNodes,k?k.transclude:b),f.push(k),f.push(g),h=h||k||g;return h?e:null}function O(a,b,c,f){var k=c.$attr,
|
||||
g;switch(a.nodeType){case 1:A(b,fa(Cb(a).toLowerCase()),"E",f);var h,j,n;g=a.attributes;for(var o=0,l=g&&g.length;o<l;o++)if(h=g[o],h.specified)j=h.name,n=fa(j.toLowerCase()),k[n]=j,c[n]=h=R(aa&&j=="href"?decodeURIComponent(a.getAttribute(j,2)):h.value),yb(a,n)&&(c[n]=!0),X(a,b,h,n),A(b,n,"A",f);a=a.className;if(F(a)&&a!=="")for(;g=e.exec(a);)n=fa(g[2]),A(b,n,"C",f)&&(c[n]=R(g[3])),a=a.substr(g.index+g[0].length);break;case 3:H(b,a.nodeValue);break;case 8:try{if(g=d.exec(a.nodeValue))n=fa(g[1]),A(b,
|
||||
n,"M",f)&&(c[n]=R(g[2]))}catch(r){}}b.sort(y);return b}function C(a,b,c,d,e){function f(a,b){if(a)a.require=z.require,l.push(a);if(b)b.require=z.require,ba.push(b)}function h(a,b){var c,d="data",e=!1;if(F(a)){for(;(c=a.charAt(0))=="^"||c=="?";)a=a.substr(1),c=="^"&&(d="inheritedData"),e=e||c=="?";c=b[d]("$"+a+"Controller");if(!c&&!e)throw B("No controller: "+a);}else J(a)&&(c=[],m(a,function(a){c.push(h(a,b))}));return c}function j(a,d,e,f,g){var n,q,w,K,s;n=b===e?c:hc(c,new ea(u(e),c.$attr));q=n.$$element;
|
||||
if(C){var zc=/^\s*([@=&])\s*(\w*)\s*$/,O=d.$parent||d;m(C.scope,function(a,b){var c=a.match(zc)||[],e=c[2]||b,f,g,k;switch(c[1]){case "@":n.$observe(e,function(a){d[b]=a});n.$$observers[e].$$scope=O;break;case "=":g=o(n[e]);k=g.assign||function(){f=d[b]=g(O);throw B(Db+n[e]+" (directive: "+C.name+")");};f=d[b]=g(O);d.$watch(function(){var a=g(O);a!==d[b]&&(a!==f?f=d[b]=a:k(O,a=f=d[b]));return a});break;case "&":g=o(n[e]);d[b]=function(a){return g(O,a)};break;default:throw B("Invalid isolate scope definition for directive "+
|
||||
C.name+": "+a);}})}t&&m(t,function(a){var b={$scope:d,$element:q,$attrs:n,$transclude:g};s=a.controller;s=="@"&&(s=n[a.name]);q.data("$"+a.name+"Controller",r(s,b))});f=0;for(w=l.length;f<w;f++)try{K=l[f],K(d,q,n,K.require&&h(K.require,q))}catch(y){k(y,pa(q))}a&&a(d,e.childNodes,p,g);f=0;for(w=ba.length;f<w;f++)try{K=ba[f],K(d,q,n,K.require&&h(K.require,q))}catch(Ha){k(Ha,pa(q))}}for(var n=-Number.MAX_VALUE,l=[],ba=[],s=null,C=null,A=null,y=c.$$element=u(b),z,H,X,D,v=d,t,x,Y,E=0,G=a.length;E<G;E++){z=
|
||||
a[E];X=p;if(n>z.priority)break;if(Y=z.scope)M("isolated scope",C,z,y),L(Y)&&(q(y,"ng-isolate-scope"),C=z),q(y,"ng-scope"),s=s||z;H=z.name;if(Y=z.controller)t=t||{},M("'"+H+"' controller",t[H],z,y),t[H]=z;if(Y=z.transclude)M("transclusion",D,z,y),D=z,n=z.priority,Y=="element"?(X=u(b),y=c.$$element=u("<\!-- "+H+": "+c[H]+" --\>"),b=y[0],Ga(e,u(X[0]),b),v=w(X,d,n)):(X=u(cb(b)).contents(),y.html(""),v=w(X,d));if(Y=z.template)if(M("template",A,z,y),A=z,Y=Ha(Y),z.replace){X=u("<div>"+R(Y)+"</div>").contents();
|
||||
b=X[0];if(X.length!=1||b.nodeType!==1)throw new B(g+Y);Ga(e,y,b);H={$attr:{}};a=a.concat(O(b,a.splice(E+1,a.length-(E+1)),H));K(c,H);G=a.length}else y.html(Y);if(z.templateUrl)M("template",A,z,y),A=z,j=W(a.splice(E,a.length-E),j,y,c,e,z.replace,v),G=a.length;else if(z.compile)try{x=z.compile(y,c,v),N(x)?f(null,x):x&&f(x.pre,x.post)}catch(I){k(I,pa(y))}if(z.terminal)j.terminal=!0,n=Math.max(n,z.priority)}j.scope=s&&s.scope;j.transclude=D&&v;return j}function A(d,e,g,h){var j=!1;if(a.hasOwnProperty(e))for(var n,
|
||||
e=b.get(e+c),o=0,l=e.length;o<l;o++)try{if(n=e[o],(h===p||h>n.priority)&&n.restrict.indexOf(g)!=-1)d.push(n),j=!0}catch(r){k(r)}return j}function K(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;m(a,function(d,e){e.charAt(0)!="$"&&(b[e]&&(d+=(e==="style"?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});m(b,function(b,f){f=="class"?(q(e,b),a["class"]=(a["class"]?a["class"]+" ":"")+b):f=="style"?e.attr("style",e.attr("style")+";"+b):f.charAt(0)!="$"&&!a.hasOwnProperty(f)&&(a[f]=b,d[f]=c[f])})}function W(a,b,c,d,e,
|
||||
f,k){var h=[],n,o,r=c[0],q=a.shift(),w=x({},q,{controller:null,templateUrl:null,transclude:null,scope:null});c.html("");j.get(q.templateUrl,{cache:l}).success(function(j){var l,q,j=Ha(j);if(f){q=u("<div>"+R(j)+"</div>").contents();l=q[0];if(q.length!=1||l.nodeType!==1)throw new B(g+j);j={$attr:{}};Ga(e,c,l);O(l,a,j);K(d,j)}else l=r,c.html(j);a.unshift(w);n=C(a,c,d,k);for(o=s(c.contents(),k);h.length;){var ba=h.pop(),j=h.pop();q=h.pop();var y=h.pop(),m=l;q!==r&&(m=cb(l),Ga(j,u(q),m));n(function(){b(o,
|
||||
y,m,e,ba)},y,m,e,ba)}h=null}).error(function(a,b,c,d){throw B("Failed to load template: "+d.url);});return function(a,c,d,e,f){h?(h.push(c),h.push(d),h.push(e),h.push(f)):n(function(){b(o,c,d,e,f)},c,d,e,f)}}function y(a,b){return b.priority-a.priority}function M(a,b,c,d){if(b)throw B("Multiple directives ["+b.name+", "+c.name+"] asking for "+a+" on: "+pa(d));}function H(a,b){var c=h(b,!0);c&&a.push({priority:0,compile:I(function(a,b){var d=b.parent(),e=d.data("$binding")||[];e.push(c);q(d.data("$binding",
|
||||
e),"ng-binding");a.$watch(c,function(a){b[0].nodeValue=a})})})}function X(a,b,c,d){var e=h(c,!0);e&&b.push({priority:100,compile:I(function(a,b,c){b=c.$$observers||(c.$$observers={});d==="class"&&(e=h(c[d],!0));c[d]=p;(b[d]||(b[d]=[])).$$inter=!0;(c.$$observers&&c.$$observers[d].$$scope||a).$watch(e,function(a){c.$set(d,a)})})})}function Ga(a,b,c){var d=b[0],e=d.parentNode,f,g;if(a){f=0;for(g=a.length;f<g;f++)if(a[f]==d){a[f]=c;break}}e&&e.replaceChild(c,d);c[u.expando]=d[u.expando];b[0]=c}var ea=
|
||||
function(a,b){this.$$element=a;this.$attr=b||{}};ea.prototype={$normalize:fa,$set:function(a,b,c,d){var e=yb(this.$$element[0],a),f=this.$$observers;e&&(this.$$element.prop(a,b),d=e);this[a]=b;d?this.$attr[a]=d:(d=this.$attr[a])||(this.$attr[a]=d=$a(a,"-"));c!==!1&&(b===null||b===p?this.$$element.removeAttr(d):this.$$element.attr(d,b));f&&m(f[a],function(a){try{a(b)}catch(c){k(c)}})},$observe:function(a,b){var c=this,d=c.$$observers||(c.$$observers={}),e=d[a]||(d[a]=[]);e.push(b);n.$evalAsync(function(){e.$$inter||
|
||||
b(c[a])});return b}};var D=h.startSymbol(),ba=h.endSymbol(),Ha=D=="{{"||ba=="}}"?ma:function(a){return a.replace(/\{\{/g,D).replace(/}}/g,ba)};return w}]}function fa(b){return rb(b.replace(Ac,""))}function Bc(){var b={};this.register=function(a,c){L(a)?x(b,a):b[a]=c};this.$get=["$injector","$window",function(a,c){return function(d,e){if(F(d)){var g=d,d=b.hasOwnProperty(g)?b[g]:fb(e.$scope,g,!0)||fb(c,g,!0);ra(d,g,!0)}return a.instantiate(d,e)}}]}function Cc(){this.$get=["$window",function(b){return u(b.document)}]}
|
||||
function Dc(){this.$get=["$log",function(b){return function(a,c){b.error.apply(b,arguments)}}]}function Ec(){var b="{{",a="}}";this.startSymbol=function(a){return a?(b=a,this):b};this.endSymbol=function(b){return b?(a=b,this):a};this.$get=["$parse",function(c){function d(d,f){for(var h,k,j=0,l=[],o=d.length,r=!1,n=[];j<o;)(h=d.indexOf(b,j))!=-1&&(k=d.indexOf(a,h+e))!=-1?(j!=h&&l.push(d.substring(j,h)),l.push(j=c(r=d.substring(h+e,k))),j.exp=r,j=k+g,r=!0):(j!=o&&l.push(d.substring(j)),j=o);if(!(o=
|
||||
l.length))l.push(""),o=1;if(!f||r)return n.length=o,j=function(a){for(var b=0,c=o,d;b<c;b++){if(typeof(d=l[b])=="function")d=d(a),d==null||d==p?d="":typeof d!="string"&&(d=da(d));n[b]=d}return n.join("")},j.exp=d,j.parts=l,j}var e=b.length,g=a.length;d.startSymbol=function(){return b};d.endSymbol=function(){return a};return d}]}function Eb(b){for(var b=b.split("/"),a=b.length;a--;)b[a]=Za(b[a]);return b.join("/")}function va(b,a){var c=Fb.exec(b),c={protocol:c[1],host:c[3],port:G(c[5])||Gb[c[1]]||
|
||||
null,path:c[6]||"/",search:c[8],hash:c[10]};if(a)a.$$protocol=c.protocol,a.$$host=c.host,a.$$port=c.port;return c}function ka(b,a,c){return b+"://"+a+(c==Gb[b]?"":":"+c)}function Fc(b,a,c){var d=va(b);return decodeURIComponent(d.path)!=a||t(d.hash)||d.hash.indexOf(c)!==0?b:ka(d.protocol,d.host,d.port)+a.substr(0,a.lastIndexOf("/"))+d.hash.substr(c.length)}function Gc(b,a,c){var d=va(b);if(decodeURIComponent(d.path)==a)return b;else{var e=d.search&&"?"+d.search||"",g=d.hash&&"#"+d.hash||"",i=a.substr(0,
|
||||
a.lastIndexOf("/")),f=d.path.substr(i.length);if(d.path.indexOf(i)!==0)throw B('Invalid url "'+b+'", missing path prefix "'+i+'" !');return ka(d.protocol,d.host,d.port)+a+"#"+c+f+e+g}}function gb(b,a,c){a=a||"";this.$$parse=function(b){var c=va(b,this);if(c.path.indexOf(a)!==0)throw B('Invalid url "'+b+'", missing path prefix "'+a+'" !');this.$$path=decodeURIComponent(c.path.substr(a.length));this.$$search=Xa(c.search);this.$$hash=c.hash&&decodeURIComponent(c.hash)||"";this.$$compose()};this.$$compose=
|
||||
function(){var b=ob(this.$$search),c=this.$$hash?"#"+Za(this.$$hash):"";this.$$url=Eb(this.$$path)+(b?"?"+b:"")+c;this.$$absUrl=ka(this.$$protocol,this.$$host,this.$$port)+a+this.$$url};this.$$rewriteAppUrl=function(a){if(a.indexOf(c)==0)return a};this.$$parse(b)}function Ia(b,a,c){var d;this.$$parse=function(b){var c=va(b,this);if(c.hash&&c.hash.indexOf(a)!==0)throw B('Invalid url "'+b+'", missing hash prefix "'+a+'" !');d=c.path+(c.search?"?"+c.search:"");c=Hc.exec((c.hash||"").substr(a.length));
|
||||
this.$$path=c[1]?(c[1].charAt(0)=="/"?"":"/")+decodeURIComponent(c[1]):"";this.$$search=Xa(c[3]);this.$$hash=c[5]&&decodeURIComponent(c[5])||"";this.$$compose()};this.$$compose=function(){var b=ob(this.$$search),c=this.$$hash?"#"+Za(this.$$hash):"";this.$$url=Eb(this.$$path)+(b?"?"+b:"")+c;this.$$absUrl=ka(this.$$protocol,this.$$host,this.$$port)+d+(this.$$url?"#"+a+this.$$url:"")};this.$$rewriteAppUrl=function(a){if(a.indexOf(c)==0)return a};this.$$parse(b)}function Hb(b,a,c,d){Ia.apply(this,arguments);
|
||||
this.$$rewriteAppUrl=function(b){if(b.indexOf(c)==0)return c+d+"#"+a+b.substr(c.length)}}function Ja(b){return function(){return this[b]}}function Ib(b,a){return function(c){if(t(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Ic(){var b="",a=!1;this.hashPrefix=function(a){return v(a)?(b=a,this):b};this.html5Mode=function(b){return v(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,g){function i(a){c.$broadcast("$locationChangeSuccess",
|
||||
f.absUrl(),a)}var f,h,k,j=d.url(),l=va(j);a?(h=d.baseHref()||"/",k=h.substr(0,h.lastIndexOf("/")),l=ka(l.protocol,l.host,l.port)+k+"/",f=e.history?new gb(Fc(j,h,b),k,l):new Hb(Gc(j,h,b),b,l,h.substr(k.length+1))):(l=ka(l.protocol,l.host,l.port)+(l.path||"")+(l.search?"?"+l.search:"")+"#"+b+"/",f=new Ia(j,b,l));g.bind("click",function(a){if(!a.ctrlKey&&!(a.metaKey||a.which==2)){for(var b=u(a.target);E(b[0].nodeName)!=="a";)if(b[0]===g[0]||!(b=b.parent())[0])return;var d=b.prop("href"),e=f.$$rewriteAppUrl(d);
|
||||
d&&!b.attr("target")&&e&&(f.$$parse(e),c.$apply(),a.preventDefault(),U.angular["ff-684208-preventDefault"]=!0)}});f.absUrl()!=j&&d.url(f.absUrl(),!0);d.onUrlChange(function(a){f.absUrl()!=a&&(c.$evalAsync(function(){var b=f.absUrl();f.$$parse(a);i(b)}),c.$$phase||c.$digest())});var o=0;c.$watch(function(){var a=d.url(),b=f.$$replace;if(!o||a!=f.absUrl())o++,c.$evalAsync(function(){c.$broadcast("$locationChangeStart",f.absUrl(),a).defaultPrevented?f.$$parse(a):(d.url(f.absUrl(),b),i(a))});f.$$replace=
|
||||
!1;return o});return f}]}function Jc(){this.$get=["$window",function(b){function a(a){a instanceof B&&(a.stack?a=a.message&&a.stack.indexOf(a.message)===-1?"Error: "+a.message+"\n"+a.stack:a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function c(c){var e=b.console||{},g=e[c]||e.log||D;return g.apply?function(){var b=[];m(arguments,function(c){b.push(a(c))});return g.apply(e,b)}:function(a,b){g(a,b)}}return{log:c("log"),warn:c("warn"),info:c("info"),error:c("error")}}]}function Kc(b,
|
||||
a){function c(a){return a.indexOf(q)!=-1}function d(){return n+1<b.length?b.charAt(n+1):!1}function e(a){return"0"<=a&&a<="9"}function g(a){return a==" "||a=="\r"||a=="\t"||a=="\n"||a=="\u000b"||a=="\u00a0"}function i(a){return"a"<=a&&a<="z"||"A"<=a&&a<="Z"||"_"==a||a=="$"}function f(a){return a=="-"||a=="+"||e(a)}function h(a,c,d){d=d||n;throw B("Lexer Error: "+a+" at column"+(v(c)?"s "+c+"-"+n+" ["+b.substring(c,d)+"]":" "+d)+" in expression ["+b+"].");}function k(){for(var a="",c=n;n<b.length;){var k=
|
||||
E(b.charAt(n));if(k=="."||e(k))a+=k;else{var g=d();if(k=="e"&&f(g))a+=k;else if(f(k)&&g&&e(g)&&a.charAt(a.length-1)=="e")a+=k;else if(f(k)&&(!g||!e(g))&&a.charAt(a.length-1)=="e")h("Invalid exponent");else break}n++}a*=1;o.push({index:c,text:a,json:!0,fn:function(){return a}})}function j(){for(var c="",d=n,f,k,h;n<b.length;){var j=b.charAt(n);if(j=="."||i(j)||e(j))j=="."&&(f=n),c+=j;else break;n++}if(f)for(k=n;k<b.length;){j=b.charAt(k);if(j=="("){h=c.substr(f-d+1);c=c.substr(0,f-d);n=k;break}if(g(j))k++;
|
||||
else break}d={index:d,text:c};if(Ka.hasOwnProperty(c))d.fn=d.json=Ka[c];else{var l=Jb(c,a);d.fn=x(function(a,b){return l(a,b)},{assign:function(a,b){return Kb(a,c,b)}})}o.push(d);h&&(o.push({index:f,text:".",json:!1}),o.push({index:f+1,text:h,json:!1}))}function l(a){var c=n;n++;for(var d="",e=a,f=!1;n<b.length;){var k=b.charAt(n);e+=k;if(f)k=="u"?(k=b.substring(n+1,n+5),k.match(/[\da-f]{4}/i)||h("Invalid unicode escape [\\u"+k+"]"),n+=4,d+=String.fromCharCode(parseInt(k,16))):(f=Lc[k],d+=f?f:k),
|
||||
f=!1;else if(k=="\\")f=!0;else if(k==a){n++;o.push({index:c,text:e,string:d,json:!0,fn:function(){return d}});return}else d+=k;n++}h("Unterminated quote",c)}for(var o=[],r,n=0,w=[],q,s=":";n<b.length;){q=b.charAt(n);if(c("\"'"))l(q);else if(e(q)||c(".")&&e(d()))k();else if(i(q)){if(j(),"{,".indexOf(s)!=-1&&w[0]=="{"&&(r=o[o.length-1]))r.json=r.text.indexOf(".")==-1}else if(c("(){}[].,;:"))o.push({index:n,text:q,json:":[,".indexOf(s)!=-1&&c("{[")||c("}]:,")}),c("{[")&&w.unshift(q),c("}]")&&w.shift(),
|
||||
n++;else if(g(q)){n++;continue}else{var m=q+d(),C=Ka[q],A=Ka[m];A?(o.push({index:n,text:m,fn:A}),n+=2):C?(o.push({index:n,text:q,fn:C,json:"[,:".indexOf(s)!=-1&&c("+-")}),n+=1):h("Unexpected next character ",n,n+1)}s=q}return o}function Mc(b,a,c,d){function e(a,c){throw B("Syntax Error: Token '"+c.text+"' "+a+" at column "+(c.index+1)+" of the expression ["+b+"] starting at ["+b.substring(c.index)+"].");}function g(){if(M.length===0)throw B("Unexpected end of expression: "+b);return M[0]}function i(a,
|
||||
b,c,d){if(M.length>0){var e=M[0],f=e.text;if(f==a||f==b||f==c||f==d||!a&&!b&&!c&&!d)return e}return!1}function f(b,c,d,f){return(b=i(b,c,d,f))?(a&&!b.json&&e("is not valid json",b),M.shift(),b):!1}function h(a){f(a)||e("is unexpected, expecting ["+a+"]",i())}function k(a,b){return function(c,d){return a(c,d,b)}}function j(a,b,c){return function(d,e){return b(d,e,a,c)}}function l(){for(var a=[];;)if(M.length>0&&!i("}",")",";","]")&&a.push(v()),!f(";"))return a.length==1?a[0]:function(b,c){for(var d,
|
||||
e=0;e<a.length;e++){var f=a[e];f&&(d=f(b,c))}return d}}function o(){for(var a=f(),b=c(a.text),d=[];;)if(a=f(":"))d.push(H());else{var e=function(a,c,e){for(var e=[e],f=0;f<d.length;f++)e.push(d[f](a,c));return b.apply(a,e)};return function(){return e}}}function r(){for(var a=n(),b;;)if(b=f("||"))a=j(a,b.fn,n());else return a}function n(){var a=w(),b;if(b=f("&&"))a=j(a,b.fn,n());return a}function w(){var a=q(),b;if(b=f("==","!="))a=j(a,b.fn,w());return a}function q(){var a;a=s();for(var b;b=f("+",
|
||||
"-");)a=j(a,b.fn,s());if(b=f("<",">","<=",">="))a=j(a,b.fn,q());return a}function s(){for(var a=m(),b;b=f("*","/","%");)a=j(a,b.fn,m());return a}function m(){var a;return f("+")?C():(a=f("-"))?j(W,a.fn,m()):(a=f("!"))?k(a.fn,m()):C()}function C(){var a;if(f("("))a=v(),h(")");else if(f("["))a=A();else if(f("{"))a=K();else{var b=f();(a=b.fn)||e("not a primary expression",b)}for(var c;b=f("(","[",".");)b.text==="("?(a=u(a,c),c=null):b.text==="["?(c=a,a=ea(a)):b.text==="."?(c=a,a=t(a)):e("IMPOSSIBLE");
|
||||
return a}function A(){var a=[];if(g().text!="]"){do a.push(H());while(f(","))}h("]");return function(b,c){for(var d=[],e=0;e<a.length;e++)d.push(a[e](b,c));return d}}function K(){var a=[];if(g().text!="}"){do{var b=f(),b=b.string||b.text;h(":");var c=H();a.push({key:b,value:c})}while(f(","))}h("}");return function(b,c){for(var d={},e=0;e<a.length;e++){var f=a[e],k=f.value(b,c);d[f.key]=k}return d}}var W=I(0),y,M=Kc(b,d),H=function(){var a=r(),c,d;return(d=f("="))?(a.assign||e("implies assignment but ["+
|
||||
b.substring(0,d.index)+"] can not be assigned to",d),c=r(),function(b,d){return a.assign(b,c(b,d),d)}):a},u=function(a,b){var c=[];if(g().text!=")"){do c.push(H());while(f(","))}h(")");return function(d,e){for(var f=[],k=b?b(d,e):d,h=0;h<c.length;h++)f.push(c[h](d,e));h=a(d,e)||D;return h.apply?h.apply(k,f):h(f[0],f[1],f[2],f[3],f[4])}},t=function(a){var b=f().text,c=Jb(b,d);return x(function(b,d){return c(a(b,d),d)},{assign:function(c,d,e){return Kb(a(c,e),b,d)}})},ea=function(a){var b=H();h("]");
|
||||
return x(function(c,d){var e=a(c,d),f=b(c,d),k;if(!e)return p;if((e=e[f])&&e.then){k=e;if(!("$$v"in e))k.$$v=p,k.then(function(a){k.$$v=a});e=e.$$v}return e},{assign:function(c,d,e){return a(c,e)[b(c,e)]=d}})},v=function(){for(var a=H(),b;;)if(b=f("|"))a=j(a,b.fn,o());else return a};a?(H=r,u=t=ea=v=function(){e("is not valid json",{text:b,index:0})},y=C()):y=l();M.length!==0&&e("is an unexpected token",M[0]);return y}function Kb(b,a,c){for(var a=a.split("."),d=0;a.length>1;d++){var e=a.shift(),g=
|
||||
b[e];g||(g={},b[e]=g);b=g}return b[a.shift()]=c}function fb(b,a,c){if(!a)return b;for(var a=a.split("."),d,e=b,g=a.length,i=0;i<g;i++)d=a[i],b&&(b=(e=b)[d]);return!c&&N(b)?Va(e,b):b}function Lb(b,a,c,d,e){return function(g,i){var f=i&&i.hasOwnProperty(b)?i:g,h;if(f===null||f===p)return f;if((f=f[b])&&f.then){if(!("$$v"in f))h=f,h.$$v=p,h.then(function(a){h.$$v=a});f=f.$$v}if(!a||f===null||f===p)return f;if((f=f[a])&&f.then){if(!("$$v"in f))h=f,h.$$v=p,h.then(function(a){h.$$v=a});f=f.$$v}if(!c||f===
|
||||
null||f===p)return f;if((f=f[c])&&f.then){if(!("$$v"in f))h=f,h.$$v=p,h.then(function(a){h.$$v=a});f=f.$$v}if(!d||f===null||f===p)return f;if((f=f[d])&&f.then){if(!("$$v"in f))h=f,h.$$v=p,h.then(function(a){h.$$v=a});f=f.$$v}if(!e||f===null||f===p)return f;if((f=f[e])&&f.then){if(!("$$v"in f))h=f,h.$$v=p,h.then(function(a){h.$$v=a});f=f.$$v}return f}}function Jb(b,a){if(hb.hasOwnProperty(b))return hb[b];var c=b.split("."),d=c.length,e;if(a)e=d<6?Lb(c[0],c[1],c[2],c[3],c[4]):function(a,b){var e=0,
|
||||
k;do k=Lb(c[e++],c[e++],c[e++],c[e++],c[e++])(a,b),b=p,a=k;while(e<d);return k};else{var g="var l, fn, p;\n";m(c,function(a,b){g+="if(s === null || s === undefined) return s;\nl=s;\ns="+(b?"s":'((k&&k.hasOwnProperty("'+a+'"))?k:s)')+'["'+a+'"];\nif (s && s.then) {\n if (!("$$v" in s)) {\n p=s;\n p.$$v = undefined;\n p.then(function(v) {p.$$v=v;});\n}\n s=s.$$v\n}\n'});g+="return s;";e=Function("s","k",g);e.toString=function(){return g}}return hb[b]=e}function Nc(){var b={};this.$get=["$filter","$sniffer",
|
||||
function(a,c){return function(d){switch(typeof d){case "string":return b.hasOwnProperty(d)?b[d]:b[d]=Mc(d,!1,a,c.csp);case "function":return d;default:return D}}}]}function Oc(){this.$get=["$rootScope","$exceptionHandler",function(b,a){return Pc(function(a){b.$evalAsync(a)},a)}]}function Pc(b,a){function c(a){return a}function d(a){return i(a)}var e=function(){var f=[],h,k;return k={resolve:function(a){if(f){var c=f;f=p;h=g(a);c.length&&b(function(){for(var a,b=0,d=c.length;b<d;b++)a=c[b],h.then(a[0],
|
||||
a[1])})}},reject:function(a){k.resolve(i(a))},promise:{then:function(b,k){var g=e(),i=function(d){try{g.resolve((b||c)(d))}catch(e){a(e),g.reject(e)}},n=function(b){try{g.resolve((k||d)(b))}catch(c){a(c),g.reject(c)}};f?f.push([i,n]):h.then(i,n);return g.promise}}}},g=function(a){return a&&a.then?a:{then:function(c){var d=e();b(function(){d.resolve(c(a))});return d.promise}}},i=function(a){return{then:function(c,k){var g=e();b(function(){g.resolve((k||d)(a))});return g.promise}}};return{defer:e,reject:i,
|
||||
when:function(f,h,k){var j=e(),l,o=function(b){try{return(h||c)(b)}catch(d){return a(d),i(d)}},r=function(b){try{return(k||d)(b)}catch(c){return a(c),i(c)}};b(function(){g(f).then(function(a){l||(l=!0,j.resolve(g(a).then(o,r)))},function(a){l||(l=!0,j.resolve(r(a)))})});return j.promise},all:function(a){var b=e(),c=a.length,d=[];c?m(a,function(a,e){g(a).then(function(a){e in d||(d[e]=a,--c||b.resolve(d))},function(a){e in d||b.reject(a)})}):b.resolve(d);return b.promise}}}function Qc(){var b={};this.when=
|
||||
function(a,c){b[a]=x({reloadOnSearch:!0},c);if(a){var d=a[a.length-1]=="/"?a.substr(0,a.length-1):a+"/";b[d]={redirectTo:a}}return this};this.otherwise=function(a){this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache",function(a,c,d,e,g,i,f){function h(){var b=k(),h=r.current;if(b&&h&&b.$route===h.$route&&ha(b.pathParams,h.pathParams)&&!b.reloadOnSearch&&!o)h.params=b.params,V(h.params,d),a.$broadcast("$routeUpdate",h);else if(b||
|
||||
h)o=!1,a.$broadcast("$routeChangeStart",b,h),(r.current=b)&&b.redirectTo&&(F(b.redirectTo)?c.path(j(b.redirectTo,b.params)).search(b.params).replace():c.url(b.redirectTo(b.pathParams,c.path(),c.search())).replace()),e.when(b).then(function(){if(b){var a=[],c=[],d;m(b.resolve||{},function(b,d){a.push(d);c.push(F(b)?g.get(b):g.invoke(b))});if(!v(d=b.template))if(v(d=b.templateUrl))d=i.get(d,{cache:f}).then(function(a){return a.data});v(d)&&(a.push("$template"),c.push(d));return e.all(c).then(function(b){var c=
|
||||
{};m(b,function(b,d){c[a[d]]=b});return c})}}).then(function(c){if(b==r.current){if(b)b.locals=c,V(b.params,d);a.$broadcast("$routeChangeSuccess",b,h)}},function(c){b==r.current&&a.$broadcast("$routeChangeError",b,h,c)})}function k(){var a,d;m(b,function(b,e){if(!d&&(a=l(c.path(),e)))d=ya(b,{params:x({},c.search(),a),pathParams:a}),d.$route=b});return d||b[null]&&ya(b[null],{params:{},pathParams:{}})}function j(a,b){var c=[];m((a||"").split(":"),function(a,d){if(d==0)c.push(a);else{var e=a.match(/(\w+)(.*)/),
|
||||
f=e[1];c.push(b[f]);c.push(e[2]||"");delete b[f]}});return c.join("")}var l=function(a,b){var c="^"+b.replace(/([\.\\\(\)\^\$])/g,"\\$1")+"$",d=[],e={};m(b.split(/\W/),function(a){if(a){var b=RegExp(":"+a+"([\\W])");c.match(b)&&(c=c.replace(b,"([^\\/]*)$1"),d.push(a))}});var f=a.match(RegExp(c));f&&m(d,function(a,b){e[a]=f[b+1]});return f?e:null},o=!1,r={routes:b,reload:function(){o=!0;a.$evalAsync(h)}};a.$on("$locationChangeSuccess",h);return r}]}function Rc(){this.$get=I({})}function Sc(){var b=
|
||||
10;this.digestTtl=function(a){arguments.length&&(b=a);return b};this.$get=["$injector","$exceptionHandler","$parse",function(a,c,d){function e(){this.$id=xa();this.$$phase=this.$parent=this.$$watchers=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=null;this["this"]=this.$root=this;this.$$asyncQueue=[];this.$$listeners={}}function g(a){if(h.$$phase)throw B(h.$$phase+" already in progress");h.$$phase=a}function i(a,b){var c=d(a);ra(c,b);return c}function f(){}e.prototype={$new:function(a){if(N(a))throw B("API-CHANGE: Use $controller to instantiate controllers.");
|
||||
a?(a=new e,a.$root=this.$root):(a=function(){},a.prototype=this,a=new a,a.$id=xa());a["this"]=a;a.$$listeners={};a.$parent=this;a.$$asyncQueue=[];a.$$watchers=a.$$nextSibling=a.$$childHead=a.$$childTail=null;a.$$prevSibling=this.$$childTail;this.$$childHead?this.$$childTail=this.$$childTail.$$nextSibling=a:this.$$childHead=this.$$childTail=a;return a},$watch:function(a,b,c){var d=i(a,"watch"),e=this.$$watchers,g={fn:b,last:f,get:d,exp:a,eq:!!c};if(!N(b)){var h=i(b||D,"listener");g.fn=function(a,b,
|
||||
c){h(c)}}if(!e)e=this.$$watchers=[];e.unshift(g);return function(){Ua(e,g)}},$digest:function(){var a,d,e,i,r,n,m,q=b,s,p=[],C,A;g("$digest");do{m=!1;s=this;do{for(r=s.$$asyncQueue;r.length;)try{s.$eval(r.shift())}catch(K){c(K)}if(i=s.$$watchers)for(n=i.length;n--;)try{if(a=i[n],(d=a.get(s))!==(e=a.last)&&!(a.eq?ha(d,e):typeof d=="number"&&typeof e=="number"&&isNaN(d)&&isNaN(e)))m=!0,a.last=a.eq?V(d):d,a.fn(d,e===f?d:e,s),q<5&&(C=4-q,p[C]||(p[C]=[]),A=N(a.exp)?"fn: "+(a.exp.name||a.exp.toString()):
|
||||
a.exp,A+="; newVal: "+da(d)+"; oldVal: "+da(e),p[C].push(A))}catch(W){c(W)}if(!(i=s.$$childHead||s!==this&&s.$$nextSibling))for(;s!==this&&!(i=s.$$nextSibling);)s=s.$parent}while(s=i);if(m&&!q--)throw h.$$phase=null,B(b+" $digest() iterations reached. Aborting!\nWatchers fired in the last 5 iterations: "+da(p));}while(m||r.length);h.$$phase=null},$destroy:function(){if(h!=this){var a=this.$parent;this.$broadcast("$destroy");if(a.$$childHead==this)a.$$childHead=this.$$nextSibling;if(a.$$childTail==
|
||||
this)a.$$childTail=this.$$prevSibling;if(this.$$prevSibling)this.$$prevSibling.$$nextSibling=this.$$nextSibling;if(this.$$nextSibling)this.$$nextSibling.$$prevSibling=this.$$prevSibling;this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=null}},$eval:function(a,b){return d(a)(this,b)},$evalAsync:function(a){this.$$asyncQueue.push(a)},$apply:function(a){try{return g("$apply"),this.$eval(a)}catch(b){c(b)}finally{h.$$phase=null;try{h.$digest()}catch(d){throw c(d),d;}}},
|
||||
$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=c=[]);c.push(b);return function(){c[za(c,b)]=null}},$emit:function(a,b){var d=[],e,f=this,g=!1,h={name:a,targetScope:f,stopPropagation:function(){g=!0},preventDefault:function(){h.defaultPrevented=!0},defaultPrevented:!1},i=[h].concat(ia.call(arguments,1)),m,p;do{e=f.$$listeners[a]||d;h.currentScope=f;m=0;for(p=e.length;m<p;m++)if(e[m])try{if(e[m].apply(null,i),g)return h}catch(C){c(C)}else e.splice(m,1),m--,p--;f=f.$parent}while(f);
|
||||
return h},$broadcast:function(a,b){var d=this,e=this,f={name:a,targetScope:this,preventDefault:function(){f.defaultPrevented=!0},defaultPrevented:!1},g=[f].concat(ia.call(arguments,1)),h,i;do{d=e;f.currentScope=d;e=d.$$listeners[a]||[];h=0;for(i=e.length;h<i;h++)if(e[h])try{e[h].apply(null,g)}catch(m){c(m)}else e.splice(h,1),h--,i--;if(!(e=d.$$childHead||d!==this&&d.$$nextSibling))for(;d!==this&&!(e=d.$$nextSibling);)d=d.$parent}while(d=e);return f}};var h=new e;return h}]}function Tc(){this.$get=
|
||||
["$window",function(b){var a={},c=G((/android (\d+)/.exec(E(b.navigator.userAgent))||[])[1]);return{history:!(!b.history||!b.history.pushState||c<4),hashchange:"onhashchange"in b&&(!b.document.documentMode||b.document.documentMode>7),hasEvent:function(c){if(c=="input"&&aa==9)return!1;if(t(a[c])){var e=b.document.createElement("div");a[c]="on"+c in e}return a[c]},csp:!1}}]}function Uc(){this.$get=I(U)}function Mb(b){var a={},c,d,e;if(!b)return a;m(b.split("\n"),function(b){e=b.indexOf(":");c=E(R(b.substr(0,
|
||||
e)));d=R(b.substr(e+1));c&&(a[c]?a[c]+=", "+d:a[c]=d)});return a}function Nb(b){var a=L(b)?b:p;return function(c){a||(a=Mb(b));return c?a[E(c)]||null:a}}function Ob(b,a,c){if(N(c))return c(b,a);m(c,function(c){b=c(b,a)});return b}function Vc(){var b=/^\s*(\[|\{[^\{])/,a=/[\}\]]\s*$/,c=/^\)\]\}',?\n/,d=this.defaults={transformResponse:[function(d){F(d)&&(d=d.replace(c,""),b.test(d)&&a.test(d)&&(d=nb(d,!0)));return d}],transformRequest:[function(a){return L(a)&&Sa.apply(a)!=="[object File]"?da(a):a}],
|
||||
headers:{common:{Accept:"application/json, text/plain, */*","X-Requested-With":"XMLHttpRequest"},post:{"Content-Type":"application/json;charset=utf-8"},put:{"Content-Type":"application/json;charset=utf-8"}}},e=this.responseInterceptors=[];this.$get=["$httpBackend","$browser","$cacheFactory","$rootScope","$q","$injector",function(a,b,c,h,k,j){function l(a){function c(a){var b=x({},a,{data:Ob(a.data,a.headers,f)});return 200<=a.status&&a.status<300?b:k.reject(b)}a.method=la(a.method);var e=a.transformRequest||
|
||||
d.transformRequest,f=a.transformResponse||d.transformResponse,h=d.headers,h=x({"X-XSRF-TOKEN":b.cookies()["XSRF-TOKEN"]},h.common,h[E(a.method)],a.headers),e=Ob(a.data,Nb(h),e),g;t(a.data)&&delete h["Content-Type"];g=o(a,e,h);g=g.then(c,c);m(w,function(a){g=a(g)});g.success=function(b){g.then(function(c){b(c.data,c.status,c.headers,a)});return g};g.error=function(b){g.then(null,function(c){b(c.data,c.status,c.headers,a)});return g};return g}function o(b,c,d){function e(a,b,c){m&&(200<=a&&a<300?m.put(w,
|
||||
[a,b,Mb(c)]):m.remove(w));f(b,a,c);h.$apply()}function f(a,c,d){c=Math.max(c,0);(200<=c&&c<300?j.resolve:j.reject)({data:a,status:c,headers:Nb(d),config:b})}function i(){var a=za(l.pendingRequests,b);a!==-1&&l.pendingRequests.splice(a,1)}var j=k.defer(),o=j.promise,m,p,w=r(b.url,b.params);l.pendingRequests.push(b);o.then(i,i);b.cache&&b.method=="GET"&&(m=L(b.cache)?b.cache:n);if(m)if(p=m.get(w))if(p.then)return p.then(i,i),p;else J(p)?f(p[1],p[0],V(p[2])):f(p,200,{});else m.put(w,o);p||a(b.method,
|
||||
w,c,e,d,b.timeout,b.withCredentials);return o}function r(a,b){if(!b)return a;var c=[];ec(b,function(a,b){a==null||a==p||(L(a)&&(a=da(a)),c.push(encodeURIComponent(b)+"="+encodeURIComponent(a)))});return a+(a.indexOf("?")==-1?"?":"&")+c.join("&")}var n=c("$http"),w=[];m(e,function(a){w.push(F(a)?j.get(a):j.invoke(a))});l.pendingRequests=[];(function(a){m(arguments,function(a){l[a]=function(b,c){return l(x(c||{},{method:a,url:b}))}})})("get","delete","head","jsonp");(function(a){m(arguments,function(a){l[a]=
|
||||
function(b,c,d){return l(x(d||{},{method:a,url:b,data:c}))}})})("post","put");l.defaults=d;return l}]}function Wc(){this.$get=["$browser","$window","$document",function(b,a,c){return Xc(b,Yc,b.defer,a.angular.callbacks,c[0],a.location.protocol.replace(":",""))}]}function Xc(b,a,c,d,e,g){function i(a,b){var c=e.createElement("script"),d=function(){e.body.removeChild(c);b&&b()};c.type="text/javascript";c.src=a;aa?c.onreadystatechange=function(){/loaded|complete/.test(c.readyState)&&d()}:c.onload=c.onerror=
|
||||
d;e.body.appendChild(c)}return function(e,h,k,j,l,o,r){function n(a,c,d,e){c=(h.match(Fb)||["",g])[1]=="file"?d?200:404:c;a(c==1223?204:c,d,e);b.$$completeOutstandingRequest(D)}b.$$incOutstandingRequestCount();h=h||b.url();if(E(e)=="jsonp"){var p="_"+(d.counter++).toString(36);d[p]=function(a){d[p].data=a};i(h.replace("JSON_CALLBACK","angular.callbacks."+p),function(){d[p].data?n(j,200,d[p].data):n(j,-2);delete d[p]})}else{var q=new a;q.open(e,h,!0);m(l,function(a,b){a&&q.setRequestHeader(b,a)});
|
||||
var s;q.onreadystatechange=function(){q.readyState==4&&n(j,s||q.status,q.responseText,q.getAllResponseHeaders())};if(r)q.withCredentials=!0;q.send(k||"");o>0&&c(function(){s=-1;q.abort()},o)}}}function Zc(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},
|
||||
DATETIME_FORMATS:{MONTH:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),SHORTMONTH:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),DAY:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),SHORTDAY:"Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(","),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",
|
||||
shortTime:"h:mm a"},pluralCat:function(b){return b===1?"one":"other"}}}}function $c(){this.$get=["$rootScope","$browser","$q","$exceptionHandler",function(b,a,c,d){function e(e,f,h){var k=c.defer(),j=k.promise,l=v(h)&&!h,f=a.defer(function(){try{k.resolve(e())}catch(a){k.reject(a),d(a)}l||b.$apply()},f),h=function(){delete g[j.$$timeoutId]};j.$$timeoutId=f;g[f]=k;j.then(h,h);return j}var g={};e.cancel=function(b){return b&&b.$$timeoutId in g?(g[b.$$timeoutId].reject("canceled"),a.defer.cancel(b.$$timeoutId)):
|
||||
!1};return e}]}function Pb(b){function a(a,e){return b.factory(a+c,e)}var c="Filter";this.register=a;this.$get=["$injector",function(a){return function(b){return a.get(b+c)}}];a("currency",Qb);a("date",Rb);a("filter",ad);a("json",bd);a("limitTo",cd);a("lowercase",dd);a("number",Sb);a("orderBy",Tb);a("uppercase",ed)}function ad(){return function(b,a){if(!(b instanceof Array))return b;var c=[];c.check=function(a){for(var b=0;b<c.length;b++)if(!c[b](a))return!1;return!0};var d=function(a,b){if(b.charAt(0)===
|
||||
"!")return!d(a,b.substr(1));switch(typeof a){case "boolean":case "number":case "string":return(""+a).toLowerCase().indexOf(b)>-1;case "object":for(var c in a)if(c.charAt(0)!=="$"&&d(a[c],b))return!0;return!1;case "array":for(c=0;c<a.length;c++)if(d(a[c],b))return!0;return!1;default:return!1}};switch(typeof a){case "boolean":case "number":case "string":a={$:a};case "object":for(var e in a)e=="$"?function(){var b=(""+a[e]).toLowerCase();b&&c.push(function(a){return d(a,b)})}():function(){var b=e,f=
|
||||
(""+a[e]).toLowerCase();f&&c.push(function(a){return d(fb(a,b),f)})}();break;case "function":c.push(a);break;default:return b}for(var g=[],i=0;i<b.length;i++){var f=b[i];c.check(f)&&g.push(f)}return g}}function Qb(b){var a=b.NUMBER_FORMATS;return function(b,d){if(t(d))d=a.CURRENCY_SYM;return Ub(b,a.PATTERNS[1],a.GROUP_SEP,a.DECIMAL_SEP,2).replace(/\u00A4/g,d)}}function Sb(b){var a=b.NUMBER_FORMATS;return function(b,d){return Ub(b,a.PATTERNS[0],a.GROUP_SEP,a.DECIMAL_SEP,d)}}function Ub(b,a,c,d,e){if(isNaN(b)||
|
||||
!isFinite(b))return"";var g=b<0,b=Math.abs(b),i=b+"",f="",h=[],k=!1;if(i.indexOf("e")!==-1){var j=i.match(/([\d\.]+)e(-?)(\d+)/);j&&j[2]=="-"&&j[3]>e+1?i="0":(f=i,k=!0)}if(!k){i=(i.split(Vb)[1]||"").length;t(e)&&(e=Math.min(Math.max(a.minFrac,i),a.maxFrac));var i=Math.pow(10,e),b=Math.round(b*i)/i,b=(""+b).split(Vb),i=b[0],b=b[1]||"",k=0,j=a.lgSize,l=a.gSize;if(i.length>=j+l)for(var k=i.length-j,o=0;o<k;o++)(k-o)%l===0&&o!==0&&(f+=c),f+=i.charAt(o);for(o=k;o<i.length;o++)(i.length-o)%j===0&&o!==0&&
|
||||
(f+=c),f+=i.charAt(o);for(;b.length<e;)b+="0";e&&(f+=d+b.substr(0,e))}h.push(g?a.negPre:a.posPre);h.push(f);h.push(g?a.negSuf:a.posSuf);return h.join("")}function ib(b,a,c){var d="";b<0&&(d="-",b=-b);for(b=""+b;b.length<a;)b="0"+b;c&&(b=b.substr(b.length-a));return d+b}function P(b,a,c,d){return function(e){e=e["get"+b]();if(c>0||e>-c)e+=c;e===0&&c==-12&&(e=12);return ib(e,a,d)}}function La(b,a){return function(c,d){var e=c["get"+b](),g=la(a?"SHORT"+b:b);return d[g][e]}}function Rb(b){function a(a){var b;
|
||||
if(b=a.match(c)){var a=new Date(0),g=0,i=0;b[9]&&(g=G(b[9]+b[10]),i=G(b[9]+b[11]));a.setUTCFullYear(G(b[1]),G(b[2])-1,G(b[3]));a.setUTCHours(G(b[4]||0)-g,G(b[5]||0)-i,G(b[6]||0),G(b[7]||0))}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e){var g="",i=[],f,h,e=e||"mediumDate",e=b.DATETIME_FORMATS[e]||e;F(c)&&(c=fd.test(c)?G(c):a(c));wa(c)&&(c=new Date(c));if(!na(c))return c;for(;e;)(h=gd.exec(e))?(i=i.concat(ia.call(h,
|
||||
1)),e=i.pop()):(i.push(e),e=null);m(i,function(a){f=hd[a];g+=f?f(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function bd(){return function(b){return da(b,!0)}}function cd(){return function(b,a){if(!(b instanceof Array))return b;var a=G(a),c=[],d,e;if(!b||!(b instanceof Array))return c;a>b.length?a=b.length:a<-b.length&&(a=-b.length);a>0?(d=0,e=a):(d=b.length+a,e=b.length);for(;d<e;d++)c.push(b[d]);return c}}function Tb(b){return function(a,c,d){function e(a,b){return Wa(b)?
|
||||
function(b,c){return a(c,b)}:a}if(!(a instanceof Array))return a;if(!c)return a;for(var c=J(c)?c:[c],c=Ta(c,function(a){var c=!1,d=a||ma;if(F(a)){if(a.charAt(0)=="+"||a.charAt(0)=="-")c=a.charAt(0)=="-",a=a.substring(1);d=b(a)}return e(function(a,b){var c;c=d(a);var e=d(b),f=typeof c,g=typeof e;f==g?(f=="string"&&(c=c.toLowerCase()),f=="string"&&(e=e.toLowerCase()),c=c===e?0:c<e?-1:1):c=f<g?-1:1;return c},c)}),g=[],i=0;i<a.length;i++)g.push(a[i]);return g.sort(e(function(a,b){for(var d=0;d<c.length;d++){var e=
|
||||
c[d](a,b);if(e!==0)return e}return 0},d))}}function S(b){N(b)&&(b={link:b});b.restrict=b.restrict||"AC";return I(b)}function Wb(b,a){function c(a,c){c=c?"-"+$a(c,"-"):"";b.removeClass((a?Ma:Na)+c).addClass((a?Na:Ma)+c)}var d=this,e=b.parent().controller("form")||Oa,g=0,i=d.$error={};d.$name=a.name;d.$dirty=!1;d.$pristine=!0;d.$valid=!0;d.$invalid=!1;e.$addControl(d);b.addClass(Pa);c(!0);d.$addControl=function(a){a.$name&&!d.hasOwnProperty(a.$name)&&(d[a.$name]=a)};d.$removeControl=function(a){a.$name&&
|
||||
d[a.$name]===a&&delete d[a.$name];m(i,function(b,c){d.$setValidity(c,!0,a)})};d.$setValidity=function(a,b,k){var j=i[a];if(b){if(j&&(Ua(j,k),!j.length)){g--;if(!g)c(b),d.$valid=!0,d.$invalid=!1;i[a]=!1;c(!0,a);e.$setValidity(a,!0,d)}}else{g||c(b);if(j){if(za(j,k)!=-1)return}else i[a]=j=[],g++,c(!1,a),e.$setValidity(a,!1,d);j.push(k);d.$valid=!1;d.$invalid=!0}};d.$setDirty=function(){b.removeClass(Pa).addClass(Xb);d.$dirty=!0;d.$pristine=!1;e.$setDirty()}}function T(b){return t(b)||b===""||b===null||
|
||||
b!==b}function Qa(b,a,c,d,e,g){var i=function(){var c=R(a.val());d.$viewValue!==c&&b.$apply(function(){d.$setViewValue(c)})};if(e.hasEvent("input"))a.bind("input",i);else{var f;a.bind("keydown",function(a){a=a.keyCode;a===91||15<a&&a<19||37<=a&&a<=40||f||(f=g.defer(function(){i();f=null}))});a.bind("change",i)}d.$render=function(){a.val(T(d.$viewValue)?"":d.$viewValue)};var h=c.ngPattern,k=function(a,b){return T(b)||a.test(b)?(d.$setValidity("pattern",!0),b):(d.$setValidity("pattern",!1),p)};h&&(h.match(/^\/(.*)\/$/)?
|
||||
(h=RegExp(h.substr(1,h.length-2)),e=function(a){return k(h,a)}):e=function(a){var c=b.$eval(h);if(!c||!c.test)throw new B("Expected "+h+" to be a RegExp but was "+c);return k(c,a)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var j=G(c.ngMinlength),e=function(a){return!T(a)&&a.length<j?(d.$setValidity("minlength",!1),p):(d.$setValidity("minlength",!0),a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var l=G(c.ngMaxlength),c=function(a){return!T(a)&&a.length>l?(d.$setValidity("maxlength",
|
||||
!1),p):(d.$setValidity("maxlength",!0),a)};d.$parsers.push(c);d.$formatters.push(c)}}function jb(b,a){b="ngClass"+b;return S(function(c,d,e){function g(b,d){if(a===!0||c.$index%2===a)d&&b!==d&&i(d),f(b)}function i(a){L(a)&&!J(a)&&(a=Ta(a,function(a,b){if(a)return b}));d.removeClass(J(a)?a.join(" "):a)}function f(a){L(a)&&!J(a)&&(a=Ta(a,function(a,b){if(a)return b}));a&&d.addClass(J(a)?a.join(" "):a)}c.$watch(e[b],g,!0);e.$observe("class",function(){var a=c.$eval(e[b]);g(a,a)});b!=="ngClass"&&c.$watch("$index",
|
||||
function(d,g){var j=d%2;j!==g%2&&(j==a?f(c.$eval(e[b])):i(c.$eval(e[b])))})})}var E=function(b){return F(b)?b.toLowerCase():b},la=function(b){return F(b)?b.toUpperCase():b},B=U.Error,aa=G((/msie (\d+)/.exec(E(navigator.userAgent))||[])[1]),u,ja,ia=[].slice,Ra=[].push,Sa=Object.prototype.toString,Yb=U.angular||(U.angular={}),ta,Cb,Z=["0","0","0"];D.$inject=[];ma.$inject=[];Cb=aa<9?function(b){b=b.nodeName?b:b[0];return b.scopeName&&b.scopeName!="HTML"?la(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?
|
||||
b.nodeName:b[0].nodeName};var kc=/[A-Z]/g,id={full:"1.0.3",major:1,minor:0,dot:3,codeName:"bouncy-thunder"},Ba=Q.cache={},Aa=Q.expando="ng-"+(new Date).getTime(),oc=1,Zb=U.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},db=U.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)},mc=/([\:\-\_]+(.))/g,nc=/^moz([A-Z])/,ua=Q.prototype={ready:function(b){function a(){c||(c=!0,b())}
|
||||
var c=!1;this.bind("DOMContentLoaded",a);Q(U).bind("load",a)},toString:function(){var b=[];m(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return b>=0?u(this[b]):u(this[this.length+b])},length:0,push:Ra,sort:[].sort,splice:[].splice},Ea={};m("multiple,selected,checked,disabled,readOnly,required".split(","),function(b){Ea[E(b)]=b});var zb={};m("input,select,option,textarea,button,form".split(","),function(b){zb[la(b)]=!0});m({data:ub,inheritedData:Da,scope:function(b){return Da(b,
|
||||
"$scope")},controller:xb,injector:function(b){return Da(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Ca,css:function(b,a,c){a=rb(a);if(v(c))b.style[a]=c;else{var d;aa<=8&&(d=b.currentStyle&&b.currentStyle[a],d===""&&(d="auto"));d=d||b.style[a];aa<=8&&(d=d===""?p:d);return d}},attr:function(b,a,c){var d=E(a);if(Ea[d])if(v(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||D).specified?d:p;else if(v(c))b.setAttribute(a,
|
||||
c);else if(b.getAttribute)return b=b.getAttribute(a,2),b===null?p:b},prop:function(b,a,c){if(v(c))b[a]=c;else return b[a]},text:x(aa<9?function(b,a){if(b.nodeType==1){if(t(a))return b.innerText;b.innerText=a}else{if(t(a))return b.nodeValue;b.nodeValue=a}}:function(b,a){if(t(a))return b.textContent;b.textContent=a},{$dv:""}),val:function(b,a){if(t(a))return b.value;b.value=a},html:function(b,a){if(t(a))return b.innerHTML;for(var c=0,d=b.childNodes;c<d.length;c++)sa(d[c]);b.innerHTML=a}},function(b,
|
||||
a){Q.prototype[a]=function(a,d){var e,g;if((b.length==2&&b!==Ca&&b!==xb?a:d)===p)if(L(a)){for(e=0;e<this.length;e++)if(b===ub)b(this[e],a);else for(g in a)b(this[e],g,a[g]);return this}else{if(this.length)return b(this[0],a,d)}else{for(e=0;e<this.length;e++)b(this[e],a,d);return this}return b.$dv}});m({removeData:sb,dealoc:sa,bind:function a(c,d,e){var g=$(c,"events"),i=$(c,"handle");g||$(c,"events",g={});i||$(c,"handle",i=pc(c,g));m(d.split(" "),function(d){var h=g[d];if(!h){if(d=="mouseenter"||
|
||||
d=="mouseleave"){var k=0;g.mouseenter=[];g.mouseleave=[];a(c,"mouseover",function(a){k++;k==1&&i(a,"mouseenter")});a(c,"mouseout",function(a){k--;k==0&&i(a,"mouseleave")})}else Zb(c,d,i),g[d]=[];h=g[d]}h.push(e)})},unbind:tb,replaceWith:function(a,c){var d,e=a.parentNode;sa(a);m(new Q(c),function(c){d?e.insertBefore(c,d.nextSibling):e.replaceChild(c,a);d=c})},children:function(a){var c=[];m(a.childNodes,function(a){a.nodeName!="#text"&&c.push(a)});return c},contents:function(a){return a.childNodes},
|
||||
append:function(a,c){m(new Q(c),function(c){a.nodeType===1&&a.appendChild(c)})},prepend:function(a,c){if(a.nodeType===1){var d=a.firstChild;m(new Q(c),function(c){d?a.insertBefore(c,d):(a.appendChild(c),d=c)})}},wrap:function(a,c){var c=u(c)[0],d=a.parentNode;d&&d.replaceChild(c,a);c.appendChild(a)},remove:function(a){sa(a);var c=a.parentNode;c&&c.removeChild(a)},after:function(a,c){var d=a,e=a.parentNode;m(new Q(c),function(a){e.insertBefore(a,d.nextSibling);d=a})},addClass:wb,removeClass:vb,toggleClass:function(a,
|
||||
c,d){t(d)&&(d=!Ca(a,c));(d?wb:vb)(a,c)},parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},next:function(a){return a.nextSibling},find:function(a,c){return a.getElementsByTagName(c)},clone:cb,triggerHandler:function(a,c){var d=($(a,"events")||{})[c];m(d,function(c){c.call(a,null)})}},function(a,c){Q.prototype[c]=function(c,e){for(var g,i=0;i<this.length;i++)g==p?(g=a(this[i],c,e),g!==p&&(g=u(g))):bb(g,a(this[i],c,e));return g==p?this:g}});Fa.prototype={put:function(a,c){this[ga(a)]=
|
||||
c},get:function(a){return this[ga(a)]},remove:function(a){var c=this[a=ga(a)];delete this[a];return c}};eb.prototype={push:function(a,c){var d=this[a=ga(a)];d?d.push(c):this[a]=[c]},shift:function(a){var c=this[a=ga(a)];if(c)return c.length==1?(delete this[a],c[0]):c.shift()},peek:function(a){if(a=this[ga(a)])return a[0]}};var rc=/^function\s*[^\(]*\(\s*([^\)]*)\)/m,sc=/,/,tc=/^\s*(_?)(\S+?)\1\s*$/,qc=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg,Db="Non-assignable model expression: ";Bb.$inject=["$provide"];
|
||||
var Ac=/^(x[\:\-_]|data[\:\-_])/i,Fb=/^([^:]+):\/\/(\w+:{0,1}\w*@)?([\w\.-]*)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/,$b=/^([^\?#]*)?(\?([^#]*))?(#(.*))?$/,Hc=$b,Gb={http:80,https:443,ftp:21};gb.prototype={$$replace:!1,absUrl:Ja("$$absUrl"),url:function(a,c){if(t(a))return this.$$url;var d=$b.exec(a);d[1]&&this.path(decodeURIComponent(d[1]));if(d[2]||d[1])this.search(d[3]||"");this.hash(d[5]||"",c);return this},protocol:Ja("$$protocol"),host:Ja("$$host"),port:Ja("$$port"),path:Ib("$$path",function(a){return a.charAt(0)==
|
||||
"/"?a:"/"+a}),search:function(a,c){if(t(a))return this.$$search;v(c)?c===null?delete this.$$search[a]:this.$$search[a]=c:this.$$search=F(a)?Xa(a):a;this.$$compose();return this},hash:Ib("$$hash",ma),replace:function(){this.$$replace=!0;return this}};Ia.prototype=ya(gb.prototype);Hb.prototype=ya(Ia.prototype);var Ka={"null":function(){return null},"true":function(){return!0},"false":function(){return!1},undefined:D,"+":function(a,c,d,e){d=d(a,c);e=e(a,c);return v(d)?v(e)?d+e:d:v(e)?e:p},"-":function(a,
|
||||
c,d,e){d=d(a,c);e=e(a,c);return(v(d)?d:0)-(v(e)?e:0)},"*":function(a,c,d,e){return d(a,c)*e(a,c)},"/":function(a,c,d,e){return d(a,c)/e(a,c)},"%":function(a,c,d,e){return d(a,c)%e(a,c)},"^":function(a,c,d,e){return d(a,c)^e(a,c)},"=":D,"==":function(a,c,d,e){return d(a,c)==e(a,c)},"!=":function(a,c,d,e){return d(a,c)!=e(a,c)},"<":function(a,c,d,e){return d(a,c)<e(a,c)},">":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,
|
||||
c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Lc={n:"\n",f:"\u000c",r:"\r",t:"\t",v:"\u000b","'":"'",'"':'"'},hb={},Yc=U.XMLHttpRequest||function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(c){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(d){}throw new B("This browser does not support XMLHttpRequest.");
|
||||
};Pb.$inject=["$provide"];Qb.$inject=["$locale"];Sb.$inject=["$locale"];var Vb=".",hd={yyyy:P("FullYear",4),yy:P("FullYear",2,0,!0),y:P("FullYear",1),MMMM:La("Month"),MMM:La("Month",!0),MM:P("Month",2,1),M:P("Month",1,1),dd:P("Date",2),d:P("Date",1),HH:P("Hours",2),H:P("Hours",1),hh:P("Hours",2,-12),h:P("Hours",1,-12),mm:P("Minutes",2),m:P("Minutes",1),ss:P("Seconds",2),s:P("Seconds",1),EEEE:La("Day"),EEE:La("Day",!0),a:function(a,c){return a.getHours()<12?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=a.getTimezoneOffset();
|
||||
return ib(a/60,2)+ib(Math.abs(a%60),2)}},gd=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,fd=/^\d+$/;Rb.$inject=["$locale"];var dd=I(E),ed=I(la);Tb.$inject=["$parse"];var jd=I({restrict:"E",compile:function(a,c){c.href||c.$set("href","");return function(a,c){c.bind("click",function(a){if(!c.attr("href"))return a.preventDefault(),!1})}}}),kb={};m(Ea,function(a,c){var d=fa("ng-"+c);kb[d]=function(){return{priority:100,compile:function(){return function(a,g,i){a.$watch(i[d],
|
||||
function(a){i.$set(c,!!a)})}}}}});m(["src","href"],function(a){var c=fa("ng-"+a);kb[c]=function(){return{priority:99,link:function(d,e,g){g.$observe(c,function(c){c&&(g.$set(a,c),aa&&e.prop(a,c))})}}}});var Oa={$addControl:D,$removeControl:D,$setValidity:D,$setDirty:D};Wb.$inject=["$element","$attrs","$scope"];var Ra=function(a){return["$timeout",function(c){var d={name:"form",restrict:"E",controller:Wb,compile:function(){return{pre:function(a,d,i,f){if(!i.action){var h=function(a){a.preventDefault?
|
||||
a.preventDefault():a.returnValue=!1};Zb(d[0],"submit",h);d.bind("$destroy",function(){c(function(){db(d[0],"submit",h)},0,!1)})}var k=d.parent().controller("form"),j=i.name||i.ngForm;j&&(a[j]=f);k&&d.bind("$destroy",function(){k.$removeControl(f);j&&(a[j]=p);x(f,Oa)})}}}};return a?x(V(d),{restrict:"EAC"}):d}]},kd=Ra(),ld=Ra(!0),md=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,nd=/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/,od=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,
|
||||
ac={text:Qa,number:function(a,c,d,e,g,i){Qa(a,c,d,e,g,i);e.$parsers.push(function(a){var c=T(a);return c||od.test(a)?(e.$setValidity("number",!0),a===""?null:c?a:parseFloat(a)):(e.$setValidity("number",!1),p)});e.$formatters.push(function(a){return T(a)?"":""+a});if(d.min){var f=parseFloat(d.min),a=function(a){return!T(a)&&a<f?(e.$setValidity("min",!1),p):(e.$setValidity("min",!0),a)};e.$parsers.push(a);e.$formatters.push(a)}if(d.max){var h=parseFloat(d.max),d=function(a){return!T(a)&&a>h?(e.$setValidity("max",
|
||||
!1),p):(e.$setValidity("max",!0),a)};e.$parsers.push(d);e.$formatters.push(d)}e.$formatters.push(function(a){return T(a)||wa(a)?(e.$setValidity("number",!0),a):(e.$setValidity("number",!1),p)})},url:function(a,c,d,e,g,i){Qa(a,c,d,e,g,i);a=function(a){return T(a)||md.test(a)?(e.$setValidity("url",!0),a):(e.$setValidity("url",!1),p)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,c,d,e,g,i){Qa(a,c,d,e,g,i);a=function(a){return T(a)||nd.test(a)?(e.$setValidity("email",!0),a):(e.$setValidity("email",
|
||||
!1),p)};e.$formatters.push(a);e.$parsers.push(a)},radio:function(a,c,d,e){t(d.name)&&c.attr("name",xa());c.bind("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue};d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var g=d.ngTrueValue,i=d.ngFalseValue;F(g)||(g=!0);F(i)||(i=!1);c.bind("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$formatters.push(function(a){return a===
|
||||
g});e.$parsers.push(function(a){return a?g:i})},hidden:D,button:D,submit:D,reset:D},bc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel",link:function(d,e,g,i){i&&(ac[E(g.type)]||ac.text)(d,e,g,i,c,a)}}}],Na="ng-valid",Ma="ng-invalid",Pa="ng-pristine",Xb="ng-dirty",pd=["$scope","$exceptionHandler","$attrs","$element","$parse",function(a,c,d,e,g){function i(a,c){c=c?"-"+$a(c,"-"):"";e.removeClass((a?Ma:Na)+c).addClass((a?Na:Ma)+c)}this.$modelValue=this.$viewValue=Number.NaN;
|
||||
this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name=d.name;var f=g(d.ngModel),h=f.assign;if(!h)throw B(Db+d.ngModel+" ("+pa(e)+")");this.$render=D;var k=e.inheritedData("$formController")||Oa,j=0,l=this.$error={};e.addClass(Pa);i(!0);this.$setValidity=function(a,c){if(l[a]!==!c){if(c){if(l[a]&&j--,!j)i(!0),this.$valid=!0,this.$invalid=!1}else i(!1),this.$invalid=!0,this.$valid=!1,j++;l[a]=!c;i(c,a);k.$setValidity(a,
|
||||
c,this)}};this.$setViewValue=function(d){this.$viewValue=d;if(this.$pristine)this.$dirty=!0,this.$pristine=!1,e.removeClass(Pa).addClass(Xb),k.$setDirty();m(this.$parsers,function(a){d=a(d)});if(this.$modelValue!==d)this.$modelValue=d,h(a,d),m(this.$viewChangeListeners,function(a){try{a()}catch(d){c(d)}})};var o=this;a.$watch(function(){var c=f(a);if(o.$modelValue!==c){var d=o.$formatters,e=d.length;for(o.$modelValue=c;e--;)c=d[e](c);if(o.$viewValue!==c)o.$viewValue=c,o.$render()}})}],qd=function(){return{require:["ngModel",
|
||||
"^?form"],controller:pd,link:function(a,c,d,e){var g=e[0],i=e[1]||Oa;i.$addControl(g);c.bind("$destroy",function(){i.$removeControl(g)})}}},rd=I({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),cc=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var g=function(a){if(d.required&&(T(a)||a===!1))e.$setValidity("required",!1);else return e.$setValidity("required",!0),a};e.$formatters.push(g);e.$parsers.unshift(g);
|
||||
d.$observe("required",function(){g(e.$viewValue)})}}}},sd=function(){return{require:"ngModel",link:function(a,c,d,e){var g=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){var c=[];a&&m(a.split(g),function(a){a&&c.push(R(a))});return c});e.$formatters.push(function(a){return J(a)?a.join(", "):p})}}},td=/^(true|false|\d+)$/,ud=function(){return{priority:100,compile:function(a,c){return td.test(c.ngValue)?function(a,c,g){g.$set("value",a.$eval(g.ngValue))}:function(a,
|
||||
c,g){a.$watch(g.ngValue,function(a){g.$set("value",a,!1)})}}}},vd=S(function(a,c,d){c.addClass("ng-binding").data("$binding",d.ngBind);a.$watch(d.ngBind,function(a){c.text(a==p?"":a)})}),wd=["$interpolate",function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}],xd=[function(){return function(a,c,d){c.addClass("ng-binding").data("$binding",d.ngBindHtmlUnsafe);a.$watch(d.ngBindHtmlUnsafe,
|
||||
function(a){c.html(a||"")})}}],yd=jb("",!0),zd=jb("Odd",0),Ad=jb("Even",1),Bd=S({compile:function(a,c){c.$set("ngCloak",p);a.removeClass("ng-cloak")}}),Cd=[function(){return{scope:!0,controller:"@"}}],Dd=["$sniffer",function(a){return{priority:1E3,compile:function(){a.csp=!0}}}],dc={};m("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave".split(" "),function(a){var c=fa("ng-"+a);dc[c]=["$parse",function(d){return function(e,g,i){var f=d(i[c]);g.bind(E(a),function(a){e.$apply(function(){f(e,
|
||||
{$event:a})})})}}]});var Ed=S(function(a,c,d){c.bind("submit",function(){a.$apply(d.ngSubmit)})}),Fd=["$http","$templateCache","$anchorScroll","$compile",function(a,c,d,e){return{restrict:"ECA",terminal:!0,compile:function(g,i){var f=i.ngInclude||i.src,h=i.onload||"",k=i.autoscroll;return function(g,i){var o=0,m,n=function(){m&&(m.$destroy(),m=null);i.html("")};g.$watch(f,function(f){var p=++o;f?a.get(f,{cache:c}).success(function(a){p===o&&(m&&m.$destroy(),m=g.$new(),i.html(a),e(i.contents())(m),
|
||||
v(k)&&(!k||g.$eval(k))&&d(),m.$emit("$includeContentLoaded"),g.$eval(h))}).error(function(){p===o&&n()}):n()})}}}}],Gd=S({compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),Hd=S({terminal:!0,priority:1E3}),Id=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,g,i){var f=i.count,h=g.attr(i.$attr.when),k=i.offset||0,j=e.$eval(h),l={},o=c.startSymbol(),r=c.endSymbol();m(j,function(a,e){l[e]=c(a.replace(d,o+f+"-"+k+r))});e.$watch(function(){var c=
|
||||
parseFloat(e.$eval(f));return isNaN(c)?"":(j[c]||(c=a.pluralCat(c-k)),l[c](e,g,!0))},function(a){g.text(a)})}}}],Jd=S({transclude:"element",priority:1E3,terminal:!0,compile:function(a,c,d){return function(a,c,i){var f=i.ngRepeat,i=f.match(/^\s*(.+)\s+in\s+(.*)\s*$/),h,k,j;if(!i)throw B("Expected ngRepeat in form of '_item_ in _collection_' but got '"+f+"'.");f=i[1];h=i[2];i=f.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!i)throw B("'item' in 'item in collection' should be identifier or (key, value) but got '"+
|
||||
f+"'.");k=i[3]||i[1];j=i[2];var l=new eb;a.$watch(function(a){var e,f,i=a.$eval(h),m=gc(i,!0),p,u=new eb,C,A,v,t,y=c;if(J(i))v=i||[];else{v=[];for(C in i)i.hasOwnProperty(C)&&C.charAt(0)!="$"&&v.push(C);v.sort()}e=0;for(f=v.length;e<f;e++){C=i===v?e:v[e];A=i[C];if(t=l.shift(A)){p=t.scope;u.push(A,t);if(e!==t.index)t.index=e,y.after(t.element);y=t.element}else p=a.$new();p[k]=A;j&&(p[j]=C);p.$index=e;p.$first=e===0;p.$last=e===m-1;p.$middle=!(p.$first||p.$last);t||d(p,function(a){y.after(a);t={scope:p,
|
||||
element:y=a,index:e};u.push(A,t)})}for(C in l)if(l.hasOwnProperty(C))for(v=l[C];v.length;)A=v.pop(),A.element.remove(),A.scope.$destroy();l=u})}}}),Kd=S(function(a,c,d){a.$watch(d.ngShow,function(a){c.css("display",Wa(a)?"":"none")})}),Ld=S(function(a,c,d){a.$watch(d.ngHide,function(a){c.css("display",Wa(a)?"none":"")})}),Md=S(function(a,c,d){a.$watch(d.ngStyle,function(a,d){d&&a!==d&&m(d,function(a,d){c.css(d,"")});a&&c.css(a)},!0)}),Nd=I({restrict:"EA",compile:function(a,c){var d=c.ngSwitch||c.on,
|
||||
e={};a.data("ng-switch",e);return function(a,i){var f,h,k;a.$watch(d,function(d){h&&(k.$destroy(),h.remove(),h=k=null);if(f=e["!"+d]||e["?"])a.$eval(c.change),k=a.$new(),f(k,function(a){h=a;i.append(a)})})}}}),Od=S({transclude:"element",priority:500,compile:function(a,c,d){a=a.inheritedData("ng-switch");qa(a);a["!"+c.ngSwitchWhen]=d}}),Pd=S({transclude:"element",priority:500,compile:function(a,c,d){a=a.inheritedData("ng-switch");qa(a);a["?"]=d}}),Qd=S({controller:["$transclude","$element",function(a,
|
||||
c){a(function(a){c.append(a)})}]}),Rd=["$http","$templateCache","$route","$anchorScroll","$compile","$controller",function(a,c,d,e,g,i){return{restrict:"ECA",terminal:!0,link:function(a,c,k){function j(){var j=d.current&&d.current.locals,k=j&&j.$template;if(k){c.html(k);l&&(l.$destroy(),l=null);var k=g(c.contents()),p=d.current;l=p.scope=a.$new();if(p.controller)j.$scope=l,j=i(p.controller,j),c.contents().data("$ngControllerController",j);k(l);l.$emit("$viewContentLoaded");l.$eval(m);e()}else c.html(""),
|
||||
l&&(l.$destroy(),l=null)}var l,m=k.onload||"";a.$on("$routeChangeSuccess",j);j()}}}],Sd=["$templateCache",function(a){return{restrict:"E",terminal:!0,compile:function(c,d){d.type=="text/ng-template"&&a.put(d.id,c[0].text)}}}],Td=I({terminal:!0}),Ud=["$compile","$parse",function(a,c){var d=/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w\d]*)|(?:\(\s*([\$\w][\$\w\d]*)\s*,\s*([\$\w][\$\w\d]*)\s*\)))\s+in\s+(.*)$/,e={$setViewValue:D};return{restrict:"E",require:["select",
|
||||
"?ngModel"],controller:["$element","$scope","$attrs",function(a,c,d){var h=this,k={},j=e,l;h.databound=d.ngModel;h.init=function(a,c,d){j=a;l=d};h.addOption=function(c){k[c]=!0;j.$viewValue==c&&(a.val(c),l.parent()&&l.remove())};h.removeOption=function(a){this.hasOption(a)&&(delete k[a],j.$viewValue==a&&this.renderUnknownOption(a))};h.renderUnknownOption=function(c){c="? "+ga(c)+" ?";l.val(c);a.prepend(l);a.val(c);l.prop("selected",!0)};h.hasOption=function(a){return k.hasOwnProperty(a)};c.$on("$destroy",
|
||||
function(){h.renderUnknownOption=D})}],link:function(e,i,f,h){function k(a,c,d,e){d.$render=function(){var a=d.$viewValue;e.hasOption(a)?(A.parent()&&A.remove(),c.val(a),a===""&&s.prop("selected",!0)):t(a)&&s?c.val(""):e.renderUnknownOption(a)};c.bind("change",function(){a.$apply(function(){A.parent()&&A.remove();d.$setViewValue(c.val())})})}function j(a,c,d){var e;d.$render=function(){var a=new Fa(d.$viewValue);m(c.children(),function(c){c.selected=v(a.get(c.value))})};a.$watch(function(){ha(e,d.$viewValue)||
|
||||
(e=V(d.$viewValue),d.$render())});c.bind("change",function(){a.$apply(function(){var a=[];m(c.children(),function(c){c.selected&&a.push(c.value)});d.$setViewValue(a)})})}function l(e,f,g){function h(){var a={"":[]},c=[""],d,i,s,t,u;s=g.$modelValue;t=r(e)||[];var y=l?lb(t):t,A,w,x;w={};u=!1;var z,B;if(n)u=new Fa(s);else if(s===null||q)a[""].push({selected:s===null,id:"",label:""}),u=!0;for(x=0;A=y.length,x<A;x++){w[k]=t[l?w[l]=y[x]:x];d=m(e,w)||"";if(!(i=a[d]))i=a[d]=[],c.push(d);n?d=u.remove(o(e,
|
||||
w))!=p:(d=s===o(e,w),u=u||d);z=j(e,w);z=z===p?"":z;i.push({id:l?y[x]:x,label:z,selected:d})}!n&&!u&&a[""].unshift({id:"?",label:"",selected:!0});w=0;for(y=c.length;w<y;w++){d=c[w];i=a[d];if(v.length<=w)s={element:C.clone().attr("label",d),label:i.label},t=[s],v.push(t),f.append(s.element);else if(t=v[w],s=t[0],s.label!=d)s.element.attr("label",s.label=d);z=null;x=0;for(A=i.length;x<A;x++)if(d=i[x],u=t[x+1]){z=u.element;if(u.label!==d.label)z.text(u.label=d.label);if(u.id!==d.id)z.val(u.id=d.id);if(u.element.selected!==
|
||||
d.selected)z.prop("selected",u.selected=d.selected)}else d.id===""&&q?B=q:(B=D.clone()).val(d.id).attr("selected",d.selected).text(d.label),t.push({element:B,label:d.label,id:d.id,selected:d.selected}),z?z.after(B):s.element.append(B),z=B;for(x++;t.length>x;)t.pop().element.remove()}for(;v.length>w;)v.pop()[0].element.remove()}var i;if(!(i=w.match(d)))throw B("Expected ngOptions in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_' but got '"+w+"'.");var j=c(i[2]||i[1]),k=i[4]||
|
||||
i[6],l=i[5],m=c(i[3]||""),o=c(i[2]?i[1]:k),r=c(i[7]),v=[[{element:f,label:""}]];q&&(a(q)(e),q.removeClass("ng-scope"),q.remove());f.html("");f.bind("change",function(){e.$apply(function(){var a,c=r(e)||[],d={},h,i,j,m,q,s;if(n){i=[];m=0;for(s=v.length;m<s;m++){a=v[m];j=1;for(q=a.length;j<q;j++)if((h=a[j].element)[0].selected)h=h.val(),l&&(d[l]=h),d[k]=c[h],i.push(o(e,d))}}else h=f.val(),h=="?"?i=p:h==""?i=null:(d[k]=c[h],l&&(d[l]=h),i=o(e,d));g.$setViewValue(i)})});g.$render=h;e.$watch(h)}if(h[1]){for(var o=
|
||||
h[0],r=h[1],n=f.multiple,w=f.ngOptions,q=!1,s,D=u(ca.createElement("option")),C=u(ca.createElement("optgroup")),A=D.clone(),h=0,x=i.children(),E=x.length;h<E;h++)if(x[h].value==""){s=q=x.eq(h);break}o.init(r,q,A);if(n&&(f.required||f.ngRequired)){var y=function(a){r.$setValidity("required",!f.required||a&&a.length);return a};r.$parsers.push(y);r.$formatters.unshift(y);f.$observe("required",function(){y(r.$viewValue)})}w?l(e,i,r):n?j(e,i,r):k(e,i,r,o)}}}}],Vd=["$interpolate",function(a){var c={addOption:D,
|
||||
removeOption:D};return{restrict:"E",priority:100,compile:function(d,e){if(t(e.value)){var g=a(d.text(),!0);g||e.$set("value",d.text())}return function(a,d,e){var k=d.parent(),j=k.data("$selectController")||k.parent().data("$selectController");j&&j.databound?d.prop("selected",!1):j=c;g?a.$watch(g,function(a,c){e.$set("value",a);a!==c&&j.removeOption(c);j.addOption(a)}):j.addOption(e.value);d.bind("$destroy",function(){j.removeOption(e.value)})}}}}],Wd=I({restrict:"E",terminal:!0});(ja=U.jQuery)?(u=
|
||||
ja,x(ja.fn,{scope:ua.scope,controller:ua.controller,injector:ua.injector,inheritedData:ua.inheritedData}),ab("remove",!0),ab("empty"),ab("html")):u=Q;Yb.element=u;(function(a){x(a,{bootstrap:pb,copy:V,extend:x,equals:ha,element:u,forEach:m,injector:qb,noop:D,bind:Va,toJson:da,fromJson:nb,identity:ma,isUndefined:t,isDefined:v,isString:F,isFunction:N,isObject:L,isNumber:wa,isElement:fc,isArray:J,version:id,isDate:na,lowercase:E,uppercase:la,callbacks:{counter:0}});ta=lc(U);try{ta("ngLocale")}catch(c){ta("ngLocale",
|
||||
[]).provider("$locale",Zc)}ta("ng",["ngLocale"],["$provide",function(a){a.provider("$compile",Bb).directive({a:jd,input:bc,textarea:bc,form:kd,script:Sd,select:Ud,style:Wd,option:Vd,ngBind:vd,ngBindHtmlUnsafe:xd,ngBindTemplate:wd,ngClass:yd,ngClassEven:Ad,ngClassOdd:zd,ngCsp:Dd,ngCloak:Bd,ngController:Cd,ngForm:ld,ngHide:Ld,ngInclude:Fd,ngInit:Gd,ngNonBindable:Hd,ngPluralize:Id,ngRepeat:Jd,ngShow:Kd,ngSubmit:Ed,ngStyle:Md,ngSwitch:Nd,ngSwitchWhen:Od,ngSwitchDefault:Pd,ngOptions:Td,ngView:Rd,ngTransclude:Qd,
|
||||
ngModel:qd,ngList:sd,ngChange:rd,required:cc,ngRequired:cc,ngValue:ud}).directive(kb).directive(dc);a.provider({$anchorScroll:uc,$browser:wc,$cacheFactory:xc,$controller:Bc,$document:Cc,$exceptionHandler:Dc,$filter:Pb,$interpolate:Ec,$http:Vc,$httpBackend:Wc,$location:Ic,$log:Jc,$parse:Nc,$route:Qc,$routeParams:Rc,$rootScope:Sc,$q:Oc,$sniffer:Tc,$templateCache:yc,$timeout:$c,$window:Uc})}])})(Yb);u(ca).ready(function(){jc(ca,pb)})})(window,document);angular.element(document).find("head").append('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak{display:none;}ng\\:form{display:block;}</style>');
|
||||
1092
AndorsTrailEdit/inc/bootstrap/css/bootstrap-responsive.css
vendored
Normal file
1092
AndorsTrailEdit/inc/bootstrap/css/bootstrap-responsive.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
AndorsTrailEdit/inc/bootstrap/css/bootstrap-responsive.min.css
vendored
Normal file
9
AndorsTrailEdit/inc/bootstrap/css/bootstrap-responsive.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
6039
AndorsTrailEdit/inc/bootstrap/css/bootstrap.css
vendored
Normal file
6039
AndorsTrailEdit/inc/bootstrap/css/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
AndorsTrailEdit/inc/bootstrap/css/bootstrap.min.css
vendored
Normal file
9
AndorsTrailEdit/inc/bootstrap/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
AndorsTrailEdit/inc/bootstrap/img/glyphicons-halflings-white.png
Normal file
BIN
AndorsTrailEdit/inc/bootstrap/img/glyphicons-halflings-white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
BIN
AndorsTrailEdit/inc/bootstrap/img/glyphicons-halflings.png
Normal file
BIN
AndorsTrailEdit/inc/bootstrap/img/glyphicons-halflings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
2159
AndorsTrailEdit/inc/bootstrap/js/bootstrap.js
vendored
Normal file
2159
AndorsTrailEdit/inc/bootstrap/js/bootstrap.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
AndorsTrailEdit/inc/bootstrap/js/bootstrap.min.js
vendored
Normal file
6
AndorsTrailEdit/inc/bootstrap/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
AndorsTrailEdit/inc/hint.min.css
vendored
Normal file
5
AndorsTrailEdit/inc/hint.min.css
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/*! Hint.css - v0.1.0 - 2013-02-03
|
||||
* https://github.com/chinchang/hint.css
|
||||
* Copyright (c) 2013 Kushagra Gour; Licensed MIT */
|
||||
|
||||
.hint{position:relative;display:inline-block}.hint:before,.hint:after{position:absolute;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease}.hint:hover:before,.hint:hover:after{opacity:1}.hint:before{content:'';position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}.hint:after{content:attr(data-hint);background:#383838;color:#fff;text-shadow:0 -1px 0 black;padding:8px 10px;font-size:12px;line-height:12px;white-space:nowrap;box-shadow:4px 4px 8px rgba(0,0,0,.3)}.hint--top:before{border-top-color:#383838}.hint--bottom:before{border-bottom-color:#383838}.hint--left:before{border-left-color:#383838}.hint--right:before{border-right-color:#383838}.hint--top:before{margin-bottom:-12px}.hint--top:after{margin-left:-18px}.hint--top:before,.hint--top:after{bottom:100%;left:50%}.hint--top:hover:before,.hint--top:hover:after{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--bottom:before{margin-top:-12px}.hint--bottom:after{margin-left:-18px}.hint--bottom:before,.hint--bottom:after{top:100%;left:50%}.hint--bottom:hover:before,.hint--bottom:hover:after{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--right:before{margin-left:-12px;margin-bottom:-6px}.hint--right:after{margin-bottom:-14px}.hint--right:before,.hint--right:after{left:100%;bottom:50%}.hint--right:hover:before,.hint--right:hover:after{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translateX(8px)}.hint--left:before{margin-right:-12px;margin-bottom:-6px}.hint--left:after{margin-bottom:-14px}.hint--left:before,.hint--left:after{right:100%;bottom:50%}.hint--left:hover:before,.hint--left:hover:after{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translateX(-8px)}.hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0 #5a2626}.hint--error.hint--top:before{border-top-color:#b34e4d}.hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.hint--error.hint--left:before{border-left-color:#b34e4d}.hint--error.hint--right:before{border-right-color:#b34e4d}.hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0 #6d5228}.hint--warning.hint--top:before{border-top-color:#c09854}.hint--warning.hint--bottom:before{border-bottom-color:#c09854}.hint--warning.hint--left:before{border-left-color:#c09854}.hint--warning.hint--right:before{border-right-color:#c09854}.hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0 #193c4c}.hint--info.hint--top:before{border-top-color:#3986ac}.hint--info.hint--bottom:before{border-bottom-color:#3986ac}.hint--info.hint--left:before{border-left-color:#3986ac}.hint--info.hint--right:before{border-right-color:#3986ac}.hint--success:after{background-color:#458746;text-shadow:0 -1px 0 #1a331a}.hint--success.hint--top:before{border-top-color:#458746}.hint--success.hint--bottom:before{border-bottom-color:#458746}.hint--success.hint--left:before{border-left-color:#458746}.hint--success.hint--right:before{border-right-color:#458746}.hint--always:after,.hint--always:before{opacity:1}.hint--always.hint--top:after,.hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--always.hint--bottom:after,.hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--always.hint--left:after,.hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translateX(-8px)}.hint--always.hint--right:after,.hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translateX(8px)}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.9 KiB |
252
AndorsTrailEdit/inc/jquery.dynatree.min.js
vendored
252
AndorsTrailEdit/inc/jquery.dynatree.min.js
vendored
@@ -1,252 +0,0 @@
|
||||
// jquery.dynatree.js build 1.1.1
|
||||
// Revision: 481, date: 2011-03-02 07:25:35
|
||||
// Copyright (c) 2008-10 Martin Wendt (http://dynatree.googlecode.com/)
|
||||
// Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
|
||||
var _canLog=true;function _log(mode,msg){if(!_canLog){return;}
|
||||
var args=Array.prototype.slice.apply(arguments,[1]);var dt=new Date();var tag=dt.getHours()+":"+dt.getMinutes()+":"+dt.getSeconds()+"."+dt.getMilliseconds();args[0]=tag+" - "+args[0];try{switch(mode){case"info":window.console.info.apply(window.console,args);break;case"warn":window.console.warn.apply(window.console,args);break;default:window.console.log.apply(window.console,args);break;}}catch(e){if(!window.console){_canLog=false;}}}
|
||||
function logMsg(msg){Array.prototype.unshift.apply(arguments,["debug"]);_log.apply(this,arguments);}
|
||||
var getDynaTreePersistData=null;var DTNodeStatus_Error=-1;var DTNodeStatus_Loading=1;var DTNodeStatus_Ok=0;(function($){var Class={create:function(){return function(){this.initialize.apply(this,arguments);};}};function getDtNodeFromElement(el){var iMax=5;while(el&&iMax--){if(el.dtnode){return el.dtnode;}
|
||||
el=el.parentNode;}
|
||||
return null;}
|
||||
function noop(){}
|
||||
var DynaTreeNode=Class.create();DynaTreeNode.prototype={initialize:function(parent,tree,data){this.parent=parent;this.tree=tree;if(typeof data==="string"){data={title:data};}
|
||||
if(data.key===undefined){data.key="_"+tree._nodeCount++;}
|
||||
this.data=$.extend({},$.ui.dynatree.nodedatadefaults,data);this.li=null;this.span=null;this.ul=null;this.childList=null;this.isLoading=false;this.hasSubSel=false;this.bExpanded=false;this.bSelected=false;},toString:function(){return"DynaTreeNode<"+this.data.key+">: '"+this.data.title+"'";},toDict:function(recursive,callback){var dict=$.extend({},this.data);dict.activate=(this.tree.activeNode===this);dict.focus=(this.tree.focusNode===this);dict.expand=this.bExpanded;dict.select=this.bSelected;if(callback){callback(dict);}
|
||||
if(recursive&&this.childList){dict.children=[];for(var i=0,l=this.childList.length;i<l;i++){dict.children.push(this.childList[i].toDict(true,callback));}}else{delete dict.children;}
|
||||
return dict;},fromDict:function(dict){var children=dict.children;if(children===undefined){this.data=$.extend(this.data,dict);this.render();return;}
|
||||
dict=$.extend({},dict);dict.children=undefined;this.data=$.extend(this.data,dict);this.removeChildren();this.addChild(children);},_getInnerHtml:function(){var tree=this.tree,opts=tree.options,cache=tree.cache,level=this.getLevel(),data=this.data,res="";if(level<opts.minExpandLevel){if(level>1){res+=cache.tagConnector;}}else if(this.hasChildren()!==false){res+=cache.tagExpander;}else{res+=cache.tagConnector;}
|
||||
if(opts.checkbox&&data.hideCheckbox!==true&&!data.isStatusNode){res+=cache.tagCheckbox;}
|
||||
if(data.icon){res+="<img src='"+opts.imagePath+data.icon+"' alt='' />";}else if(data.icon===false){noop();}else{res+=cache.tagNodeIcon;}
|
||||
var nodeTitle="";if(opts.onCustomRender){nodeTitle=opts.onCustomRender.call(tree,this)||"";}
|
||||
if(!nodeTitle){var tooltip=data.tooltip?" title='"+data.tooltip+"'":"";if(opts.noLink||data.noLink){nodeTitle="<span style='display: inline-block;' class='"+opts.classNames.title+"'"+tooltip+">"+data.title+"</span>";}else{nodeTitle="<a href='#' class='"+opts.classNames.title+"'"+tooltip+">"+data.title+"</a>";}}
|
||||
res+=nodeTitle;return res;},_fixOrder:function(){var cl=this.childList;if(!cl||!this.ul){return;}
|
||||
var childLI=this.ul.firstChild;for(var i=0,l=cl.length-1;i<l;i++){var childNode1=cl[i];var childNode2=childLI.dtnode;if(childNode1!==childNode2){this.tree.logDebug("_fixOrder: mismatch at index "+i+": "+childNode1+" != "+childNode2);this.ul.insertBefore(childNode1.li,childNode2.li);}else{childLI=childLI.nextSibling;}}},render:function(useEffects,includeInvisible){var tree=this.tree,parent=this.parent,data=this.data,opts=tree.options,cn=opts.classNames,isLastSib=this.isLastSibling();if(!parent&&!this.ul){this.li=this.span=null;this.ul=document.createElement("ul");if(opts.minExpandLevel>1){this.ul.className=cn.container+" "+cn.noConnector;}else{this.ul.className=cn.container;}}else if(parent){if(!this.li){this.li=document.createElement("li");this.li.dtnode=this;if(data.key&&opts.generateIds){this.li.id=opts.idPrefix+data.key;}
|
||||
this.span=document.createElement("span");this.span.className=cn.title;this.li.appendChild(this.span);if(!parent.ul){parent.ul=document.createElement("ul");parent.ul.style.display="none";parent.li.appendChild(parent.ul);}
|
||||
parent.ul.appendChild(this.li);}
|
||||
this.span.innerHTML=this._getInnerHtml();var cnList=[];cnList.push(cn.node);if(data.isFolder){cnList.push(cn.folder);}
|
||||
if(this.bExpanded){cnList.push(cn.expanded);}
|
||||
if(this.hasChildren()!==false){cnList.push(cn.hasChildren);}
|
||||
if(data.isLazy&&this.childList===null){cnList.push(cn.lazy);}
|
||||
if(isLastSib){cnList.push(cn.lastsib);}
|
||||
if(this.bSelected){cnList.push(cn.selected);}
|
||||
if(this.hasSubSel){cnList.push(cn.partsel);}
|
||||
if(tree.activeNode===this){cnList.push(cn.active);}
|
||||
if(data.addClass){cnList.push(data.addClass);}
|
||||
cnList.push(cn.combinedExpanderPrefix
|
||||
+(this.bExpanded?"e":"c")
|
||||
+(data.isLazy&&this.childList===null?"d":"")
|
||||
+(isLastSib?"l":""));cnList.push(cn.combinedIconPrefix
|
||||
+(this.bExpanded?"e":"c")
|
||||
+(data.isFolder?"f":""));this.span.className=cnList.join(" ");this.li.className=isLastSib?cn.lastsib:"";if(opts.onRender){opts.onRender.call(tree,this,this.span);}}
|
||||
if((this.bExpanded||includeInvisible===true)&&this.childList){for(var i=0,l=this.childList.length;i<l;i++){this.childList[i].render(false,includeInvisible);}
|
||||
this._fixOrder();}
|
||||
if(this.ul){var isHidden=(this.ul.style.display==="none");var isExpanded=!!this.bExpanded;if(useEffects&&opts.fx&&(isHidden===isExpanded)){var duration=opts.fx.duration||200;$(this.ul).animate(opts.fx,duration);}else{this.ul.style.display=(this.bExpanded||!parent)?"":"none";}}},getKeyPath:function(excludeSelf){var path=[];this.visitParents(function(node){if(node.parent){path.unshift(node.data.key);}},!excludeSelf);return"/"+path.join(this.tree.options.keyPathSeparator);},getParent:function(){return this.parent;},getChildren:function(){return this.childList;},hasChildren:function(){if(this.data.isLazy){if(this.childList===null||this.childList===undefined){return undefined;}else if(this.childList.length===0){return false;}else if(this.childList.length===1&&this.childList[0].isStatusNode()){return undefined;}
|
||||
return true;}
|
||||
return!!this.childList;},isFirstSibling:function(){var p=this.parent;return!p||p.childList[0]===this;},isLastSibling:function(){var p=this.parent;return!p||p.childList[p.childList.length-1]===this;},getPrevSibling:function(){if(!this.parent){return null;}
|
||||
var ac=this.parent.childList;for(var i=1,l=ac.length;i<l;i++){if(ac[i]===this){return ac[i-1];}}
|
||||
return null;},getNextSibling:function(){if(!this.parent){return null;}
|
||||
var ac=this.parent.childList;for(var i=0,l=ac.length-1;i<l;i++){if(ac[i]===this){return ac[i+1];}}
|
||||
return null;},isStatusNode:function(){return(this.data.isStatusNode===true);},isChildOf:function(otherNode){return(this.parent&&this.parent===otherNode);},isDescendantOf:function(otherNode){if(!otherNode){return false;}
|
||||
var p=this.parent;while(p){if(p===otherNode){return true;}
|
||||
p=p.parent;}
|
||||
return false;},countChildren:function(){var cl=this.childList;if(!cl){return 0;}
|
||||
var n=cl.length;for(var i=0,l=n;i<l;i++){var child=cl[i];n+=child.countChildren();}
|
||||
return n;},sortChildren:function(cmp,deep){var cl=this.childList;if(!cl){return;}
|
||||
cmp=cmp||function(a,b){return a.data.title===b.data.title?0:a.data.title>b.data.title?1:-1;};cl.sort(cmp);if(deep){for(var i=0,l=cl.length;i<l;i++){if(cl[i].childList){cl[i].sortChildren(cmp,"$norender$");}}}
|
||||
if(deep!=="$norender$"){this.render();}},_setStatusNode:function(data){var firstChild=(this.childList?this.childList[0]:null);if(!data){if(firstChild&&firstChild.isStatusNode()){try{if(this.ul){this.ul.removeChild(firstChild.li);}}catch(e){}
|
||||
if(this.childList.length===1){this.childList=[];}else{this.childList.shift();}}}else if(firstChild){data.isStatusNode=true;data.key="_statusNode";firstChild.data=data;firstChild.render();}else{data.isStatusNode=true;data.key="_statusNode";firstChild=this.addChild(data);}},setLazyNodeStatus:function(lts,opts){var tooltip=(opts&&opts.tooltip)?opts.tooltip:null;var info=(opts&&opts.info)?" ("+opts.info+")":"";switch(lts){case DTNodeStatus_Ok:this._setStatusNode(null);$(this.span).removeClass(this.tree.options.classNames.nodeLoading);this.isLoading=false;if(this.tree.options.autoFocus){if(this===this.tree.tnRoot&&this.childList&&this.childList.length>0){this.childList[0].focus();}else{this.focus();}}
|
||||
break;case DTNodeStatus_Loading:this.isLoading=true;$(this.span).addClass(this.tree.options.classNames.nodeLoading);if(!this.parent){this._setStatusNode({title:this.tree.options.strings.loading+info,tooltip:tooltip,addClass:this.tree.options.classNames.nodeWait});}
|
||||
break;case DTNodeStatus_Error:this.isLoading=false;this._setStatusNode({title:this.tree.options.strings.loadError+info,tooltip:tooltip,addClass:this.tree.options.classNames.nodeError});break;default:throw"Bad LazyNodeStatus: '"+lts+"'.";}},_parentList:function(includeRoot,includeSelf){var l=[];var dtn=includeSelf?this:this.parent;while(dtn){if(includeRoot||dtn.parent){l.unshift(dtn);}
|
||||
dtn=dtn.parent;}
|
||||
return l;},getLevel:function(){var level=0;var dtn=this.parent;while(dtn){level++;dtn=dtn.parent;}
|
||||
return level;},_getTypeForOuterNodeEvent:function(event){var cns=this.tree.options.classNames;var target=event.target;if(target.className.indexOf(cns.node)<0){return null;}
|
||||
var eventX=event.pageX-target.offsetLeft;var eventY=event.pageY-target.offsetTop;for(var i=0,l=target.childNodes.length;i<l;i++){var cn=target.childNodes[i];var x=cn.offsetLeft-target.offsetLeft;var y=cn.offsetTop-target.offsetTop;var nx=cn.clientWidth,ny=cn.clientHeight;if(eventX>=x&&eventX<=(x+nx)&&eventY>=y&&eventY<=(y+ny)){if(cn.className==cns.title){return"title";}else if(cn.className==cns.expander){return"expander";}else if(cn.className==cns.checkbox){return"checkbox";}else if(cn.className==cns.nodeIcon){return"icon";}}}
|
||||
return"prefix";},getEventTargetType:function(event){var tcn=event&&event.target?event.target.className:"";var cns=this.tree.options.classNames;if(tcn===cns.title){return"title";}else if(tcn===cns.expander){return"expander";}else if(tcn===cns.checkbox){return"checkbox";}else if(tcn===cns.nodeIcon){return"icon";}else if(tcn===cns.empty||tcn===cns.vline||tcn===cns.connector){return"prefix";}else if(tcn.indexOf(cns.node)>=0){return this._getTypeForOuterNodeEvent(event);}
|
||||
return null;},isVisible:function(){var parents=this._parentList(true,false);for(var i=0,l=parents.length;i<l;i++){if(!parents[i].bExpanded){return false;}}
|
||||
return true;},makeVisible:function(){var parents=this._parentList(true,false);for(var i=0,l=parents.length;i<l;i++){parents[i]._expand(true);}},focus:function(){this.makeVisible();try{$(this.span).find(">a").focus();}catch(e){}},isFocused:function(){return(this.tree.tnFocused===this);},_activate:function(flag,fireEvents){this.tree.logDebug("dtnode._activate(%o, fireEvents=%o) - %o",flag,fireEvents,this);var opts=this.tree.options;if(this.data.isStatusNode){return;}
|
||||
if(fireEvents&&opts.onQueryActivate&&opts.onQueryActivate.call(this.tree,flag,this)===false){return;}
|
||||
if(flag){if(this.tree.activeNode){if(this.tree.activeNode===this){return;}
|
||||
this.tree.activeNode.deactivate();}
|
||||
if(opts.activeVisible){this.makeVisible();}
|
||||
this.tree.activeNode=this;if(opts.persist){$.cookie(opts.cookieId+"-active",this.data.key,opts.cookie);}
|
||||
this.tree.persistence.activeKey=this.data.key;$(this.span).addClass(opts.classNames.active);if(fireEvents&&opts.onActivate){opts.onActivate.call(this.tree,this);}}else{if(this.tree.activeNode===this){if(opts.onQueryActivate&&opts.onQueryActivate.call(this.tree,false,this)===false){return;}
|
||||
$(this.span).removeClass(opts.classNames.active);if(opts.persist){$.cookie(opts.cookieId+"-active","",opts.cookie);}
|
||||
this.tree.persistence.activeKey=null;this.tree.activeNode=null;if(fireEvents&&opts.onDeactivate){opts.onDeactivate.call(this.tree,this);}}}},activate:function(){this._activate(true,true);},activateSilently:function(){this._activate(true,false);},deactivate:function(){this._activate(false,true);},isActive:function(){return(this.tree.activeNode===this);},_userActivate:function(){var activate=true;var expand=false;if(this.data.isFolder){switch(this.tree.options.clickFolderMode){case 2:activate=false;expand=true;break;case 3:activate=expand=true;break;}}
|
||||
if(this.parent===null){expand=false;}
|
||||
if(expand){this.toggleExpand();this.focus();}
|
||||
if(activate){this.activate();}},_setSubSel:function(hasSubSel){if(hasSubSel){this.hasSubSel=true;$(this.span).addClass(this.tree.options.classNames.partsel);}else{this.hasSubSel=false;$(this.span).removeClass(this.tree.options.classNames.partsel);}},_fixSelectionState:function(){var p,i,l;if(this.bSelected){this.visit(function(node){node.parent._setSubSel(true);node._select(true,false,false);});p=this.parent;while(p){p._setSubSel(true);var allChildsSelected=true;for(i=0,l=p.childList.length;i<l;i++){var n=p.childList[i];if(!n.bSelected&&!n.data.isStatusNode){allChildsSelected=false;break;}}
|
||||
if(allChildsSelected){p._select(true,false,false);}
|
||||
p=p.parent;}}else{this._setSubSel(false);this.visit(function(node){node._setSubSel(false);node._select(false,false,false);});p=this.parent;while(p){p._select(false,false,false);var isPartSel=false;for(i=0,l=p.childList.length;i<l;i++){if(p.childList[i].bSelected||p.childList[i].hasSubSel){isPartSel=true;break;}}
|
||||
p._setSubSel(isPartSel);p=p.parent;}}},_select:function(sel,fireEvents,deep){var opts=this.tree.options;if(this.data.isStatusNode){return;}
|
||||
if(this.bSelected===sel){return;}
|
||||
if(fireEvents&&opts.onQuerySelect&&opts.onQuerySelect.call(this.tree,sel,this)===false){return;}
|
||||
if(opts.selectMode==1&&sel){this.tree.visit(function(node){if(node.bSelected){node._select(false,false,false);return false;}});}
|
||||
this.bSelected=sel;if(sel){if(opts.persist){this.tree.persistence.addSelect(this.data.key);}
|
||||
$(this.span).addClass(opts.classNames.selected);if(deep&&opts.selectMode===3){this._fixSelectionState();}
|
||||
if(fireEvents&&opts.onSelect){opts.onSelect.call(this.tree,true,this);}}else{if(opts.persist){this.tree.persistence.clearSelect(this.data.key);}
|
||||
$(this.span).removeClass(opts.classNames.selected);if(deep&&opts.selectMode===3){this._fixSelectionState();}
|
||||
if(fireEvents&&opts.onSelect){opts.onSelect.call(this.tree,false,this);}}},select:function(sel){if(this.data.unselectable){return this.bSelected;}
|
||||
return this._select(sel!==false,true,true);},toggleSelect:function(){return this.select(!this.bSelected);},isSelected:function(){return this.bSelected;},_loadContent:function(){try{var opts=this.tree.options;this.tree.logDebug("_loadContent: start - %o",this);this.setLazyNodeStatus(DTNodeStatus_Loading);if(true===opts.onLazyRead.call(this.tree,this)){this.setLazyNodeStatus(DTNodeStatus_Ok);this.tree.logDebug("_loadContent: succeeded - %o",this);}}catch(e){this.tree.logWarning("_loadContent: failed - %o",e);this.setLazyNodeStatus(DTNodeStatus_Error,{tooltip:""+e});}},_expand:function(bExpand,forceSync){if(this.bExpanded===bExpand){this.tree.logDebug("dtnode._expand(%o) IGNORED - %o",bExpand,this);return;}
|
||||
this.tree.logDebug("dtnode._expand(%o) - %o",bExpand,this);var opts=this.tree.options;if(!bExpand&&this.getLevel()<opts.minExpandLevel){this.tree.logDebug("dtnode._expand(%o) prevented collapse - %o",bExpand,this);return;}
|
||||
if(opts.onQueryExpand&&opts.onQueryExpand.call(this.tree,bExpand,this)===false){return;}
|
||||
this.bExpanded=bExpand;if(opts.persist){if(bExpand){this.tree.persistence.addExpand(this.data.key);}else{this.tree.persistence.clearExpand(this.data.key);}}
|
||||
var allowEffects=!(this.data.isLazy&&this.childList===null)&&!this.isLoading&&!forceSync;this.render(allowEffects);if(this.bExpanded&&this.parent&&opts.autoCollapse){var parents=this._parentList(false,true);for(var i=0,l=parents.length;i<l;i++){parents[i].collapseSiblings();}}
|
||||
if(opts.activeVisible&&this.tree.activeNode&&!this.tree.activeNode.isVisible()){this.tree.activeNode.deactivate();}
|
||||
if(bExpand&&this.data.isLazy&&this.childList===null&&!this.isLoading){this._loadContent();return;}
|
||||
if(opts.onExpand){opts.onExpand.call(this.tree,bExpand,this);}},expand:function(flag){flag=(flag!==false);if(!this.childList&&!this.data.isLazy&&flag){return;}else if(this.parent===null&&!flag){return;}
|
||||
this._expand(flag);},scheduleAction:function(mode,ms){if(this.tree.timer){clearTimeout(this.tree.timer);this.tree.logDebug("clearTimeout(%o)",this.tree.timer);}
|
||||
var self=this;switch(mode){case"cancel":break;case"expand":this.tree.timer=setTimeout(function(){self.tree.logDebug("setTimeout: trigger expand");self.expand(true);},ms);break;case"activate":this.tree.timer=setTimeout(function(){self.tree.logDebug("setTimeout: trigger activate");self.activate();},ms);break;default:throw"Invalid mode "+mode;}
|
||||
this.tree.logDebug("setTimeout(%s, %s): %s",mode,ms,this.tree.timer);},toggleExpand:function(){this.expand(!this.bExpanded);},collapseSiblings:function(){if(this.parent===null){return;}
|
||||
var ac=this.parent.childList;for(var i=0,l=ac.length;i<l;i++){if(ac[i]!==this&&ac[i].bExpanded){ac[i]._expand(false);}}},_onClick:function(event){var targetType=this.getEventTargetType(event);if(targetType==="expander"){this.toggleExpand();this.focus();}else if(targetType==="checkbox"){this.toggleSelect();this.focus();}else{this._userActivate();var aTag=this.span.getElementsByTagName("a");if(aTag[0]){if(!$.browser.msie){aTag[0].focus();}}else{return true;}}
|
||||
event.preventDefault();},_onDblClick:function(event){},_onKeydown:function(event){var handled=true,sib;switch(event.which){case 107:case 187:if(!this.bExpanded){this.toggleExpand();}
|
||||
break;case 109:case 189:if(this.bExpanded){this.toggleExpand();}
|
||||
break;case 32:this._userActivate();break;case 8:if(this.parent){this.parent.focus();}
|
||||
break;case 37:if(this.bExpanded){this.toggleExpand();this.focus();}else if(this.parent&&this.parent.parent){this.parent.focus();}
|
||||
break;case 39:if(!this.bExpanded&&(this.childList||this.data.isLazy)){this.toggleExpand();this.focus();}else if(this.childList){this.childList[0].focus();}
|
||||
break;case 38:sib=this.getPrevSibling();while(sib&&sib.bExpanded&&sib.childList){sib=sib.childList[sib.childList.length-1];}
|
||||
if(!sib&&this.parent&&this.parent.parent){sib=this.parent;}
|
||||
if(sib){sib.focus();}
|
||||
break;case 40:if(this.bExpanded&&this.childList){sib=this.childList[0];}else{var parents=this._parentList(false,true);for(var i=parents.length-1;i>=0;i--){sib=parents[i].getNextSibling();if(sib){break;}}}
|
||||
if(sib){sib.focus();}
|
||||
break;default:handled=false;}
|
||||
if(handled){event.preventDefault();}},_onKeypress:function(event){},_onFocus:function(event){var opts=this.tree.options;if(event.type=="blur"||event.type=="focusout"){if(opts.onBlur){opts.onBlur.call(this.tree,this);}
|
||||
if(this.tree.tnFocused){$(this.tree.tnFocused.span).removeClass(opts.classNames.focused);}
|
||||
this.tree.tnFocused=null;if(opts.persist){$.cookie(opts.cookieId+"-focus","",opts.cookie);}}else if(event.type=="focus"||event.type=="focusin"){if(this.tree.tnFocused&&this.tree.tnFocused!==this){this.tree.logDebug("dtnode.onFocus: out of sync: curFocus: %o",this.tree.tnFocused);$(this.tree.tnFocused.span).removeClass(opts.classNames.focused);}
|
||||
this.tree.tnFocused=this;if(opts.onFocus){opts.onFocus.call(this.tree,this);}
|
||||
$(this.tree.tnFocused.span).addClass(opts.classNames.focused);if(opts.persist){$.cookie(opts.cookieId+"-focus",this.data.key,opts.cookie);}}},visit:function(fn,includeSelf){var res=true;if(includeSelf===true){res=fn(this);if(res===false||res=="skip"){return res;}}
|
||||
if(this.childList){for(var i=0,l=this.childList.length;i<l;i++){res=this.childList[i].visit(fn,true);if(res===false){break;}}}
|
||||
return res;},visitParents:function(fn,includeSelf){if(includeSelf&&fn(this)===false){return false;}
|
||||
var p=this.parent;while(p){if(fn(p)===false){return false;}
|
||||
p=p.parent;}
|
||||
return true;},remove:function(){if(this===this.tree.root){throw"Cannot remove system root";}
|
||||
return this.parent.removeChild(this);},removeChild:function(tn){var ac=this.childList;if(ac.length==1){if(tn!==ac[0]){throw"removeChild: invalid child";}
|
||||
return this.removeChildren();}
|
||||
if(tn===this.tree.activeNode){tn.deactivate();}
|
||||
if(this.tree.options.persist){if(tn.bSelected){this.tree.persistence.clearSelect(tn.data.key);}
|
||||
if(tn.bExpanded){this.tree.persistence.clearExpand(tn.data.key);}}
|
||||
tn.removeChildren(true);this.ul.removeChild(tn.li);for(var i=0,l=ac.length;i<l;i++){if(ac[i]===tn){this.childList.splice(i,1);break;}}},removeChildren:function(isRecursiveCall,retainPersistence){this.tree.logDebug("%s.removeChildren(%o)",this,isRecursiveCall);var tree=this.tree;var ac=this.childList;if(ac){for(var i=0,l=ac.length;i<l;i++){var tn=ac[i];if(tn===tree.activeNode&&!retainPersistence){tn.deactivate();}
|
||||
if(this.tree.options.persist&&!retainPersistence){if(tn.bSelected){this.tree.persistence.clearSelect(tn.data.key);}
|
||||
if(tn.bExpanded){this.tree.persistence.clearExpand(tn.data.key);}}
|
||||
tn.removeChildren(true,retainPersistence);if(this.ul){this.ul.removeChild(tn.li);}}
|
||||
this.childList=null;}
|
||||
if(!isRecursiveCall){this.isLoading=false;this.render();}},setTitle:function(title){this.fromDict({title:title});},reload:function(force){throw"Use reloadChildren() instead";},reloadChildren:function(callback){if(this.parent===null){throw"Use tree.reload() instead";}else if(!this.data.isLazy){throw"node.reloadChildren() requires lazy nodes.";}
|
||||
if(callback){var self=this;var eventType="nodeLoaded.dynatree."+this.tree.$tree.attr("id")
|
||||
+"."+this.data.key;this.tree.$tree.bind(eventType,function(e,node,isOk){self.tree.$tree.unbind(eventType);self.tree.logInfo("loaded %o, %o, %o",e,node,isOk);if(node!==self){throw"got invalid load event";}
|
||||
callback.call(self.tree,node,isOk);});}
|
||||
this.removeChildren();this._loadContent();},_loadKeyPath:function(keyPath,callback){var tree=this.tree;tree.logDebug("%s._loadKeyPath(%s)",this,keyPath);if(keyPath===""){throw"Key path must not be empty";}
|
||||
var segList=keyPath.split(tree.options.keyPathSeparator);if(segList[0]===""){throw"Key path must be relative (don't start with '/')";}
|
||||
var seg=segList.shift();for(var i=0,l=this.childList.length;i<l;i++){var child=this.childList[i];if(child.data.key===seg){if(segList.length===0){callback.call(tree,child,"ok");}else if(child.data.isLazy&&(child.childList===null||child.childList===undefined)){tree.logDebug("%s._loadKeyPath(%s) -> reloading %s...",this,keyPath,child);var self=this;child.reloadChildren(function(node,isOk){if(isOk){tree.logDebug("%s._loadKeyPath(%s) -> reloaded %s.",node,keyPath,node);callback.call(tree,child,"loaded");node._loadKeyPath(segList.join(tree.options.keyPathSeparator),callback);}else{tree.logWarning("%s._loadKeyPath(%s) -> reloadChildren() failed.",self,keyPath);callback.call(tree,child,"error");}});}else{callback.call(tree,child,"loaded");child._loadKeyPath(segList.join(tree.options.keyPathSeparator),callback);}
|
||||
return;}}
|
||||
tree.logWarning("Node not found: "+seg);return;},resetLazy:function(){if(this.parent===null){throw"Use tree.reload() instead";}else if(!this.data.isLazy){throw"node.resetLazy() requires lazy nodes.";}
|
||||
this.expand(false);this.removeChildren();},_addChildNode:function(dtnode,beforeNode){var tree=this.tree;var opts=tree.options;var pers=tree.persistence;dtnode.parent=this;if(this.childList===null){this.childList=[];}else if(!beforeNode){if(this.childList.length>0){$(this.childList[this.childList.length-1].span).removeClass(opts.classNames.lastsib);}}
|
||||
if(beforeNode){var iBefore=$.inArray(beforeNode,this.childList);if(iBefore<0){throw"<beforeNode> must be a child of <this>";}
|
||||
this.childList.splice(iBefore,0,dtnode);}else{this.childList.push(dtnode);}
|
||||
var isInitializing=tree.isInitializing();if(opts.persist&&pers.cookiesFound&&isInitializing){if(pers.activeKey==dtnode.data.key){tree.activeNode=dtnode;}
|
||||
if(pers.focusedKey==dtnode.data.key){tree.focusNode=dtnode;}
|
||||
dtnode.bExpanded=($.inArray(dtnode.data.key,pers.expandedKeyList)>=0);dtnode.bSelected=($.inArray(dtnode.data.key,pers.selectedKeyList)>=0);}else{if(dtnode.data.activate){tree.activeNode=dtnode;if(opts.persist){pers.activeKey=dtnode.data.key;}}
|
||||
if(dtnode.data.focus){tree.focusNode=dtnode;if(opts.persist){pers.focusedKey=dtnode.data.key;}}
|
||||
dtnode.bExpanded=(dtnode.data.expand===true);if(dtnode.bExpanded&&opts.persist){pers.addExpand(dtnode.data.key);}
|
||||
dtnode.bSelected=(dtnode.data.select===true);if(dtnode.bSelected&&opts.persist){pers.addSelect(dtnode.data.key);}}
|
||||
if(opts.minExpandLevel>=dtnode.getLevel()){this.bExpanded=true;}
|
||||
if(dtnode.bSelected&&opts.selectMode==3){var p=this;while(p){if(!p.hasSubSel){p._setSubSel(true);}
|
||||
p=p.parent;}}
|
||||
if(tree.bEnableUpdate){this.render();}
|
||||
return dtnode;},addChild:function(obj,beforeNode){if(typeof(obj)=="string"){throw"Invalid data type for "+obj;}else if(!obj||obj.length===0){return;}else if(obj instanceof DynaTreeNode){return this._addChildNode(obj,beforeNode);}
|
||||
if(!obj.length){obj=[obj];}
|
||||
var prevFlag=this.tree.enableUpdate(false);var tnFirst=null;for(var i=0,l=obj.length;i<l;i++){var data=obj[i];var dtnode=this._addChildNode(new DynaTreeNode(this,this.tree,data),beforeNode);if(!tnFirst){tnFirst=dtnode;}
|
||||
if(data.children){dtnode.addChild(data.children,null);}}
|
||||
this.tree.enableUpdate(prevFlag);return tnFirst;},append:function(obj){this.tree.logWarning("node.append() is deprecated (use node.addChild() instead).");return this.addChild(obj,null);},appendAjax:function(ajaxOptions){var self=this;this.removeChildren(false,true);this.setLazyNodeStatus(DTNodeStatus_Loading);if(ajaxOptions.debugLazyDelay){var ms=ajaxOptions.debugLazyDelay;ajaxOptions.debugLazyDelay=0;this.tree.logInfo("appendAjax: waiting for debugLazyDelay "+ms);setTimeout(function(){self.appendAjax(ajaxOptions);},ms);return;}
|
||||
var orgSuccess=ajaxOptions.success;var orgError=ajaxOptions.error;var eventType="nodeLoaded.dynatree."+this.tree.$tree.attr("id")
|
||||
+"."+this.data.key;var options=$.extend({},this.tree.options.ajaxDefaults,ajaxOptions,{success:function(data,textStatus){var prevPhase=self.tree.phase;self.tree.phase="init";if(options.postProcess){data=options.postProcess.call(this,data,this.dataType);}
|
||||
if(!$.isArray(data)||data.length!==0){self.addChild(data,null);}
|
||||
self.tree.phase="postInit";if(orgSuccess){orgSuccess.call(options,self);}
|
||||
self.tree.logInfo("trigger "+eventType);self.tree.$tree.trigger(eventType,[self,true]);self.tree.phase=prevPhase;self.setLazyNodeStatus(DTNodeStatus_Ok);if($.isArray(data)&&data.length===0){self.childList=[];self.render();}},error:function(XMLHttpRequest,textStatus,errorThrown){self.tree.logWarning("appendAjax failed:",textStatus,":\n",XMLHttpRequest,"\n",errorThrown);if(orgError){orgError.call(options,self,XMLHttpRequest,textStatus,errorThrown);}
|
||||
self.tree.$tree.trigger(eventType,[self,false]);self.setLazyNodeStatus(DTNodeStatus_Error,{info:textStatus,tooltip:""+errorThrown});}});$.ajax(options);},move:function(targetNode,mode){var pos;if(this===targetNode){return;}
|
||||
if(!this.parent){throw"Cannot move system root";}
|
||||
if(mode===undefined||mode=="over"){mode="child";}
|
||||
var prevParent=this.parent;var targetParent=(mode==="child")?targetNode:targetNode.parent;if(targetParent.isDescendantOf(this)){throw"Cannot move a node to it's own descendant";}
|
||||
if(this.parent.childList.length==1){this.parent.childList=null;this.parent.bExpanded=false;}else{pos=$.inArray(this,this.parent.childList);if(pos<0){throw"Internal error";}
|
||||
this.parent.childList.splice(pos,1);}
|
||||
this.parent.ul.removeChild(this.li);this.parent=targetParent;if(targetParent.hasChildren()){switch(mode){case"child":targetParent.childList.push(this);break;case"before":pos=$.inArray(targetNode,targetParent.childList);if(pos<0){throw"Internal error";}
|
||||
targetParent.childList.splice(pos,0,this);break;case"after":pos=$.inArray(targetNode,targetParent.childList);if(pos<0){throw"Internal error";}
|
||||
targetParent.childList.splice(pos+1,0,this);break;default:throw"Invalid mode "+mode;}}else{targetParent.childList=[this];if(!targetParent.ul){targetParent.ul=document.createElement("ul");targetParent.ul.style.display="none";targetParent.li.appendChild(targetParent.ul);}}
|
||||
targetParent.ul.appendChild(this.li);if(this.tree!==targetNode.tree){this.visit(function(node){node.tree=targetNode.tree;},null,true);throw"Not yet implemented.";}
|
||||
if(!prevParent.isDescendantOf(targetParent)){prevParent.render();}
|
||||
if(!targetParent.isDescendantOf(prevParent)){targetParent.render();}},lastentry:undefined};var DynaTreeStatus=Class.create();DynaTreeStatus._getTreePersistData=function(cookieId,cookieOpts){var ts=new DynaTreeStatus(cookieId,cookieOpts);ts.read();return ts.toDict();};getDynaTreePersistData=DynaTreeStatus._getTreePersistData;DynaTreeStatus.prototype={initialize:function(cookieId,cookieOpts){this._log("DynaTreeStatus: initialize");if(cookieId===undefined){cookieId=$.ui.dynatree.prototype.options.cookieId;}
|
||||
cookieOpts=$.extend({},$.ui.dynatree.prototype.options.cookie,cookieOpts);this.cookieId=cookieId;this.cookieOpts=cookieOpts;this.cookiesFound=undefined;this.activeKey=null;this.focusedKey=null;this.expandedKeyList=null;this.selectedKeyList=null;},_log:function(msg){Array.prototype.unshift.apply(arguments,["debug"]);_log.apply(this,arguments);},read:function(){this._log("DynaTreeStatus: read");this.cookiesFound=false;var cookie=$.cookie(this.cookieId+"-active");this.activeKey=(cookie===null)?"":cookie;if(cookie!==null){this.cookiesFound=true;}
|
||||
cookie=$.cookie(this.cookieId+"-focus");this.focusedKey=(cookie===null)?"":cookie;if(cookie!==null){this.cookiesFound=true;}
|
||||
cookie=$.cookie(this.cookieId+"-expand");this.expandedKeyList=(cookie===null)?[]:cookie.split(",");if(cookie!==null){this.cookiesFound=true;}
|
||||
cookie=$.cookie(this.cookieId+"-select");this.selectedKeyList=(cookie===null)?[]:cookie.split(",");if(cookie!==null){this.cookiesFound=true;}},write:function(){this._log("DynaTreeStatus: write");$.cookie(this.cookieId+"-active",(this.activeKey===null)?"":this.activeKey,this.cookieOpts);$.cookie(this.cookieId+"-focus",(this.focusedKey===null)?"":this.focusedKey,this.cookieOpts);$.cookie(this.cookieId+"-expand",(this.expandedKeyList===null)?"":this.expandedKeyList.join(","),this.cookieOpts);$.cookie(this.cookieId+"-select",(this.selectedKeyList===null)?"":this.selectedKeyList.join(","),this.cookieOpts);},addExpand:function(key){this._log("addExpand(%o)",key);if($.inArray(key,this.expandedKeyList)<0){this.expandedKeyList.push(key);$.cookie(this.cookieId+"-expand",this.expandedKeyList.join(","),this.cookieOpts);}},clearExpand:function(key){this._log("clearExpand(%o)",key);var idx=$.inArray(key,this.expandedKeyList);if(idx>=0){this.expandedKeyList.splice(idx,1);$.cookie(this.cookieId+"-expand",this.expandedKeyList.join(","),this.cookieOpts);}},addSelect:function(key){this._log("addSelect(%o)",key);if($.inArray(key,this.selectedKeyList)<0){this.selectedKeyList.push(key);$.cookie(this.cookieId+"-select",this.selectedKeyList.join(","),this.cookieOpts);}},clearSelect:function(key){this._log("clearSelect(%o)",key);var idx=$.inArray(key,this.selectedKeyList);if(idx>=0){this.selectedKeyList.splice(idx,1);$.cookie(this.cookieId+"-select",this.selectedKeyList.join(","),this.cookieOpts);}},isReloading:function(){return this.cookiesFound===true;},toDict:function(){return{cookiesFound:this.cookiesFound,activeKey:this.activeKey,focusedKey:this.activeKey,expandedKeyList:this.expandedKeyList,selectedKeyList:this.selectedKeyList};},lastentry:undefined};var DynaTree=Class.create();DynaTree.version="$Version: 1.1.1$";DynaTree.prototype={initialize:function($widget){this.phase="init";this.$widget=$widget;this.options=$widget.options;this.$tree=$widget.element;this.timer=null;this.divTree=this.$tree.get(0);_initDragAndDrop(this);},_load:function(callback){var $widget=this.$widget;var opts=this.options;this.bEnableUpdate=true;this._nodeCount=1;this.activeNode=null;this.focusNode=null;if(opts.rootVisible!==undefined){_log("warn","Option 'rootVisible' is no longer supported.");}
|
||||
if(opts.minExpandLevel<1){_log("warn","Option 'minExpandLevel' must be >= 1.");opts.minExpandLevel=1;}
|
||||
if(opts.classNames!==$.ui.dynatree.prototype.options.classNames){opts.classNames=$.extend({},$.ui.dynatree.prototype.options.classNames,opts.classNames);}
|
||||
if(opts.ajaxDefaults!==$.ui.dynatree.prototype.options.ajaxDefaults){opts.ajaxDefaults=$.extend({},$.ui.dynatree.prototype.options.ajaxDefaults,opts.ajaxDefaults);}
|
||||
if(opts.dnd!==$.ui.dynatree.prototype.options.dnd){opts.dnd=$.extend({},$.ui.dynatree.prototype.options.dnd,opts.dnd);}
|
||||
if(!opts.imagePath){$("script").each(function(){var _rexDtLibName=/.*dynatree[^\/]*\.js$/i;if(this.src.search(_rexDtLibName)>=0){if(this.src.indexOf("/")>=0){opts.imagePath=this.src.slice(0,this.src.lastIndexOf("/"))+"/skin/";}else{opts.imagePath="skin/";}
|
||||
logMsg("Guessing imagePath from '%s': '%s'",this.src,opts.imagePath);return false;}});}
|
||||
this.persistence=new DynaTreeStatus(opts.cookieId,opts.cookie);if(opts.persist){if(!$.cookie){_log("warn","Please include jquery.cookie.js to use persistence.");}
|
||||
this.persistence.read();}
|
||||
this.logDebug("DynaTree.persistence: %o",this.persistence.toDict());this.cache={tagEmpty:"<span class='"+opts.classNames.empty+"'></span>",tagVline:"<span class='"+opts.classNames.vline+"'></span>",tagExpander:"<span class='"+opts.classNames.expander+"'></span>",tagConnector:"<span class='"+opts.classNames.connector+"'></span>",tagNodeIcon:"<span class='"+opts.classNames.nodeIcon+"'></span>",tagCheckbox:"<span class='"+opts.classNames.checkbox+"'></span>",lastentry:undefined};if(opts.children||(opts.initAjax&&opts.initAjax.url)||opts.initId){$(this.divTree).empty();}
|
||||
var $ulInitialize=this.$tree.find(">ul:first").hide();this.tnRoot=new DynaTreeNode(null,this,{});this.tnRoot.bExpanded=true;this.tnRoot.render();this.divTree.appendChild(this.tnRoot.ul);var root=this.tnRoot;var isReloading=(opts.persist&&this.persistence.isReloading());var isLazy=false;var prevFlag=this.enableUpdate(false);this.logDebug("Dynatree._load(): read tree structure...");if(opts.children){root.addChild(opts.children);}else if(opts.initAjax&&opts.initAjax.url){isLazy=true;root.data.isLazy=true;this._reloadAjax(callback);}else if(opts.initId){this._createFromTag(root,$("#"+opts.initId));}else{this._createFromTag(root,$ulInitialize);$ulInitialize.remove();}
|
||||
this._checkConsistency();this.logDebug("Dynatree._load(): render nodes...");this.enableUpdate(prevFlag);this.logDebug("Dynatree._load(): bind events...");this.$widget.bind();this.logDebug("Dynatree._load(): postInit...");this.phase="postInit";if(opts.persist){this.persistence.write();}
|
||||
if(this.focusNode&&this.focusNode.isVisible()){this.logDebug("Focus on init: %o",this.focusNode);this.focusNode.focus();}
|
||||
if(!isLazy&&opts.onPostInit){opts.onPostInit.call(this,isReloading,false);}
|
||||
this.phase="idle";},_reloadAjax:function(callback){var opts=this.options;if(!opts.initAjax||!opts.initAjax.url){throw"tree.reload() requires 'initAjax' mode.";}
|
||||
var pers=this.persistence;var ajaxOpts=$.extend({},opts.initAjax);if(ajaxOpts.addActiveKey){ajaxOpts.data.activeKey=pers.activeKey;}
|
||||
if(ajaxOpts.addFocusedKey){ajaxOpts.data.focusedKey=pers.focusedKey;}
|
||||
if(ajaxOpts.addExpandedKeyList){ajaxOpts.data.expandedKeyList=pers.expandedKeyList.join(",");}
|
||||
if(ajaxOpts.addSelectedKeyList){ajaxOpts.data.selectedKeyList=pers.selectedKeyList.join(",");}
|
||||
if(opts.onPostInit){if(ajaxOpts.success){this.logWarning("initAjax: success callback is ignored when onPostInit was specified.");}
|
||||
if(ajaxOpts.error){this.logWarning("initAjax: error callback is ignored when onPostInit was specified.");}
|
||||
var isReloading=pers.isReloading();ajaxOpts.success=function(dtnode){opts.onPostInit.call(dtnode.tree,isReloading,false);if(callback){callback.call(dtnode.tree,"ok");}};ajaxOpts.error=function(dtnode){opts.onPostInit.call(dtnode.tree,isReloading,true);if(callback){callback.call(dtnode.tree,"error");}};}
|
||||
this.logDebug("Dynatree._init(): send Ajax request...");this.tnRoot.appendAjax(ajaxOpts);},toString:function(){return"Dynatree '"+this.$tree.attr("id")+"'";},toDict:function(){return this.tnRoot.toDict(true);},serializeArray:function(stopOnParents){var nodeList=this.getSelectedNodes(stopOnParents),name=this.$tree.attr("name")||this.$tree.attr("id"),arr=[];for(var i=0,l=nodeList.length;i<l;i++){arr.push({name:name,value:nodeList[i].data.key});}
|
||||
return arr;},getPersistData:function(){return this.persistence.toDict();},logDebug:function(msg){if(this.options.debugLevel>=2){Array.prototype.unshift.apply(arguments,["debug"]);_log.apply(this,arguments);}},logInfo:function(msg){if(this.options.debugLevel>=1){Array.prototype.unshift.apply(arguments,["info"]);_log.apply(this,arguments);}},logWarning:function(msg){Array.prototype.unshift.apply(arguments,["warn"]);_log.apply(this,arguments);},isInitializing:function(){return(this.phase=="init"||this.phase=="postInit");},isReloading:function(){return(this.phase=="init"||this.phase=="postInit")&&this.options.persist&&this.persistence.cookiesFound;},isUserEvent:function(){return(this.phase=="userEvent");},redraw:function(){this.tnRoot.render(false,false);},renderInvisibleNodes:function(){this.tnRoot.render(false,true);},reload:function(callback){this._load(callback);},getRoot:function(){return this.tnRoot;},enable:function(){this.$widget.enable();},disable:function(){this.$widget.disable();},getNodeByKey:function(key){var el=document.getElementById(this.options.idPrefix+key);if(el){return el.dtnode?el.dtnode:null;}
|
||||
var match=null;this.visit(function(node){if(node.data.key==key){match=node;return false;}},true);return match;},getActiveNode:function(){return this.activeNode;},reactivate:function(setFocus){var node=this.activeNode;if(node){this.activeNode=null;node.activate();if(setFocus){node.focus();}}},getSelectedNodes:function(stopOnParents){var nodeList=[];this.tnRoot.visit(function(node){if(node.bSelected){nodeList.push(node);if(stopOnParents===true){return"skip";}}});return nodeList;},activateKey:function(key){var dtnode=(key===null)?null:this.getNodeByKey(key);if(!dtnode){if(this.activeNode){this.activeNode.deactivate();}
|
||||
this.activeNode=null;return null;}
|
||||
dtnode.focus();dtnode.activate();return dtnode;},loadKeyPath:function(keyPath,callback){var segList=keyPath.split(this.options.keyPathSeparator);if(segList[0]===""){segList.shift();}
|
||||
if(segList[0]==this.tnRoot.data.key){this.logDebug("Removed leading root key.");segList.shift();}
|
||||
keyPath=segList.join(this.options.keyPathSeparator);return this.tnRoot._loadKeyPath(keyPath,callback);},selectKey:function(key,select){var dtnode=this.getNodeByKey(key);if(!dtnode){return null;}
|
||||
dtnode.select(select);return dtnode;},enableUpdate:function(bEnable){if(this.bEnableUpdate==bEnable){return bEnable;}
|
||||
this.bEnableUpdate=bEnable;if(bEnable){this.redraw();}
|
||||
return!bEnable;},count:function(){return this.tnRoot.countChildren();},visit:function(fn,includeRoot){return this.tnRoot.visit(fn,includeRoot);},_createFromTag:function(parentTreeNode,$ulParent){var self=this;$ulParent.find(">li").each(function(){var $li=$(this);var $liSpan=$li.find(">span:first");var title;if($liSpan.length){title=$liSpan.html();}else{title=$li.html();var iPos=title.search(/<ul/i);if(iPos>=0){title=$.trim(title.substring(0,iPos));}else{title=$.trim(title);}}
|
||||
var data={title:title,isFolder:$li.hasClass("folder"),isLazy:$li.hasClass("lazy"),expand:$li.hasClass("expanded"),select:$li.hasClass("selected"),activate:$li.hasClass("active"),focus:$li.hasClass("focused"),noLink:$li.hasClass("noLink")};if($li.attr("title")){data.tooltip=$li.attr("title");}
|
||||
if($li.attr("id")){data.key=$li.attr("id");}
|
||||
if($li.attr("data")){var dataAttr=$.trim($li.attr("data"));if(dataAttr){if(dataAttr.charAt(0)!="{"){dataAttr="{"+dataAttr+"}";}
|
||||
try{$.extend(data,eval("("+dataAttr+")"));}catch(e){throw("Error parsing node data: "+e+"\ndata:\n'"+dataAttr+"'");}}}
|
||||
var childNode=parentTreeNode.addChild(data);var $ul=$li.find(">ul:first");if($ul.length){self._createFromTag(childNode,$ul);}});},_checkConsistency:function(){},_setDndStatus:function(sourceNode,targetNode,helper,hitMode,accept){var $source=sourceNode?$(sourceNode.span):null;var $target=$(targetNode.span);if(!this.$dndMarker){this.$dndMarker=$("<div id='dynatree-drop-marker'></div>").hide().prependTo($(this.divTree).parent());}
|
||||
if(hitMode==="after"||hitMode==="before"||hitMode==="over"){var pos=$target.position();switch(hitMode){case"before":this.$dndMarker.removeClass("dynatree-drop-after dynatree-drop-over");this.$dndMarker.addClass("dynatree-drop-before");pos.top-=8;break;case"after":this.$dndMarker.removeClass("dynatree-drop-before dynatree-drop-over");this.$dndMarker.addClass("dynatree-drop-after");pos.top+=8;break;default:this.$dndMarker.removeClass("dynatree-drop-after dynatree-drop-before");this.$dndMarker.addClass("dynatree-drop-over");$target.addClass("dynatree-drop-target");pos.left+=8;}
|
||||
this.$dndMarker.css({"left":(pos.left)+"px","top":(pos.top)+"px"}).show();}else{$target.removeClass("dynatree-drop-target");this.$dndMarker.hide();}
|
||||
if(hitMode==="after"){$target.addClass("dynatree-drop-after");}else{$target.removeClass("dynatree-drop-after");}
|
||||
if(hitMode==="before"){$target.addClass("dynatree-drop-before");}else{$target.removeClass("dynatree-drop-before");}
|
||||
if(accept===true){if($source){$source.addClass("dynatree-drop-accept");}
|
||||
$target.addClass("dynatree-drop-accept");helper.addClass("dynatree-drop-accept");}else{if($source){$source.removeClass("dynatree-drop-accept");}
|
||||
$target.removeClass("dynatree-drop-accept");helper.removeClass("dynatree-drop-accept");}
|
||||
if(accept===false){if($source){$source.addClass("dynatree-drop-reject");}
|
||||
$target.addClass("dynatree-drop-reject");helper.addClass("dynatree-drop-reject");}else{if($source){$source.removeClass("dynatree-drop-reject");}
|
||||
$target.removeClass("dynatree-drop-reject");helper.removeClass("dynatree-drop-reject");}},_onDragEvent:function(eventName,node,otherNode,event,ui,draggable){var opts=this.options;var dnd=this.options.dnd;var res=null;var nodeTag=$(node.span);var hitMode;switch(eventName){case"helper":var helper=$("<div class='dynatree-drag-helper'><span class='dynatree-drag-helper-img' /></div>").append($(event.target).closest('a').clone());helper.data("dtSourceNode",node);res=helper;break;case"start":if(node.isStatusNode()){res=false;}else if(dnd.onDragStart){res=dnd.onDragStart(node);}
|
||||
if(res===false){this.logDebug("tree.onDragStart() cancelled");ui.helper.trigger("mouseup");ui.helper.hide();}else{nodeTag.addClass("dynatree-drag-source");}
|
||||
break;case"enter":res=dnd.onDragEnter?dnd.onDragEnter(node,otherNode):null;res={over:(res!==false)&&((res===true)||(res==="over")||$.inArray("over",res)>=0),before:(res!==false)&&((res===true)||(res==="before")||$.inArray("before",res)>=0),after:(res!==false)&&((res===true)||(res==="after")||$.inArray("after",res)>=0)};ui.helper.data("enterResponse",res);break;case"over":var enterResponse=ui.helper.data("enterResponse");hitMode=null;if(enterResponse===false){break;}else if(typeof enterResponse==="string"){hitMode=enterResponse;}else{var nodeOfs=nodeTag.offset();var relPos={x:event.pageX-nodeOfs.left,y:event.pageY-nodeOfs.top};var relPos2={x:relPos.x/nodeTag.width(),y:relPos.y/nodeTag.height()};if(enterResponse.after&&relPos2.y>0.75){hitMode="after";}else if(!enterResponse.over&&enterResponse.after&&relPos2.y>0.5){hitMode="after";}else if(enterResponse.before&&relPos2.y<=0.25){hitMode="before";}else if(!enterResponse.over&&enterResponse.before&&relPos2.y<=0.5){hitMode="before";}else if(enterResponse.over){hitMode="over";}
|
||||
if(dnd.preventVoidMoves){if(node===otherNode){hitMode=null;}else if(hitMode==="before"&&otherNode&&node===otherNode.getNextSibling()){hitMode=null;}else if(hitMode==="after"&&otherNode&&node===otherNode.getPrevSibling()){hitMode=null;}else if(hitMode==="over"&&otherNode&&otherNode.parent===node&&otherNode.isLastSibling()){hitMode=null;}}
|
||||
ui.helper.data("hitMode",hitMode);}
|
||||
if(hitMode==="over"&&dnd.autoExpandMS&&node.hasChildren()!==false&&!node.bExpanded){node.scheduleAction("expand",dnd.autoExpandMS);}
|
||||
if(hitMode&&dnd.onDragOver){res=dnd.onDragOver(node,otherNode,hitMode);}
|
||||
this._setDndStatus(otherNode,node,ui.helper,hitMode,res!==false);break;case"drop":hitMode=ui.helper.data("hitMode");if(hitMode&&dnd.onDrop){dnd.onDrop(node,otherNode,hitMode,ui,draggable);}
|
||||
break;case"leave":node.scheduleAction("cancel");ui.helper.data("enterResponse",null);ui.helper.data("hitMode",null);this._setDndStatus(otherNode,node,ui.helper,"out",undefined);if(dnd.onDragLeave){dnd.onDragLeave(node,otherNode);}
|
||||
break;case"stop":nodeTag.removeClass("dynatree-drag-source");if(dnd.onDragStop){dnd.onDragStop(node);}
|
||||
break;default:throw"Unsupported drag event: "+eventName;}
|
||||
return res;},cancelDrag:function(){var dd=$.ui.ddmanager.current;if(dd){dd.cancel();}},lastentry:undefined};$.widget("ui.dynatree",{_init:function(){if(parseFloat($.ui.version)<1.8){_log("warn","ui.dynatree._init() was called; you should upgrade to jquery.ui.core.js v1.8 or higher.");return this._create();}
|
||||
_log("debug","ui.dynatree._init() was called; no current default functionality.");},_create:function(){logMsg("Dynatree._create(): version='%s', debugLevel=%o.",DynaTree.version,this.options.debugLevel);var opts=this.options;this.options.event+=".dynatree";var divTree=this.element.get(0);this.tree=new DynaTree(this);this.tree._load();this.tree.logDebug("Dynatree._init(): done.");},bind:function(){this.unbind();var eventNames="click.dynatree dblclick.dynatree";if(this.options.keyboard){eventNames+=" keypress.dynatree keydown.dynatree";}
|
||||
this.element.bind(eventNames,function(event){var dtnode=getDtNodeFromElement(event.target);if(!dtnode){return true;}
|
||||
var tree=dtnode.tree;var o=tree.options;tree.logDebug("event(%s): dtnode: %s",event.type,dtnode);var prevPhase=tree.phase;tree.phase="userEvent";try{switch(event.type){case"click":return(o.onClick&&o.onClick.call(tree,dtnode,event)===false)?false:dtnode._onClick(event);case"dblclick":return(o.onDblClick&&o.onDblClick.call(tree,dtnode,event)===false)?false:dtnode._onDblClick(event);case"keydown":return(o.onKeydown&&o.onKeydown.call(tree,dtnode,event)===false)?false:dtnode._onKeydown(event);case"keypress":return(o.onKeypress&&o.onKeypress.call(tree,dtnode,event)===false)?false:dtnode._onKeypress(event);}}catch(e){var _=null;tree.logWarning("bind(%o): dtnode: %o, error: %o",event,dtnode,e);}finally{tree.phase=prevPhase;}});function __focusHandler(event){event=$.event.fix(event||window.event);var dtnode=getDtNodeFromElement(event.target);return dtnode?dtnode._onFocus(event):false;}
|
||||
var div=this.tree.divTree;if(div.addEventListener){div.addEventListener("focus",__focusHandler,true);div.addEventListener("blur",__focusHandler,true);}else{div.onfocusin=div.onfocusout=__focusHandler;}},unbind:function(){this.element.unbind(".dynatree");},enable:function(){this.bind();$.Widget.prototype.enable.apply(this,arguments);},disable:function(){this.unbind();$.Widget.prototype.disable.apply(this,arguments);},getTree:function(){return this.tree;},getRoot:function(){return this.tree.getRoot();},getActiveNode:function(){return this.tree.getActiveNode();},getSelectedNodes:function(){return this.tree.getSelectedNodes();},lastentry:undefined});if(parseFloat($.ui.version)<1.8){$.ui.dynatree.getter="getTree getRoot getActiveNode getSelectedNodes";}
|
||||
$.ui.dynatree.prototype.options={title:"Dynatree",minExpandLevel:1,imagePath:null,children:null,initId:null,initAjax:null,autoFocus:true,keyboard:true,persist:false,autoCollapse:false,clickFolderMode:3,activeVisible:true,checkbox:false,selectMode:2,fx:null,noLink:false,onClick:null,onDblClick:null,onKeydown:null,onKeypress:null,onFocus:null,onBlur:null,onQueryActivate:null,onQuerySelect:null,onQueryExpand:null,onPostInit:null,onActivate:null,onDeactivate:null,onSelect:null,onExpand:null,onLazyRead:null,onCustomRender:null,onRender:null,dnd:{onDragStart:null,onDragStop:null,autoExpandMS:1000,preventVoidMoves:true,onDragEnter:null,onDragOver:null,onDrop:null,onDragLeave:null},ajaxDefaults:{cache:false,dataType:"json"},strings:{loading:"Loading…",loadError:"Load error!"},generateIds:false,idPrefix:"dynatree-id-",keyPathSeparator:"/",cookieId:"dynatree",cookie:{expires:null},classNames:{container:"dynatree-container",node:"dynatree-node",folder:"dynatree-folder",empty:"dynatree-empty",vline:"dynatree-vline",expander:"dynatree-expander",connector:"dynatree-connector",checkbox:"dynatree-checkbox",nodeIcon:"dynatree-icon",title:"dynatree-title",noConnector:"dynatree-no-connector",nodeError:"dynatree-statusnode-error",nodeWait:"dynatree-statusnode-wait",hidden:"dynatree-hidden",combinedExpanderPrefix:"dynatree-exp-",combinedIconPrefix:"dynatree-ico-",nodeLoading:"dynatree-loading",hasChildren:"dynatree-has-children",active:"dynatree-active",selected:"dynatree-selected",expanded:"dynatree-expanded",lazy:"dynatree-lazy",focused:"dynatree-focused",partsel:"dynatree-partsel",lastsib:"dynatree-lastsib"},debugLevel:1,lastentry:undefined};if(parseFloat($.ui.version)<1.8){$.ui.dynatree.defaults=$.ui.dynatree.prototype.options;}
|
||||
$.ui.dynatree.nodedatadefaults={title:null,key:null,isFolder:false,isLazy:false,tooltip:null,icon:null,addClass:null,noLink:false,activate:false,focus:false,expand:false,select:false,hideCheckbox:false,unselectable:false,children:null,lastentry:undefined};function _initDragAndDrop(tree){var dnd=tree.options.dnd||null;if(dnd&&(dnd.onDragStart||dnd.onDrop)){_registerDnd();}
|
||||
if(dnd&&dnd.onDragStart){tree.$tree.draggable({addClasses:false,appendTo:"body",containment:false,delay:0,distance:4,revert:false,connectToDynatree:true,helper:function(event){var sourceNode=getDtNodeFromElement(event.target);return sourceNode.tree._onDragEvent("helper",sourceNode,null,event,null,null);},_last:null});}
|
||||
if(dnd&&dnd.onDrop){tree.$tree.droppable({addClasses:false,tolerance:"intersect",greedy:false,_last:null});}}
|
||||
var didRegisterDnd=false;var _registerDnd=function(){if(didRegisterDnd){return;}
|
||||
$.ui.plugin.add("draggable","connectToDynatree",{start:function(event,ui){var draggable=$(this).data("draggable");var sourceNode=ui.helper.data("dtSourceNode")||null;if(sourceNode){draggable.offset.click.top=-2;draggable.offset.click.left=+16;return sourceNode.tree._onDragEvent("start",sourceNode,null,event,ui,draggable);}},drag:function(event,ui){var draggable=$(this).data("draggable");var sourceNode=ui.helper.data("dtSourceNode")||null;var prevTargetNode=ui.helper.data("dtTargetNode")||null;var targetNode=getDtNodeFromElement(event.target);if(event.target&&!targetNode){var isHelper=$(event.target).closest("div.dynatree-drag-helper,#dynatree-drop-marker").length>0;if(isHelper){return;}}
|
||||
ui.helper.data("dtTargetNode",targetNode);if(prevTargetNode&&prevTargetNode!==targetNode){prevTargetNode.tree._onDragEvent("leave",prevTargetNode,sourceNode,event,ui,draggable);}
|
||||
if(targetNode){if(!targetNode.tree.options.dnd.onDrop){noop();}else if(targetNode===prevTargetNode){targetNode.tree._onDragEvent("over",targetNode,sourceNode,event,ui,draggable);}else{targetNode.tree._onDragEvent("enter",targetNode,sourceNode,event,ui,draggable);}}},stop:function(event,ui){var draggable=$(this).data("draggable");var sourceNode=ui.helper.data("dtSourceNode")||null;var targetNode=ui.helper.data("dtTargetNode")||null;var mouseDownEvent=draggable._mouseDownEvent;var eventType=event.type;var dropped=(eventType=="mouseup"&&event.which==1);if(!dropped){logMsg("Drag was cancelled");}
|
||||
if(targetNode){if(dropped){targetNode.tree._onDragEvent("drop",targetNode,sourceNode,event,ui,draggable);}
|
||||
targetNode.tree._onDragEvent("leave",targetNode,sourceNode,event,ui,draggable);}
|
||||
if(sourceNode){sourceNode.tree._onDragEvent("stop",sourceNode,null,event,ui,draggable);}}});didRegisterDnd=true;};})(jQuery);
|
||||
4
AndorsTrailEdit/inc/jquery.min.js
vendored
Normal file
4
AndorsTrailEdit/inc/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 570 B |
@@ -1,597 +0,0 @@
|
||||
/*!
|
||||
* mustache.js - Logic-less {{mustache}} templates with JavaScript
|
||||
* http://github.com/janl/mustache.js
|
||||
*/
|
||||
var Mustache = (typeof module !== "undefined" && module.exports) || {};
|
||||
|
||||
(function (exports) {
|
||||
|
||||
exports.name = "mustache.js";
|
||||
exports.version = "0.5.1-dev";
|
||||
exports.tags = ["{{", "}}"];
|
||||
|
||||
exports.parse = parse;
|
||||
exports.clearCache = clearCache;
|
||||
exports.compile = compile;
|
||||
exports.compilePartial = compilePartial;
|
||||
exports.render = render;
|
||||
|
||||
exports.Scanner = Scanner;
|
||||
exports.Context = Context;
|
||||
exports.Renderer = Renderer;
|
||||
|
||||
// This is here for backwards compatibility with 0.4.x.
|
||||
exports.to_html = function (template, view, partials, send) {
|
||||
var result = render(template, view, partials);
|
||||
|
||||
if (typeof send === "function") {
|
||||
send(result);
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
var whiteRe = /\s*/;
|
||||
var spaceRe = /\s+/;
|
||||
var nonSpaceRe = /\S/;
|
||||
var eqRe = /\s*=/;
|
||||
var curlyRe = /\s*\}/;
|
||||
var tagRe = /#|\^|\/|>|\{|&|=|!/;
|
||||
|
||||
// Workaround for https://issues.apache.org/jira/browse/COUCHDB-577
|
||||
// See https://github.com/janl/mustache.js/issues/189
|
||||
function testRe(re, string) {
|
||||
return RegExp.prototype.test.call(re, string);
|
||||
}
|
||||
|
||||
function isWhitespace(string) {
|
||||
return !testRe(nonSpaceRe, string);
|
||||
}
|
||||
|
||||
var isArray = Array.isArray || function (obj) {
|
||||
return Object.prototype.toString.call(obj) === "[object Array]";
|
||||
};
|
||||
|
||||
// OSWASP Guidlines: escape all non alphanumeric characters in ASCII space.
|
||||
var jsCharsRe = /[\x00-\x2F\x3A-\x40\x5B-\x60\x7B-\xFF\u2028\u2029]/gm;
|
||||
|
||||
function quote(text) {
|
||||
var escaped = text.replace(jsCharsRe, function (c) {
|
||||
return "\\u" + ('0000' + c.charCodeAt(0).toString(16)).slice(-4);
|
||||
});
|
||||
|
||||
return '"' + escaped + '"';
|
||||
}
|
||||
|
||||
function escapeRe(string) {
|
||||
return string.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
||||
}
|
||||
|
||||
var entityMap = {
|
||||
"&": "&",
|
||||
"<": "<",
|
||||
">": ">",
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
"/": '/'
|
||||
};
|
||||
|
||||
function escapeHtml(string) {
|
||||
return String(string).replace(/[&<>"'\/]/g, function (s) {
|
||||
return entityMap[s];
|
||||
});
|
||||
}
|
||||
|
||||
// Export these utility functions.
|
||||
exports.isWhitespace = isWhitespace;
|
||||
exports.isArray = isArray;
|
||||
exports.quote = quote;
|
||||
exports.escapeRe = escapeRe;
|
||||
exports.escapeHtml = escapeHtml;
|
||||
|
||||
function Scanner(string) {
|
||||
this.string = string;
|
||||
this.tail = string;
|
||||
this.pos = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if the tail is empty (end of string).
|
||||
*/
|
||||
Scanner.prototype.eos = function () {
|
||||
return this.tail === "";
|
||||
};
|
||||
|
||||
/**
|
||||
* Tries to match the given regular expression at the current position.
|
||||
* Returns the matched text if it can match, `null` otherwise.
|
||||
*/
|
||||
Scanner.prototype.scan = function (re) {
|
||||
var match = this.tail.match(re);
|
||||
|
||||
if (match && match.index === 0) {
|
||||
this.tail = this.tail.substring(match[0].length);
|
||||
this.pos += match[0].length;
|
||||
return match[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Skips all text until the given regular expression can be matched. Returns
|
||||
* the skipped string, which is the entire tail of this scanner if no match
|
||||
* can be made.
|
||||
*/
|
||||
Scanner.prototype.scanUntil = function (re) {
|
||||
var match, pos = this.tail.search(re);
|
||||
|
||||
switch (pos) {
|
||||
case -1:
|
||||
match = this.tail;
|
||||
this.pos += this.tail.length;
|
||||
this.tail = "";
|
||||
break;
|
||||
case 0:
|
||||
match = null;
|
||||
break;
|
||||
default:
|
||||
match = this.tail.substring(0, pos);
|
||||
this.tail = this.tail.substring(pos);
|
||||
this.pos += pos;
|
||||
}
|
||||
|
||||
return match;
|
||||
};
|
||||
|
||||
function Context(view, parent) {
|
||||
this.view = view;
|
||||
this.parent = parent;
|
||||
this.clearCache();
|
||||
}
|
||||
|
||||
Context.make = function (view) {
|
||||
return (view instanceof Context) ? view : new Context(view);
|
||||
};
|
||||
|
||||
Context.prototype.clearCache = function () {
|
||||
this._cache = {};
|
||||
};
|
||||
|
||||
Context.prototype.push = function (view) {
|
||||
return new Context(view, this);
|
||||
};
|
||||
|
||||
Context.prototype.lookup = function (name) {
|
||||
var value = this._cache[name];
|
||||
|
||||
if (!value) {
|
||||
if (name === ".") {
|
||||
value = this.view;
|
||||
} else {
|
||||
var context = this;
|
||||
|
||||
while (context) {
|
||||
if (name.indexOf(".") > 0) {
|
||||
var names = name.split("."), i = 0;
|
||||
|
||||
value = context.view;
|
||||
|
||||
while (value && i < names.length) {
|
||||
value = value[names[i++]];
|
||||
}
|
||||
} else {
|
||||
value = context.view[name];
|
||||
}
|
||||
|
||||
if (value != null) {
|
||||
break;
|
||||
}
|
||||
|
||||
context = context.parent;
|
||||
}
|
||||
}
|
||||
|
||||
this._cache[name] = value;
|
||||
}
|
||||
|
||||
if (typeof value === "function") {
|
||||
value = value.call(this.view);
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
function Renderer() {
|
||||
this.clearCache();
|
||||
}
|
||||
|
||||
Renderer.prototype.clearCache = function () {
|
||||
this._cache = {};
|
||||
this._partialCache = {};
|
||||
};
|
||||
|
||||
Renderer.prototype.compile = function (tokens, tags) {
|
||||
var fn = compileTokens(tokens),
|
||||
self = this;
|
||||
|
||||
return function (view) {
|
||||
return fn(Context.make(view), self);
|
||||
};
|
||||
};
|
||||
|
||||
Renderer.prototype.compilePartial = function (name, tokens, tags) {
|
||||
this._partialCache[name] = this.compile(tokens, tags);
|
||||
return this._partialCache[name];
|
||||
};
|
||||
|
||||
Renderer.prototype.render = function (template, view) {
|
||||
var fn = this._cache[template];
|
||||
|
||||
if (!fn) {
|
||||
fn = this.compile(template);
|
||||
this._cache[template] = fn;
|
||||
}
|
||||
|
||||
return fn(view);
|
||||
};
|
||||
|
||||
Renderer.prototype._section = function (name, context, callback) {
|
||||
var value = context.lookup(name);
|
||||
|
||||
switch (typeof value) {
|
||||
case "object":
|
||||
if (isArray(value)) {
|
||||
var buffer = "";
|
||||
for (var i = 0, len = value.length; i < len; ++i) {
|
||||
buffer += callback(context.push(value[i]), this);
|
||||
}
|
||||
return buffer;
|
||||
} else {
|
||||
return callback(context.push(value), this);
|
||||
}
|
||||
break;
|
||||
case "function":
|
||||
var sectionText = callback(context, this), self = this;
|
||||
var scopedRender = function (template) {
|
||||
return self.render(template, context);
|
||||
};
|
||||
return value.call(context.view, sectionText, scopedRender) || "";
|
||||
break;
|
||||
default:
|
||||
if (value) {
|
||||
return callback(context, this);
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
|
||||
Renderer.prototype._inverted = function (name, context, callback) {
|
||||
var value = context.lookup(name);
|
||||
|
||||
// From the spec: inverted sections may render text once based on the
|
||||
// inverse value of the key. That is, they will be rendered if the key
|
||||
// doesn't exist, is false, or is an empty list.
|
||||
if (value == null || value === false || (isArray(value) && value.length === 0)) {
|
||||
return callback(context, this);
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
|
||||
Renderer.prototype._partial = function (name, context) {
|
||||
var fn = this._partialCache[name];
|
||||
|
||||
if (fn) {
|
||||
return fn(context, this);
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
|
||||
Renderer.prototype._name = function (name, context, escape) {
|
||||
var value = context.lookup(name);
|
||||
|
||||
if (typeof value === "function") {
|
||||
value = value.call(context.view);
|
||||
}
|
||||
|
||||
var string = (value == null) ? "" : String(value);
|
||||
|
||||
if (escape) {
|
||||
return escapeHtml(string);
|
||||
}
|
||||
|
||||
return string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Low-level function that compiles the given `tokens` into a
|
||||
* function that accepts two arguments: a Context and a
|
||||
* Renderer. Returns the body of the function as a string if
|
||||
* `returnBody` is true.
|
||||
*/
|
||||
function compileTokens(tokens, returnBody) {
|
||||
if (typeof tokens === "string") {
|
||||
tokens = parse(tokens);
|
||||
}
|
||||
|
||||
var body = ['""'];
|
||||
var token, method, escape;
|
||||
|
||||
for (var i = 0, len = tokens.length; i < len; ++i) {
|
||||
token = tokens[i];
|
||||
|
||||
switch (token.type) {
|
||||
case "#":
|
||||
case "^":
|
||||
method = (token.type === "#") ? "_section" : "_inverted";
|
||||
body.push("r." + method + "(" + quote(token.value) + ", c, function (c, r) {\n" +
|
||||
" " + compileTokens(token.tokens, true) + "\n" +
|
||||
"})");
|
||||
break;
|
||||
case "{":
|
||||
case "&":
|
||||
case "name":
|
||||
escape = token.type === "name" ? "true" : "false";
|
||||
body.push("r._name(" + quote(token.value) + ", c, " + escape + ")");
|
||||
break;
|
||||
case ">":
|
||||
body.push("r._partial(" + quote(token.value) + ", c)");
|
||||
break;
|
||||
case "text":
|
||||
body.push(quote(token.value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert to a string body.
|
||||
body = "return " + body.join(" + ") + ";";
|
||||
|
||||
// Good for debugging.
|
||||
// console.log(body);
|
||||
|
||||
if (returnBody) {
|
||||
return body;
|
||||
}
|
||||
|
||||
// For great evil!
|
||||
return new Function("c, r", body);
|
||||
}
|
||||
|
||||
function escapeTags(tags) {
|
||||
if (tags.length === 2) {
|
||||
return [
|
||||
new RegExp(escapeRe(tags[0]) + "\\s*"),
|
||||
new RegExp("\\s*" + escapeRe(tags[1]))
|
||||
];
|
||||
}
|
||||
|
||||
throw new Error("Invalid tags: " + tags.join(" "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Forms the given linear array of `tokens` into a nested tree structure
|
||||
* where tokens that represent a section have a "tokens" array property
|
||||
* that contains all tokens that are in that section.
|
||||
*/
|
||||
function nestTokens(tokens) {
|
||||
var tree = [];
|
||||
var collector = tree;
|
||||
var sections = [];
|
||||
var token, section;
|
||||
|
||||
for (var i = 0; i < tokens.length; ++i) {
|
||||
token = tokens[i];
|
||||
|
||||
switch (token.type) {
|
||||
case "#":
|
||||
case "^":
|
||||
token.tokens = [];
|
||||
sections.push(token);
|
||||
collector.push(token);
|
||||
collector = token.tokens;
|
||||
break;
|
||||
case "/":
|
||||
if (sections.length === 0) {
|
||||
throw new Error("Unopened section: " + token.value);
|
||||
}
|
||||
|
||||
section = sections.pop();
|
||||
|
||||
if (section.value !== token.value) {
|
||||
throw new Error("Unclosed section: " + section.value);
|
||||
}
|
||||
|
||||
if (sections.length > 0) {
|
||||
collector = sections[sections.length - 1].tokens;
|
||||
} else {
|
||||
collector = tree;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
collector.push(token);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure there were no open sections when we're done.
|
||||
section = sections.pop();
|
||||
|
||||
if (section) {
|
||||
throw new Error("Unclosed section: " + section.value);
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines the values of consecutive text tokens in the given `tokens` array
|
||||
* to a single token.
|
||||
*/
|
||||
function squashTokens(tokens) {
|
||||
var lastToken;
|
||||
|
||||
for (var i = 0; i < tokens.length; ++i) {
|
||||
var token = tokens[i];
|
||||
|
||||
if (lastToken && lastToken.type === "text" && token.type === "text") {
|
||||
lastToken.value += token.value;
|
||||
tokens.splice(i--, 1); // Remove this token from the array.
|
||||
} else {
|
||||
lastToken = token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Breaks up the given `template` string into a tree of token objects. If
|
||||
* `tags` is given here it must be an array with two string values: the
|
||||
* opening and closing tags used in the template (e.g. ["<%", "%>"]). Of
|
||||
* course, the default is to use mustaches (i.e. Mustache.tags).
|
||||
*/
|
||||
function parse(template, tags) {
|
||||
tags = tags || exports.tags;
|
||||
var tagRes = escapeTags(tags);
|
||||
|
||||
var scanner = new Scanner(template);
|
||||
|
||||
var tokens = [], // Buffer to hold the tokens
|
||||
spaces = [], // Indices of whitespace tokens on the current line
|
||||
hasTag = false, // Is there a {{tag}} on the current line?
|
||||
nonSpace = false; // Is there a non-space char on the current line?
|
||||
|
||||
// Strips all whitespace tokens array for the current line
|
||||
// if there was a {{#tag}} on it and otherwise only space.
|
||||
var stripSpace = function () {
|
||||
if (hasTag && !nonSpace) {
|
||||
while (spaces.length) {
|
||||
tokens.splice(spaces.pop(), 1);
|
||||
}
|
||||
} else {
|
||||
spaces = [];
|
||||
}
|
||||
|
||||
hasTag = false;
|
||||
nonSpace = false;
|
||||
};
|
||||
|
||||
var type, value, chr;
|
||||
|
||||
while (!scanner.eos()) {
|
||||
value = scanner.scanUntil(tagRes[0]);
|
||||
|
||||
if (value) {
|
||||
for (var i = 0, len = value.length; i < len; ++i) {
|
||||
chr = value[i];
|
||||
|
||||
if (isWhitespace(chr)) {
|
||||
spaces.push(tokens.length);
|
||||
} else {
|
||||
nonSpace = true;
|
||||
}
|
||||
|
||||
tokens.push({type: "text", value: chr});
|
||||
|
||||
if (chr === "\n") {
|
||||
stripSpace(); // Check for whitespace on the current line.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Match the opening tag.
|
||||
if (!scanner.scan(tagRes[0])) {
|
||||
break;
|
||||
}
|
||||
|
||||
hasTag = true;
|
||||
type = scanner.scan(tagRe) || "name";
|
||||
|
||||
// Skip any whitespace between tag and value.
|
||||
scanner.scan(whiteRe);
|
||||
|
||||
// Extract the tag value.
|
||||
if (type === "=") {
|
||||
value = scanner.scanUntil(eqRe);
|
||||
scanner.scan(eqRe);
|
||||
scanner.scanUntil(tagRes[1]);
|
||||
} else if (type === "{") {
|
||||
var closeRe = new RegExp("\\s*" + escapeRe("}" + tags[1]));
|
||||
value = scanner.scanUntil(closeRe);
|
||||
scanner.scan(curlyRe);
|
||||
scanner.scanUntil(tagRes[1]);
|
||||
} else {
|
||||
value = scanner.scanUntil(tagRes[1]);
|
||||
}
|
||||
|
||||
// Match the closing tag.
|
||||
if (!scanner.scan(tagRes[1])) {
|
||||
throw new Error("Unclosed tag at " + scanner.pos);
|
||||
}
|
||||
|
||||
tokens.push({type: type, value: value});
|
||||
|
||||
if (type === "name" || type === "{" || type === "&") {
|
||||
nonSpace = true;
|
||||
}
|
||||
|
||||
// Set the tags for the next time around.
|
||||
if (type === "=") {
|
||||
tags = value.split(spaceRe);
|
||||
tagRes = escapeTags(tags);
|
||||
}
|
||||
}
|
||||
|
||||
squashTokens(tokens);
|
||||
|
||||
return nestTokens(tokens);
|
||||
}
|
||||
|
||||
// The high-level clearCache, compile, compilePartial, and render functions
|
||||
// use this default renderer.
|
||||
var _renderer = new Renderer;
|
||||
|
||||
/**
|
||||
* Clears all cached templates and partials.
|
||||
*/
|
||||
function clearCache() {
|
||||
_renderer.clearCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* High-level API for compiling the given `tokens` down to a reusable
|
||||
* function. If `tokens` is a string it will be parsed using the given `tags`
|
||||
* before it is compiled.
|
||||
*/
|
||||
function compile(tokens, tags) {
|
||||
return _renderer.compile(tokens, tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* High-level API for compiling the `tokens` for the partial with the given
|
||||
* `name` down to a reusable function. If `tokens` is a string it will be
|
||||
* parsed using the given `tags` before it is compiled.
|
||||
*/
|
||||
function compilePartial(name, tokens, tags) {
|
||||
return _renderer.compilePartial(name, tokens, tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* High-level API for rendering the `template` using the given `view`. The
|
||||
* optional `partials` object may be given here for convenience, but note that
|
||||
* it will cause all partials to be re-compiled, thus hurting performance. Of
|
||||
* course, this only matters if you're going to render the same template more
|
||||
* than once. If so, it is best to call `compilePartial` before calling this
|
||||
* function and to leave the `partials` argument blank.
|
||||
*/
|
||||
function render(template, view, partials) {
|
||||
if (partials) {
|
||||
for (var name in partials) {
|
||||
compilePartial(name, partials[name]);
|
||||
}
|
||||
}
|
||||
|
||||
return _renderer.render(template, view);
|
||||
}
|
||||
|
||||
})(Mustache);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,441 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Tree container
|
||||
*/
|
||||
ul.dynatree-container
|
||||
{
|
||||
font-family: tahoma, arial, helvetica;
|
||||
font-size: 10pt; /* font size should not be too big */
|
||||
white-space: nowrap;
|
||||
padding: 3px;
|
||||
|
||||
background-color: white;
|
||||
border: 1px dotted gray;
|
||||
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
ul.dynatree-container ul
|
||||
{
|
||||
padding: 0 0 0 8px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul.dynatree-container li
|
||||
{
|
||||
list-style-image: none;
|
||||
list-style-position: outside;
|
||||
list-style-type: none;
|
||||
-moz-background-clip:border;
|
||||
-moz-background-inline-policy: continuous;
|
||||
-moz-background-origin: padding;
|
||||
background-attachment: scroll;
|
||||
background-color: transparent;
|
||||
background-repeat: repeat-y;
|
||||
background-image: url("vline.gif");
|
||||
background-position: 0 0;
|
||||
/*
|
||||
background-image: url("icons_96x256.gif");
|
||||
background-position: -80px -64px;
|
||||
*/
|
||||
margin: 0;
|
||||
padding: 1px 0 0 0;
|
||||
}
|
||||
/* Suppress lines for last child node */
|
||||
ul.dynatree-container li.dynatree-lastsib
|
||||
{
|
||||
background-image: none;
|
||||
}
|
||||
/* Suppress lines if level is fixed expanded (option minExpandLevel) */
|
||||
ul.dynatree-no-connector > li
|
||||
{
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
/* Style, when control is disabled */
|
||||
.ui-dynatree-disabled ul.dynatree-container
|
||||
{
|
||||
opacity: 0.5;
|
||||
/* filter: alpha(opacity=50); /* Yields a css warning */
|
||||
background-color: silver;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Common icon definitions
|
||||
*/
|
||||
span.dynatree-empty,
|
||||
span.dynatree-vline,
|
||||
span.dynatree-connector,
|
||||
span.dynatree-expander,
|
||||
span.dynatree-icon,
|
||||
span.dynatree-checkbox,
|
||||
span.dynatree-radio,
|
||||
span.dynatree-drag-helper-img,
|
||||
#dynatree-drop-marker
|
||||
{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: -moz-inline-box; /* @ FF 1+2 */
|
||||
display: inline-block; /* Required to make a span sizeable */
|
||||
vertical-align: top;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left;
|
||||
background-image: url("icons.gif");
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
/** Used by 'icon' node option: */
|
||||
ul.dynatree-container img
|
||||
{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 3px;
|
||||
vertical-align: top;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Lines and connectors
|
||||
*/
|
||||
|
||||
span.dynatree-connector
|
||||
{
|
||||
background-position: -16px -64px;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Expander icon
|
||||
* Note: IE6 doesn't correctly evaluate multiples class names,
|
||||
* so we create combined class names that can be used in the CSS.
|
||||
*
|
||||
* Prefix: dynatree-exp-
|
||||
* 1st character: 'e': expanded, 'c': collapsed
|
||||
* 2nd character (optional): 'd': lazy (Delayed)
|
||||
* 3rd character (optional): 'l': Last sibling
|
||||
*/
|
||||
|
||||
span.dynatree-expander
|
||||
{
|
||||
background-position: 0px -80px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.dynatree-exp-cl span.dynatree-expander /* Collapsed, not delayed, last sibling */
|
||||
{
|
||||
background-position: 0px -96px;
|
||||
}
|
||||
.dynatree-exp-cd span.dynatree-expander /* Collapsed, delayed, not last sibling */
|
||||
{
|
||||
background-position: -64px -80px;
|
||||
}
|
||||
.dynatree-exp-cdl span.dynatree-expander /* Collapsed, delayed, last sibling */
|
||||
{
|
||||
background-position: -64px -96px;
|
||||
}
|
||||
.dynatree-exp-e span.dynatree-expander, /* Expanded, not delayed, not last sibling */
|
||||
.dynatree-exp-ed span.dynatree-expander /* Expanded, delayed, not last sibling */
|
||||
{
|
||||
background-position: -32px -80px;
|
||||
}
|
||||
.dynatree-exp-el span.dynatree-expander, /* Expanded, not delayed, last sibling */
|
||||
.dynatree-exp-edl span.dynatree-expander /* Expanded, delayed, last sibling */
|
||||
{
|
||||
background-position: -32px -96px;
|
||||
}
|
||||
.dynatree-loading span.dynatree-expander /* 'Loading' status overrides all others */
|
||||
{
|
||||
background-position: 0 0;
|
||||
background-image: url("loading.gif");
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Checkbox icon
|
||||
*/
|
||||
span.dynatree-checkbox
|
||||
{
|
||||
margin-left: 3px;
|
||||
background-position: 0px -32px;
|
||||
}
|
||||
span.dynatree-checkbox:hover
|
||||
{
|
||||
background-position: -16px -32px;
|
||||
}
|
||||
|
||||
.dynatree-partsel span.dynatree-checkbox
|
||||
{
|
||||
background-position: -64px -32px;
|
||||
}
|
||||
.dynatree-partsel span.dynatree-checkbox:hover
|
||||
{
|
||||
background-position: -80px -32px;
|
||||
}
|
||||
|
||||
.dynatree-selected span.dynatree-checkbox
|
||||
{
|
||||
background-position: -32px -32px;
|
||||
}
|
||||
.dynatree-selected span.dynatree-checkbox:hover
|
||||
{
|
||||
background-position: -48px -32px;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Radiobutton icon
|
||||
* This is a customization, that may be activated by overriding the 'checkbox'
|
||||
* class name as 'dynatree-radio' in the tree options.
|
||||
*/
|
||||
span.dynatree-radio
|
||||
{
|
||||
margin-left: 3px;
|
||||
background-position: 0px -48px;
|
||||
}
|
||||
span.dynatree-radio:hover
|
||||
{
|
||||
background-position: -16px -48px;
|
||||
}
|
||||
|
||||
.dynatree-partsel span.dynatree-radio
|
||||
{
|
||||
background-position: -64px -48px;
|
||||
}
|
||||
.dynatree-partsel span.dynatree-radio:hover
|
||||
{
|
||||
background-position: -80px -48px;
|
||||
}
|
||||
|
||||
.dynatree-selected span.dynatree-radio
|
||||
{
|
||||
background-position: -32px -48px;
|
||||
}
|
||||
.dynatree-selected span.dynatree-radio:hover
|
||||
{
|
||||
background-position: -48px -48px;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Node type icon
|
||||
* Note: IE6 doesn't correctly evaluate multiples class names,
|
||||
* so we create combined class names that can be used in the CSS.
|
||||
*
|
||||
* Prefix: dynatree-ico-
|
||||
* 1st character: 'e': expanded, 'c': collapsed
|
||||
* 2nd character (optional): 'f': folder
|
||||
*/
|
||||
|
||||
span.dynatree-icon /* Default icon */
|
||||
{
|
||||
margin-left: 3px;
|
||||
background-position: 0px 0px;
|
||||
}
|
||||
|
||||
.dynatree-ico-cf span.dynatree-icon /* Collapsed Folder */
|
||||
{
|
||||
background-position: 0px -16px;
|
||||
}
|
||||
|
||||
.dynatree-ico-ef span.dynatree-icon /* Expanded Folder */
|
||||
{
|
||||
background-position: -64px -16px;
|
||||
}
|
||||
|
||||
/* Status node icons */
|
||||
|
||||
.dynatree-statusnode-wait span.dynatree-icon
|
||||
{
|
||||
background-image: url("loading.gif");
|
||||
}
|
||||
|
||||
.dynatree-statusnode-error span.dynatree-icon
|
||||
{
|
||||
background-position: 0px -112px;
|
||||
/* background-image: url("ltError.gif");*/
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Node titles
|
||||
*/
|
||||
|
||||
/* @Chrome: otherwise hit area of node titles is broken (issue 133)
|
||||
Removed again for issue 165; (133 couldn't be reproduced) */
|
||||
span.dynatree-node
|
||||
{
|
||||
/* display: -moz-inline-box; /* @ FF 1+2 */
|
||||
/* display: inline-block; /* Required to make a span sizeable */
|
||||
}
|
||||
|
||||
|
||||
/* Remove blue color and underline from title links */
|
||||
ul.dynatree-container a
|
||||
/*, ul.dynatree-container a:visited*/
|
||||
{
|
||||
color: black; /* inherit doesn't work on IE */
|
||||
text-decoration: none;
|
||||
vertical-align: top;
|
||||
margin: 0px;
|
||||
margin-left: 3px;
|
||||
/* outline: 0; /* @ Firefox, prevent dotted border after click */
|
||||
}
|
||||
|
||||
ul.dynatree-container a:hover
|
||||
{
|
||||
/* text-decoration: underline; */
|
||||
background: #F2F7FD; /* light blue */
|
||||
border-color: #B8D6FB; /* darker light blue */
|
||||
}
|
||||
|
||||
span.dynatree-node a
|
||||
{
|
||||
display: inline-block; /* Better alignment, when title contains <br> */
|
||||
/* vertical-align: top;*/
|
||||
padding-left: 3px;
|
||||
padding-right: 3px; /* Otherwise italic font will be outside bounds */
|
||||
/* line-height: 16px; /* should be the same as img height, in case 16 px */
|
||||
}
|
||||
span.dynatree-folder a
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul.dynatree-container a:focus,
|
||||
span.dynatree-focused a:link /* @IE */
|
||||
{
|
||||
background-color: #EFEBDE; /* gray */
|
||||
}
|
||||
|
||||
span.dynatree-has-children a
|
||||
{
|
||||
}
|
||||
|
||||
span.dynatree-expanded a
|
||||
{
|
||||
}
|
||||
|
||||
span.dynatree-selected a
|
||||
{
|
||||
color: green;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
span.dynatree-active a
|
||||
{
|
||||
background-color: #3169C6 !important;
|
||||
color: white !important; /* @ IE6 */
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Drag'n'drop support
|
||||
*/
|
||||
|
||||
/*** Helper object ************************************************************/
|
||||
div.dynatree-drag-helper
|
||||
{
|
||||
}
|
||||
div.dynatree-drag-helper a
|
||||
{
|
||||
border: 1px solid gray;
|
||||
background-color: white;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
span.dynatree-drag-helper-img
|
||||
{
|
||||
/*
|
||||
position: relative;
|
||||
left: -16px;
|
||||
*/
|
||||
}
|
||||
div.dynatree-drag-helper /*.dynatree-drop-accept*/
|
||||
{
|
||||
|
||||
/* border-color: green;
|
||||
background-color: red;*/
|
||||
}
|
||||
div.dynatree-drop-accept span.dynatree-drag-helper-img
|
||||
{
|
||||
background-position: -32px -112px;
|
||||
}
|
||||
div.dynatree-drag-helper.dynatree-drop-reject
|
||||
{
|
||||
border-color: red;
|
||||
}
|
||||
div.dynatree-drop-reject span.dynatree-drag-helper-img
|
||||
{
|
||||
background-position: -16px -112px;
|
||||
}
|
||||
|
||||
/*** Drop marker icon *********************************************************/
|
||||
|
||||
#dynatree-drop-marker
|
||||
{
|
||||
width: 24px;
|
||||
position: absolute;
|
||||
background-position: 0 -128px;
|
||||
}
|
||||
#dynatree-drop-marker.dynatree-drop-after,
|
||||
#dynatree-drop-marker.dynatree-drop-before
|
||||
{
|
||||
width:64px;
|
||||
background-position: 0 -144px;
|
||||
}
|
||||
#dynatree-drop-marker.dynatree-drop-copy
|
||||
{
|
||||
background-position: -64px -128px;
|
||||
}
|
||||
#dynatree-drop-marker.dynatree-drop-move
|
||||
{
|
||||
background-position: -64px -128px;
|
||||
}
|
||||
|
||||
/*** Source node while dragging ***********************************************/
|
||||
|
||||
span.dynatree-drag-source
|
||||
{
|
||||
/* border: 1px dotted gray; */
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
span.dynatree-drag-source a
|
||||
{
|
||||
color: gray;
|
||||
}
|
||||
|
||||
/*** Target node while dragging cursor is over it *****************************/
|
||||
|
||||
span.dynatree-drop-target
|
||||
{
|
||||
/*border: 1px solid gray;*/
|
||||
}
|
||||
span.dynatree-drop-target a
|
||||
{
|
||||
/*background-repeat: no-repeat;
|
||||
background-position: right;
|
||||
background-image: url("drop_child.gif");*/
|
||||
}
|
||||
span.dynatree-drop-target.dynatree-drop-accept a
|
||||
{
|
||||
/*border: 1px solid green;*/
|
||||
background-color: #3169C6 !important;
|
||||
color: white !important; /* @ IE6 */
|
||||
text-decoration: none;
|
||||
}
|
||||
span.dynatree-drop-target.dynatree-drop-reject
|
||||
{
|
||||
/*border: 1px solid red;*/
|
||||
}
|
||||
span.dynatree-drop-target.dynatree-drop-after a
|
||||
{
|
||||
/*background-repeat: repeat-x;
|
||||
background-position: bottom;
|
||||
background-image: url("drop_append.gif");*/
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Custom node classes (sample)
|
||||
*/
|
||||
|
||||
span.custom1 a
|
||||
{
|
||||
background-color: maroon;
|
||||
color: yellow;
|
||||
}
|
||||
1
AndorsTrailEdit/inc/underscore-min.js
vendored
Normal file
1
AndorsTrailEdit/inc/underscore-min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 844 B |
24
AndorsTrailEdit/js/app.js
Normal file
24
AndorsTrailEdit/js/app.js
Normal file
@@ -0,0 +1,24 @@
|
||||
var ATEditor = (function(ATEditor, controllers) {
|
||||
|
||||
var htmldir = 'partials/';
|
||||
|
||||
ATEditor.app = angular
|
||||
.module('ateditor', [])
|
||||
.config(['$routeProvider', function($routeProvider) {
|
||||
$routeProvider
|
||||
.when('/actorcondition/edit/:id', {templateUrl: htmldir+'edit_actorcondition.html', controller: controllers.ActorConditionController})
|
||||
.when('/quest/edit/:id', {templateUrl: htmldir+'edit_quest.html', controller: controllers.QuestController})
|
||||
.when('/item/edit/:id', {templateUrl: htmldir+'edit_item.html', controller: controllers.ItemController})
|
||||
.when('/item/table', {templateUrl: htmldir+'table_item.html', controller: controllers.ItemTableController})
|
||||
.when('/droplist/edit/:id', {templateUrl: htmldir+'edit_droplist.html', controller: controllers.DropListController})
|
||||
.when('/dialogue/edit/:id', {templateUrl: htmldir+'edit_dialogue.html', controller: controllers.DialogueController})
|
||||
.when('/monster/edit/:id', {templateUrl: htmldir+'edit_monster.html', controller: controllers.MonsterController})
|
||||
.when('/monster/table', {templateUrl: htmldir+'table_monster.html', controller: controllers.MonsterTableController})
|
||||
.when('/itemcategory/edit/:id', {templateUrl: htmldir+'edit_itemcategory.html', controller: controllers.ItemCategoryController})
|
||||
.when('/import', {templateUrl: htmldir+'import.html', controller: controllers.ImportController})
|
||||
.when('/export', {templateUrl: htmldir+'export.html', controller: controllers.ExportController})
|
||||
.when('/start', {templateUrl: htmldir+'start.html'})
|
||||
.otherwise({redirectTo: '/start'});
|
||||
}]);
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.controllers);
|
||||
12
AndorsTrailEdit/js/controllers/actorcondition.js
Normal file
12
AndorsTrailEdit/js/controllers/actorcondition.js
Normal file
@@ -0,0 +1,12 @@
|
||||
var ATEditor = (function(ATEditor, model) {
|
||||
|
||||
function ActorConditionController($scope, $routeParams) {
|
||||
$scope.datasource = model.actorConditions;
|
||||
$scope.obj = $scope.datasource.findById($routeParams.id);
|
||||
};
|
||||
|
||||
ATEditor.controllers = ATEditor.controllers || {};
|
||||
ATEditor.controllers.ActorConditionController = ActorConditionController;
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.model);
|
||||
56
AndorsTrailEdit/js/controllers/dialogue.js
Normal file
56
AndorsTrailEdit/js/controllers/dialogue.js
Normal file
@@ -0,0 +1,56 @@
|
||||
var ATEditor = (function(ATEditor, model, defaults, importExport, _) {
|
||||
|
||||
function DialogueController($scope, $routeParams) {
|
||||
$scope.datasource = model.dialogue;
|
||||
$scope.rootPhrase = $scope.datasource.findById($routeParams.id);
|
||||
$scope.phrase = $scope.rootPhrase;
|
||||
$scope.reply = null;
|
||||
|
||||
$scope.removeReward = function(phrase, reward) {
|
||||
var idx = phrase.rewards.indexOf(reward);
|
||||
phrase.rewards.splice(idx, 1);
|
||||
};
|
||||
$scope.addReward = function(phrase) {
|
||||
phrase.rewards.push({});
|
||||
};
|
||||
$scope.proceedToPhrase = function(obj, prop) {
|
||||
var phraseId = obj[prop];
|
||||
if (phraseId) {
|
||||
var nextPhrase = model.dialogue.findById(phraseId);
|
||||
if (nextPhrase) {
|
||||
window.location = "#/" + model.dialogue.id + "/edit/" + phraseId;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
phraseId = $scope.phrase.id;
|
||||
}
|
||||
var newPhrase = model.dialogue.addNew(phraseId);
|
||||
importExport.prepareObjectsForEditor(model.dialogue, [ newPhrase ]);
|
||||
newPhrase.hasOnlyNextReply = true;
|
||||
|
||||
phraseId = newPhrase.id;
|
||||
obj[prop] = phraseId;
|
||||
|
||||
window.location = "#/" + model.dialogue.id + "/edit/" + phraseId;
|
||||
};
|
||||
$scope.selectReply = function(reply) {
|
||||
$scope.reply = reply;
|
||||
};
|
||||
$scope.removeReply = function(phrase, reply) {
|
||||
var idx = phrase.replies.indexOf(reply);
|
||||
phrase.replies.splice(idx, 1);
|
||||
if ($scope.reply === reply) { $scope.reply = null; }
|
||||
};
|
||||
$scope.addReply = function(phrase) {
|
||||
var reply = {};
|
||||
defaults.addDefaults('reply', reply);
|
||||
phrase.replies.push(reply);
|
||||
$scope.reply = reply;
|
||||
};
|
||||
};
|
||||
|
||||
ATEditor.controllers = ATEditor.controllers || {};
|
||||
ATEditor.controllers.DialogueController = DialogueController;
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.model, ATEditor.defaults, ATEditor.importExport, _);
|
||||
19
AndorsTrailEdit/js/controllers/droplist.js
Normal file
19
AndorsTrailEdit/js/controllers/droplist.js
Normal file
@@ -0,0 +1,19 @@
|
||||
var ATEditor = (function(ATEditor, model) {
|
||||
|
||||
function DropListController($scope, $routeParams) {
|
||||
$scope.datasource = model.droplists;
|
||||
$scope.obj = $scope.datasource.findById($routeParams.id);
|
||||
$scope.addDropItem = function() {
|
||||
$scope.obj.items.push({quantity: {}});
|
||||
};
|
||||
$scope.removeDropItem = function(dropItem) {
|
||||
var idx = $scope.obj.items.indexOf(dropItem);
|
||||
$scope.obj.items.splice(idx, 1);
|
||||
};
|
||||
};
|
||||
|
||||
ATEditor.controllers = ATEditor.controllers || {};
|
||||
ATEditor.controllers.DropListController = DropListController;
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.model);
|
||||
17
AndorsTrailEdit/js/controllers/export.js
Normal file
17
AndorsTrailEdit/js/controllers/export.js
Normal file
@@ -0,0 +1,17 @@
|
||||
var ATEditor = (function(ATEditor, model, importExport) {
|
||||
|
||||
function ExportController($scope) {
|
||||
$scope.sections = model.sections;
|
||||
$scope.content = "";
|
||||
$scope.selectedSection = $scope.selectedSection || model.items;
|
||||
$scope.exportData = function() {
|
||||
$scope.content = importExport.exportData($scope.selectedSection);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
ATEditor.controllers = ATEditor.controllers || {};
|
||||
ATEditor.controllers.ExportController = ExportController;
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.model, ATEditor.importExport);
|
||||
41
AndorsTrailEdit/js/controllers/import.js
Normal file
41
AndorsTrailEdit/js/controllers/import.js
Normal file
@@ -0,0 +1,41 @@
|
||||
var ATEditor = (function(ATEditor, model, importExport, exampleData) {
|
||||
|
||||
function ImportController($scope) {
|
||||
$scope.sections = model.sections;
|
||||
$scope.content = "";
|
||||
$scope.selectedSection = $scope.selectedSection || model.items;
|
||||
$scope.importType = $scope.importType || 'paste';
|
||||
$scope.availableFiles = exampleData.resources;
|
||||
|
||||
var countBefore = 0;
|
||||
function success() {
|
||||
var section = $scope.selectedSection;
|
||||
var countAfter = section.items.length;
|
||||
$scope.importedMsg = "Imported " + (countAfter - countBefore) + " " + section.name;
|
||||
}
|
||||
function error(msg) {
|
||||
$scope.errorMsg = "Error importing data: " + msg;
|
||||
}
|
||||
$scope.importPastedData = function() {
|
||||
$scope.errorMsg = "";
|
||||
$scope.importedMsg = "";
|
||||
var section = $scope.selectedSection;
|
||||
countBefore = section.items.length;
|
||||
importExport.importText(section, $scope.content, success, error);
|
||||
};
|
||||
$scope.importExistingData = function() {
|
||||
$scope.errorMsg = "";
|
||||
$scope.importedMsg = "";
|
||||
var section = $scope.selectedSection;
|
||||
countBefore = section.items.length;
|
||||
exampleData.loadUrlFromGit("AndorsTrail/res/raw/" + $scope.selectedFile, function(data) {
|
||||
importExport.importDataObjects(section, data, success, error);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
ATEditor.controllers = ATEditor.controllers || {};
|
||||
ATEditor.controllers.ImportController = ImportController;
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.model, ATEditor.importExport, ATEditor.exampleData);
|
||||
138
AndorsTrailEdit/js/controllers/item.js
Normal file
138
AndorsTrailEdit/js/controllers/item.js
Normal file
@@ -0,0 +1,138 @@
|
||||
var ATEditor = (function(ATEditor, model) {
|
||||
|
||||
function isWeaponCategory(itemCategory) {
|
||||
if (!itemCategory) { return false; }
|
||||
if (itemCategory.actionType != 2) { return false; }
|
||||
if (itemCategory.inventorySlot != 0) { return false; }
|
||||
return true;
|
||||
}
|
||||
function isWeaponType(obj) {
|
||||
return isWeaponCategory(obj.category);
|
||||
}
|
||||
|
||||
function getItemCost(obj) {
|
||||
if (obj.hasManualPrice == 1) {
|
||||
return obj.baseMarketCost;
|
||||
}
|
||||
return calculateItemCost(obj);
|
||||
}
|
||||
|
||||
function calculateItemCost(obj) {
|
||||
var v = function(i) { return i ? parseFloat(i) : 0; }
|
||||
var sgn = function(v) {
|
||||
if (v < 0) return -1;
|
||||
else if (v > 0) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
var averageHPBoost = (v(obj.useEffect.increaseCurrentHP.min) + v(obj.useEffect.increaseCurrentHP.max)) / 2;
|
||||
var costBoostHP = Math.round(0.1*sgn(averageHPBoost)*Math.pow(Math.abs(averageHPBoost), 2) + 3*averageHPBoost);
|
||||
var itemUsageCost = costBoostHP;
|
||||
|
||||
|
||||
var isWeapon = isWeaponType(obj);
|
||||
|
||||
var equip_blockChance = v(obj.equipEffect.increaseBlockChance);
|
||||
var equip_attackChance = v(obj.equipEffect.increaseAttackChance);
|
||||
var equip_attackCost = v(obj.equipEffect.increaseAttackCost);
|
||||
var equip_damageResistance = v(obj.equipEffect.increaseDamageResistance);
|
||||
var equip_attackDamage_Min = v(obj.equipEffect.increaseAttackDamage.min);
|
||||
var equip_attackDamage_Max = v(obj.equipEffect.increaseAttackDamage.max);
|
||||
var equip_criticalChance = v(obj.equipEffect.increaseCriticalSkill);
|
||||
var equip_criticalMultiplier = v(obj.equipEffect.setCriticalMultiplier);
|
||||
var costBC = Math.round(3*Math.pow(Math.max(0,equip_blockChance), 2.5) + 28*equip_blockChance);
|
||||
var costAC = Math.round(0.4*Math.pow(Math.max(0,equip_attackChance), 2.5) - 6*Math.pow(Math.abs(Math.min(0,equip_attackChance)),2.7));
|
||||
var costAP = isWeapon ?
|
||||
Math.round(0.2*Math.pow(10/equip_attackCost, 8) - 25*equip_attackCost)
|
||||
: -3125 * equip_attackCost;
|
||||
var costDR = 1325*equip_damageResistance;
|
||||
var costDMG_Min = isWeapon ?
|
||||
Math.round(10*Math.pow(equip_attackDamage_Min, 2.5))
|
||||
:Math.round(10*Math.pow(equip_attackDamage_Min, 3) + equip_attackDamage_Min*80);
|
||||
var costDMG_Max = isWeapon ?
|
||||
Math.round(2*Math.pow(equip_attackDamage_Max, 2.1))
|
||||
:Math.round(2*Math.pow(equip_attackDamage_Max, 3) + equip_attackDamage_Max*20);
|
||||
var costCC = Math.round(2.2*Math.pow(equip_criticalChance, 3));
|
||||
var costCM = Math.round(50*Math.pow(Math.max(0, equip_criticalMultiplier), 2));
|
||||
var costCombat = costBC + costAC + costAP + costDR + costDMG_Min + costDMG_Max + costCC + costCM;
|
||||
|
||||
var equip_boostMaxHP = v(obj.equipEffect.increaseMaxHP);
|
||||
var equip_boostMaxAP = v(obj.equipEffect.increaseMaxAP);
|
||||
var equip_moveCostPenalty = v(obj.equipEffect.increaseMoveCost);
|
||||
var costMaxHP = Math.round(30*Math.pow(Math.max(0,equip_boostMaxHP), 1.2) + 70*equip_boostMaxHP);
|
||||
var costMaxAP = Math.round(50*Math.pow(Math.max(0,equip_boostMaxAP), 3) + 750*equip_boostMaxAP);
|
||||
var costMovement = Math.round(510*Math.pow(Math.max(0,-equip_moveCostPenalty), 2.5) - 350*equip_moveCostPenalty);
|
||||
var itemEquipCost = costCombat + costMaxHP + costMaxAP + costMovement;
|
||||
|
||||
if (!obj.hasEquipEffect) { itemEquipCost = 0; }
|
||||
if (!obj.hasUseEffect) { itemUsageCost = 0; }
|
||||
|
||||
var result = itemEquipCost + itemUsageCost;
|
||||
if (result <= 0) { result = 1; }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function setCategoryToObject(item, itemCategories) {
|
||||
if (_.isString(item.category)) {
|
||||
item.category = itemCategories.findById(item.category);
|
||||
}
|
||||
}
|
||||
|
||||
function ItemController($scope, $routeParams) {
|
||||
$scope.obj = model.items.findById($routeParams.id) || {};
|
||||
$scope.itemCategories = model.itemCategories.items;
|
||||
setCategoryToObject($scope.obj, model.itemCategories);
|
||||
|
||||
$scope.$watch('obj.category', function(val) {
|
||||
$scope.isWeapon = isWeaponCategory(val);
|
||||
});
|
||||
$scope.$watch('obj.hasManualPrice', function(hasManualPrice) {
|
||||
$scope.obj.baseMarketCost = hasManualPrice ? calculateItemCost($scope.obj) : 0;
|
||||
});
|
||||
|
||||
$scope.getItemCost = getItemCost;
|
||||
$scope.getItemSellingCost = function(obj) {
|
||||
var cost = getItemCost(obj);
|
||||
return Math.round(cost * (100 + 15) / 100);
|
||||
};
|
||||
$scope.getItemBuyingCost = function(obj) {
|
||||
var cost = getItemCost(obj);
|
||||
return Math.round(cost * (100 - 15) / 100);
|
||||
};
|
||||
|
||||
|
||||
$scope.addCondition = function(list) {
|
||||
list.push({magnitude:1});
|
||||
};
|
||||
$scope.removeCondition = function(list, cond) {
|
||||
var idx = list.indexOf(cond);
|
||||
list.splice(idx, 1);
|
||||
};
|
||||
}
|
||||
|
||||
function ItemTableController($scope, $routeParams) {
|
||||
$scope.items = model.items.items;
|
||||
$scope.itemCategories = model.itemCategories.items;
|
||||
_.each($scope.items, function(item) {
|
||||
setCategoryToObject(item, model.itemCategories);
|
||||
});
|
||||
$scope.getItemCost = getItemCost;
|
||||
$scope.edit = function(item) {
|
||||
window.location = "#/" + model.items.id + "/edit/" + item.id;
|
||||
};
|
||||
$scope.updateCost = function(item) {
|
||||
item.baseMarketCost = item.hasManualPrice ? calculateItemCost(item) : 0;
|
||||
};
|
||||
|
||||
$scope.iconID = true;
|
||||
$scope.id = true;
|
||||
$scope.cost = true;
|
||||
}
|
||||
|
||||
ATEditor.controllers = ATEditor.controllers || {};
|
||||
ATEditor.controllers.ItemController = ItemController;
|
||||
ATEditor.controllers.ItemTableController = ItemTableController;
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.model);
|
||||
12
AndorsTrailEdit/js/controllers/itemcategory.js
Normal file
12
AndorsTrailEdit/js/controllers/itemcategory.js
Normal file
@@ -0,0 +1,12 @@
|
||||
var ATEditor = (function(ATEditor, model) {
|
||||
|
||||
function ItemCategoryController($scope, $routeParams) {
|
||||
$scope.datasource = model.itemCategories;
|
||||
$scope.obj = $scope.datasource.findById($routeParams.id);
|
||||
};
|
||||
|
||||
ATEditor.controllers = ATEditor.controllers || {};
|
||||
ATEditor.controllers.ItemCategoryController = ItemCategoryController;
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.model);
|
||||
58
AndorsTrailEdit/js/controllers/monster.js
Normal file
58
AndorsTrailEdit/js/controllers/monster.js
Normal file
@@ -0,0 +1,58 @@
|
||||
var ATEditor = (function(ATEditor, model) {
|
||||
|
||||
function getExperience(obj) {
|
||||
var EXP_FACTOR_DAMAGERESISTANCE = 9;
|
||||
var EXP_FACTOR_SCALING = 0.7;
|
||||
|
||||
var div100 = function(v) { return v / 100; }
|
||||
var v = function(i) { return i ? i : 0; }
|
||||
|
||||
var attacksPerTurn = Math.floor(v(obj.maxAP) / v(obj.attackCost));
|
||||
var avgDamagePotential = 0;
|
||||
if (obj.attackDamage) { avgDamagePotential = (v(obj.attackDamage.min) + v(obj.attackDamage.max)) / 2; }
|
||||
var avgCrit = 0;
|
||||
if (obj.hasCritical) {
|
||||
avgCrit = div100(v(obj.criticalSkill)) * v(obj.criticalMultiplier);
|
||||
}
|
||||
var avgAttackHP = attacksPerTurn * div100(v(obj.attackChance)) * avgDamagePotential * (1 + avgCrit);
|
||||
var avgDefenseHP = v(obj.maxHP) * (1 + div100(v(obj.blockChance))) + EXP_FACTOR_DAMAGERESISTANCE * v(obj.damageResistance);
|
||||
var attackConditionBonus = 0;
|
||||
if (obj.hitEffect && obj.hitEffect.conditionsTarget && v(obj.hitEffect.conditionsTarget.length) > 0) {
|
||||
attackConditionBonus = 50;
|
||||
}
|
||||
var experience = (avgAttackHP * 3 + avgDefenseHP) * EXP_FACTOR_SCALING + attackConditionBonus;
|
||||
|
||||
return Math.ceil(experience);
|
||||
};
|
||||
|
||||
function MonsterController($scope, $routeParams) {
|
||||
$scope.obj = model.monsters.findById($routeParams.id) || {};
|
||||
$scope.getExperience = function() { return getExperience($scope.obj); }
|
||||
|
||||
$scope.addCondition = function(list) {
|
||||
list.push({magnitude:1, duration:1, chance:100});
|
||||
};
|
||||
$scope.removeCondition = function(list, cond) {
|
||||
var idx = list.indexOf(cond);
|
||||
list.splice(idx, 1);
|
||||
};
|
||||
}
|
||||
|
||||
function MonsterTableController($scope, $routeParams) {
|
||||
$scope.monsters = model.monsters.items;
|
||||
$scope.getExperience = getExperience;
|
||||
$scope.edit = function(monster) {
|
||||
window.location = "#/" + model.monsters.id + "/edit/" + monster.id;
|
||||
};
|
||||
|
||||
$scope.iconID = true;
|
||||
$scope.id = true;
|
||||
$scope.experience = true;
|
||||
}
|
||||
|
||||
ATEditor.controllers = ATEditor.controllers || {};
|
||||
ATEditor.controllers.MonsterController = MonsterController;
|
||||
ATEditor.controllers.MonsterTableController = MonsterTableController;
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.model);
|
||||
56
AndorsTrailEdit/js/controllers/navigation.js
Normal file
56
AndorsTrailEdit/js/controllers/navigation.js
Normal file
@@ -0,0 +1,56 @@
|
||||
var ATEditor = (function(ATEditor, model, importExport, exampleData) {
|
||||
|
||||
function NavigationController($scope, $routeParams, $http) {
|
||||
$scope.sections = model.sections;
|
||||
$scope.previousItems = [];
|
||||
|
||||
$scope.editObj = function(section, obj) {
|
||||
$scope.previousItems = _.reject($scope.previousItems, function(i) {
|
||||
return (i.section === section) && (i.obj === obj);
|
||||
});
|
||||
$scope.previousItems.unshift({section: section, obj: obj});
|
||||
if ($scope.previousItems.length > 5) {
|
||||
$scope.previousItems.pop();
|
||||
}
|
||||
window.location = "#/" + section.id + "/edit/" + obj.id;
|
||||
};
|
||||
$scope.addObj = function(section) {
|
||||
var item = section.addNew();
|
||||
importExport.prepareObjectsForEditor(section, [ item ]);
|
||||
$scope.editObj(section, item);
|
||||
};
|
||||
$scope.clear = function(section) {
|
||||
if(!confirm("Are you sure you want to clear all " + section.name + " ?")) return;
|
||||
section.clear();
|
||||
};
|
||||
$scope.getName = function(section, obj) {
|
||||
return section.getName(obj);
|
||||
}
|
||||
$scope.delObj = function(section, obj) {
|
||||
if(!confirm("Are you sure you want to remove " + section.getName(obj) + " ?")) return;
|
||||
this.destroy(function() {
|
||||
section.remove(obj);
|
||||
});
|
||||
};
|
||||
$scope.dupObj = function(section, obj) {
|
||||
var item = section.clone(obj);
|
||||
$scope.editObj(section, item);
|
||||
};
|
||||
$scope.supportsTableEdit = function(section) {
|
||||
if (section.id == ATEditor.model.monsters.id) { return true; }
|
||||
if (section.id == ATEditor.model.items.id) { return true; }
|
||||
return false;
|
||||
};
|
||||
$scope.editAsTable = function(section) {
|
||||
window.location = "#/" + section.id + "/table";
|
||||
};
|
||||
|
||||
|
||||
exampleData.init($http);
|
||||
};
|
||||
|
||||
ATEditor.controllers = ATEditor.controllers || {};
|
||||
ATEditor.controllers.NavigationController = NavigationController;
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.model, ATEditor.importExport, ATEditor.exampleData);
|
||||
19
AndorsTrailEdit/js/controllers/quest.js
Normal file
19
AndorsTrailEdit/js/controllers/quest.js
Normal file
@@ -0,0 +1,19 @@
|
||||
var ATEditor = (function(ATEditor, model) {
|
||||
|
||||
function QuestController($scope, $routeParams) {
|
||||
$scope.datasource = model.quests;
|
||||
$scope.obj = $scope.datasource.findById($routeParams.id);
|
||||
$scope.addQuestStage = function() {
|
||||
$scope.obj.stages.push({});
|
||||
};
|
||||
$scope.removeQuestStage = function(stage) {
|
||||
var idx = $scope.obj.stages.indexOf(stage);
|
||||
$scope.obj.stages.splice(idx, 1);
|
||||
};
|
||||
};
|
||||
|
||||
ATEditor.controllers = ATEditor.controllers || {};
|
||||
ATEditor.controllers.QuestController = QuestController;
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.model);
|
||||
26
AndorsTrailEdit/js/controllers/selecticon.js
Normal file
26
AndorsTrailEdit/js/controllers/selecticon.js
Normal file
@@ -0,0 +1,26 @@
|
||||
var ATEditor = (function(ATEditor, tilesets) {
|
||||
|
||||
function SelectIconController($scope, $routeParams) {
|
||||
var _callback = function() {};
|
||||
$scope.selectedSection = '';
|
||||
$scope.sections = [];
|
||||
_.each([ 'monster', 'item', 'actorcondition' ], function(id) {
|
||||
$scope.sections.push({id: id, imageIDs: tilesets.getIconIDsForSection(id)});
|
||||
});
|
||||
|
||||
this.startSelecting = function(sectionId, callback) {
|
||||
_callback = callback;
|
||||
$scope.selectedSection = sectionId;
|
||||
$scope.$apply();
|
||||
};
|
||||
|
||||
$scope.imageSelected = function(iconID) {
|
||||
if (_callback) { _callback(iconID); }
|
||||
};
|
||||
};
|
||||
|
||||
ATEditor.controllers = ATEditor.controllers || {};
|
||||
ATEditor.controllers.SelectIconController = SelectIconController;
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.tilesets);
|
||||
88
AndorsTrailEdit/js/datastore.js
Normal file
88
AndorsTrailEdit/js/datastore.js
Normal file
@@ -0,0 +1,88 @@
|
||||
var ATEditor = (function(ATEditor, _) {
|
||||
|
||||
ATEditor.DataStore = function(options) {
|
||||
var defaultOptions = {
|
||||
nameField: 'name'
|
||||
,idField: 'id'
|
||||
};
|
||||
_.defaults(options, defaultOptions);
|
||||
|
||||
var items = [];
|
||||
this.items = items;
|
||||
|
||||
this.name = options.name;
|
||||
this.id = options.id;
|
||||
|
||||
this.findById = function(id) {
|
||||
return _.find(this.items, function(obj) { return obj[options.idField] === id; });
|
||||
};
|
||||
this.hasObjectWithId = function(id) {
|
||||
return _.some(this.items, function(obj) { return obj[options.idField] === id; });
|
||||
};
|
||||
this.hasIcon = function() { return _.toBool(options.iconIDField); };
|
||||
this.getIcon = function(obj) { return obj[options.iconIDField]; };
|
||||
this.getId = function(obj) { return obj[options.idField]; };
|
||||
this.getName = function(obj) {
|
||||
return obj[options.nameField];
|
||||
};
|
||||
this.addNew = function(suggestedId) {
|
||||
var obj = { };
|
||||
if (!suggestedId) { suggestedId = 'new_' + options.id; }
|
||||
obj[options.idField] = suggestedId;
|
||||
if (options.idField != options.nameField) {
|
||||
obj[options.nameField] = 'New ' + options.id;
|
||||
}
|
||||
this.ensureUniqueId(obj);
|
||||
items.push(obj);
|
||||
return obj;
|
||||
};
|
||||
this.add = function(o) {
|
||||
items.push(o);
|
||||
};
|
||||
this.clone = function(o) {
|
||||
var obj = ATEditor.utils.deepClone(o);
|
||||
this.ensureUniqueId(obj);
|
||||
items.push(obj);
|
||||
return obj;
|
||||
};
|
||||
this.remove = function(o) {
|
||||
var idx = items.indexOf(o);
|
||||
if (idx >= 0) {
|
||||
items.splice(idx, 1);
|
||||
}
|
||||
};
|
||||
this.clear = function() {
|
||||
items = [];
|
||||
this.items = items;
|
||||
};
|
||||
|
||||
this.findFirstFreeId = function(id) {
|
||||
if(!this.hasObjectWithId(id)) {
|
||||
return id;
|
||||
}
|
||||
|
||||
var prefix;
|
||||
var n = 1;
|
||||
|
||||
var match = (/^(.*\D)(\d+)$/g).exec(id);
|
||||
if (match) {
|
||||
prefix = match[1];
|
||||
n = parseInt(match[2]) + 1;
|
||||
} else {
|
||||
prefix = id + "_";
|
||||
}
|
||||
|
||||
var result = prefix + n;
|
||||
while(this.hasObjectWithId(result)) {
|
||||
n = n + 1;
|
||||
result = prefix + n;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
this.ensureUniqueId = function(obj) {
|
||||
obj[options.idField] = this.findFirstFreeId(obj[options.idField]);
|
||||
};
|
||||
};
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor || {}, _);
|
||||
65
AndorsTrailEdit/js/defaults.js
Normal file
65
AndorsTrailEdit/js/defaults.js
Normal file
@@ -0,0 +1,65 @@
|
||||
var ATEditor = (function(ATEditor, _) {
|
||||
|
||||
var defaults = {
|
||||
actorcondition: {
|
||||
isStacking: 0
|
||||
,isPositive: 0
|
||||
,roundEffect: { visualEffectID: -1, increaseCurrentHP: {}, increaseCurrentAP: {} }
|
||||
,fullRoundEffect: { visualEffectID: -1, increaseCurrentHP: {}, increaseCurrentAP: {} }
|
||||
,abilityEffect: { increaseAttackDamage: {} }
|
||||
}
|
||||
,quest: {
|
||||
showInLog: 0
|
||||
,stages: []
|
||||
}
|
||||
,item: {
|
||||
displaytype: 0
|
||||
,hasManualPrice: 0
|
||||
,category: 'other'
|
||||
,equipEffect: { increaseAttackDamage: {}, addedConditions: [] }
|
||||
,useEffect: { increaseCurrentHP: {}, increaseCurrentAP: {}, conditionsSource: [], conditionsTarget: [] }
|
||||
,hitEffect: { increaseCurrentHP: {}, increaseCurrentAP: {}, conditionsSource: [], conditionsTarget: [] }
|
||||
,killEffect: { increaseCurrentHP: {}, increaseCurrentAP: {}, conditionsSource: [], conditionsTarget: [] }
|
||||
}
|
||||
,droplist: {
|
||||
items: []
|
||||
}
|
||||
,dialogue: {
|
||||
rewards: []
|
||||
,replies: []
|
||||
}
|
||||
,monster: {
|
||||
size: "1x1"
|
||||
,maxHP: 1
|
||||
,maxAP: 10
|
||||
,moveCost: 10
|
||||
,unique: 0
|
||||
,monsterClass: 0
|
||||
,attackDamage: {}
|
||||
,hitEffect: { increaseCurrentHP: {}, increaseCurrentAP: {}, conditionsSource: [], conditionsTarget: [] }
|
||||
}
|
||||
,itemcategory: {
|
||||
actionType: 0
|
||||
,inventorySlot: -1
|
||||
,size: 0
|
||||
}
|
||||
,reply: {
|
||||
requires: { item: { requireType: 0 } }
|
||||
}
|
||||
};
|
||||
|
||||
ATEditor.defaults = {
|
||||
addDefaults: function(type, o) {
|
||||
var def = defaults[type];
|
||||
if (def) {
|
||||
var copyOfDefaults = ATEditor.utils.deepClone(def);
|
||||
ATEditor.utils.copyDefaults(o, copyOfDefaults);
|
||||
}
|
||||
},
|
||||
removeDefaults: function(type, o) {
|
||||
return ATEditor.utils.removeDefaults(o, defaults[type]);
|
||||
}
|
||||
};
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor || {}, _);
|
||||
89
AndorsTrailEdit/js/directives.js
Normal file
89
AndorsTrailEdit/js/directives.js
Normal file
@@ -0,0 +1,89 @@
|
||||
var ATEditor = (function(ATEditor, app, tilesets, $) {
|
||||
|
||||
// Copied from http://jsfiddle.net/p69aT/
|
||||
// -> originally from https://groups.google.com/forum/?fromgroups=#!topic/angular/7XVOebG6z6E
|
||||
app.directive('fadey', function() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, elm, attrs) {
|
||||
elm = $(elm);
|
||||
elm.hide();
|
||||
elm.fadeIn();
|
||||
|
||||
scope.destroy = function(complete) {
|
||||
elm.slideUp(function() {
|
||||
if (complete) {
|
||||
complete.apply(scope);
|
||||
}
|
||||
});
|
||||
elm.fadeOut();
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
// Copied from
|
||||
// http://www.codeproject.com/Articles/464939/Angular-JS-Using-Directives-to-Create-Custom-Attri
|
||||
app.directive('ngDsFade', function () {
|
||||
return function(scope, element, attrs) {
|
||||
element.css('display', 'none');
|
||||
scope.$watch(attrs.ngDsFade, function(value) {
|
||||
if (value) {
|
||||
element.fadeIn(400);
|
||||
} else {
|
||||
element.fadeOut(300);
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
app.directive('ngTileImage', function () {
|
||||
return function(scope, element, attrs) {
|
||||
var scale = attrs.ngTileImageScale;
|
||||
if (!scale) scale = 1;
|
||||
|
||||
scope.$watch(attrs.ngTileImage, function(value) {
|
||||
var img = tilesets.parseImageID(value);
|
||||
var tileset = tilesets.getTileset(img.tilesetName);
|
||||
var c = tileset.localIDToCoords(img.localID);
|
||||
element.css({
|
||||
"background-image": "url(" +img.path + img.tilesetName + ".png)",
|
||||
"background-position": (-c.x)*scale+"px " + (-c.y)*scale+"px",
|
||||
"width": tileset._tileSize.x * scale + "px",
|
||||
"height": tileset._tileSize.y * scale + "px",
|
||||
"cursor": "pointer"
|
||||
});
|
||||
if (scale && (scale != 1)) {
|
||||
element.css({
|
||||
"background-size":
|
||||
tileset._tileSize.x * tileset._numTiles.x * scale + "px "
|
||||
+ tileset._tileSize.y * tileset._numTiles.y * scale + "px "
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
app.directive('ngSelectImage', function () {
|
||||
return {
|
||||
link : function(scope, element, attrs) {
|
||||
function openDialog() {
|
||||
var element = angular.element('#selectIconModal');
|
||||
var ctrl = element.controller();
|
||||
ctrl.startSelecting(attrs.ngSelectImage, function(iconID) {
|
||||
element.modal('hide');
|
||||
var s = attrs.ngSelectImageDest || 'iconID';
|
||||
eval("scope." + s + "='" + iconID + "'");
|
||||
});
|
||||
element.modal('show');
|
||||
}
|
||||
element.bind('click', openDialog);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.app, ATEditor.tilesets, jQuery);
|
||||
82
AndorsTrailEdit/js/exampledata.js
Normal file
82
AndorsTrailEdit/js/exampledata.js
Normal file
@@ -0,0 +1,82 @@
|
||||
var ATEditor = (function(ATEditor, model, utils, _, $) {
|
||||
|
||||
var http;
|
||||
var resources = {};
|
||||
|
||||
function loadUrlFromGit(relativeUrl, successCallback, errorCallback) {
|
||||
var url = utils.getUrlRelativeToBaseSrcDir(relativeUrl);
|
||||
http.get(url)
|
||||
.success(function(data, status, headers, config) {
|
||||
successCallback(data);
|
||||
}).error(function(data, status, headers, config) {
|
||||
if(errorCallback) { errorCallback(status); }
|
||||
});
|
||||
}
|
||||
|
||||
function addExampleModelItems() {
|
||||
var _import = function(section, data) {
|
||||
ATEditor.importExport.importDataObjects(section, data);
|
||||
};
|
||||
|
||||
_import(model.quests, [
|
||||
{id: "testQuest", name: "Test quest", showInLog: 1, stages: [ { progress: 10, logText: "Stage 10"} , { progress: 20, logText: "Stage 20", finishesQuest: 1 } ] }
|
||||
]);
|
||||
}
|
||||
|
||||
function init($http) {
|
||||
http = $http;
|
||||
|
||||
// http://andors-trail.googlecode.com/git/AndorsTrail/res/values/loadresources.xml
|
||||
loadUrlFromGit("AndorsTrail/res/values/loadresources.xml", function(data) {
|
||||
var parseListOfResourceFiles = function(xmlname, section) {
|
||||
var items = [];
|
||||
resources[section.id] = items;
|
||||
$(data).find("array[name='" + xmlname + "'] item").each(function(idx, f) {
|
||||
var match = (/^@.*\/(.+)$/g).exec($(f).text());
|
||||
if (match) {
|
||||
items.push(match[1] + ".json");
|
||||
}
|
||||
});
|
||||
};
|
||||
parseListOfResourceFiles("loadresource_itemcategories", model.itemCategories);
|
||||
parseListOfResourceFiles("loadresource_actorconditions", model.actorConditions);
|
||||
parseListOfResourceFiles("loadresource_items", model.items);
|
||||
parseListOfResourceFiles("loadresource_droplists", model.droplists);
|
||||
parseListOfResourceFiles("loadresource_quests", model.quests);
|
||||
parseListOfResourceFiles("loadresource_conversationlists", model.dialogue);
|
||||
parseListOfResourceFiles("loadresource_monsters", model.monsters);
|
||||
|
||||
_.each(resources['itemcategory'], function(file) {
|
||||
loadUrlFromGit("AndorsTrail/res/raw/" + file, function(data) {
|
||||
ATEditor.importExport.importDataObjects(model.itemCategories, data);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
loadUrlFromGit("AndorsTrail/res/raw/actorconditions_v069.json", function(data) {
|
||||
ATEditor.importExport.importDataObjects(model.actorConditions, data);
|
||||
});
|
||||
loadUrlFromGit("AndorsTrail/res/raw/conversationlist_mikhail.json", function(data) {
|
||||
ATEditor.importExport.importDataObjects(model.dialogue, data);
|
||||
});
|
||||
loadUrlFromGit("AndorsTrail/res/raw/droplists_crossglen.json", function(data) {
|
||||
ATEditor.importExport.importDataObjects(model.droplists, data);
|
||||
});
|
||||
loadUrlFromGit("AndorsTrail/res/raw/monsterlist_crossglen_animals.json", function(data) {
|
||||
ATEditor.importExport.importDataObjects(model.monsters, data);
|
||||
});
|
||||
loadUrlFromGit("AndorsTrail/res/raw/itemlist_v069_2.json", function(data) {
|
||||
ATEditor.importExport.importDataObjects(model.items, data);
|
||||
});
|
||||
|
||||
addExampleModelItems(model);
|
||||
}
|
||||
|
||||
ATEditor.exampleData = {
|
||||
init: init
|
||||
,resources: resources
|
||||
,loadUrlFromGit: loadUrlFromGit
|
||||
};
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.model, ATEditor.utils, _, jQuery);
|
||||
205
AndorsTrailEdit/js/fieldlist.js
Normal file
205
AndorsTrailEdit/js/fieldlist.js
Normal file
@@ -0,0 +1,205 @@
|
||||
|
||||
var ATEditor = (function(ATEditor) {
|
||||
var FieldList_Header_fieldName = '[^\\[\\]\\|]*';
|
||||
var FieldList_Header_arrayField = FieldList_Header_fieldName + '\\[(' + FieldList_Header_fieldName + '\\|)*\\]';
|
||||
var FieldList_Header_arrayFieldName = new RegExp(FieldList_Header_fieldName);
|
||||
var FieldList_Header_field = '(' + FieldList_Header_fieldName + '|' + FieldList_Header_arrayField + ')\\|';
|
||||
var FieldList_Header_pattern = new RegExp(FieldList_Header_field, 'g');
|
||||
var FieldList_Header_line = "^(\\[(" + FieldList_Header_field + ")*\\];)$";
|
||||
var FieldList_Header_linePattern = new RegExp(FieldList_Header_line, 'm');
|
||||
|
||||
function FieldList(header, name) {
|
||||
this._name = name ? name : "";
|
||||
this._fields = [];
|
||||
|
||||
var match = header.match(FieldList_Header_pattern);
|
||||
if (!match) return;
|
||||
|
||||
for (var i = 0; i < match.length; ++i) {
|
||||
var s = match[i].match(FieldList_Header_field)[1]; // Strip trailing pipe
|
||||
|
||||
var f = s;
|
||||
if (s.match(FieldList_Header_arrayField)) {
|
||||
var name = s.match(FieldList_Header_arrayFieldName)[0];
|
||||
f = new FieldList(s, name);
|
||||
}
|
||||
this._fields[i] = f;
|
||||
}
|
||||
|
||||
this.getFieldName = function(i) {
|
||||
var f = this._fields[i];
|
||||
if (f instanceof FieldList) {
|
||||
return f._name;
|
||||
} else {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
this.getHeader = function() {
|
||||
var result = this._name + "[";
|
||||
for(var i = 0; i < this._fields.length; ++i) {
|
||||
var f = this._fields[i];
|
||||
if (f instanceof FieldList) {
|
||||
result += f.getHeader();
|
||||
} else {
|
||||
result += f;
|
||||
}
|
||||
result += "|";
|
||||
}
|
||||
result += "]";
|
||||
return result;
|
||||
}
|
||||
|
||||
this.getHeaderLine = function() {
|
||||
return this.getHeader() + ";";
|
||||
}
|
||||
};
|
||||
|
||||
function findHeader(str) {
|
||||
var match = str.match(FieldList_Header_linePattern);
|
||||
if (!match) return;
|
||||
return new FieldList(match[0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
var DataStore_Data_fieldValue = '[^\\{\\}\\|]*';
|
||||
var DataStore_Data_arrayObject = '\\{(' + DataStore_Data_fieldValue + '\\|)*\\}\\s*';
|
||||
var DataStore_Data_arrayObjectPattern = new RegExp(DataStore_Data_arrayObject, 'g');
|
||||
var DataStore_Data_arrayField = '\\{\\s*(' + DataStore_Data_arrayObject + ')*\\s*\\}';
|
||||
var DataStore_Data_field = '(' + DataStore_Data_fieldValue + '|' + DataStore_Data_arrayField + ')\\|';
|
||||
var DataStore_Data_pattern = new RegExp(DataStore_Data_field, 'gm');
|
||||
var DataStore_Data_line = "^(\\{(" + DataStore_Data_field + ")*\\};)$";
|
||||
var DataStore_Data_linePattern = new RegExp(DataStore_Data_line, 'gm');
|
||||
|
||||
var showErrorMessages = true;
|
||||
|
||||
var specialEncodings = [
|
||||
{
|
||||
decoded: "'", decoded_Regex: /'/gm,
|
||||
encoded: "\\'", encoded_Regex: /\\'/gm
|
||||
},
|
||||
{
|
||||
decoded: "\n", decoded_Regex: /\n/gm,
|
||||
encoded: "\\n", encoded_Regex: /\\n/gm
|
||||
}
|
||||
];
|
||||
|
||||
var deserialize = function(str) {
|
||||
var header = findHeader(str);
|
||||
if (!header) {
|
||||
return;
|
||||
}
|
||||
return {
|
||||
header: header
|
||||
,items: deserializeObjectList(header, str)
|
||||
};
|
||||
}
|
||||
var serialize = function(dataStore) {
|
||||
return serializeObjectList(dataStore.fieldList, dataStore.items);
|
||||
}
|
||||
|
||||
|
||||
function deserializeObject(fieldList, data) {
|
||||
var match = data.match(DataStore_Data_pattern);
|
||||
if (!match) return;
|
||||
|
||||
if (match.length != fieldList._fields.length) {
|
||||
if (showErrorMessages) {
|
||||
alert("Error parsing data object. Expected " + fieldList._fields.length + " fields, but found " + match.length + " fields.\ndata = \"" + data + "\"");
|
||||
showErrorMessages = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var obj = {};
|
||||
for (var i = 0; i < fieldList._fields.length; ++i) {
|
||||
var s = match[i].match(DataStore_Data_field)[1]; // Strip trailing pipe
|
||||
|
||||
var f = fieldList._fields[i];
|
||||
var v = s;
|
||||
var fieldName = fieldList.getFieldName(i);
|
||||
if (f instanceof FieldList) {
|
||||
fieldName = f._name;
|
||||
v = [];
|
||||
var objects = s.match(DataStore_Data_arrayObjectPattern);
|
||||
if (objects) {
|
||||
for (var j = 0; j < objects.length; ++j) {
|
||||
v[j] = deserializeObject(f, objects[j]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(var j = 0; j < specialEncodings.length; ++j) {
|
||||
var e = specialEncodings[j];
|
||||
v = v.replace(e.encoded_Regex, e.decoded);
|
||||
}
|
||||
}
|
||||
obj[fieldName] = v;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function deserializeObjectList(fieldList, data) {
|
||||
var result = [];
|
||||
if(!data) return result;
|
||||
var match = data.match(DataStore_Data_linePattern);
|
||||
if(!match) return result;
|
||||
for(var i = 0; i < match.length; ++i) {
|
||||
result[i] = deserializeObject(fieldList, match[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function serializeObject(fieldList, obj) {
|
||||
if (!obj) return "";
|
||||
var result = "{";
|
||||
|
||||
for(var i = 0; i < fieldList._fields.length; ++i) {
|
||||
var fieldName = fieldList.getFieldName(i);
|
||||
var f = fieldList._fields[i];
|
||||
var v = obj[fieldName];
|
||||
if (f instanceof FieldList) {
|
||||
if (v && v.length > 0) {
|
||||
result += "{";
|
||||
if (v.length > 1) { result += "\n"; }
|
||||
for(var j = 0; j < v.length; ++j) {
|
||||
if (v.length > 1) { result += "\t"; }
|
||||
result += serializeObject(f, v[j]);
|
||||
if (v.length > 1) { result += "\n"; }
|
||||
}
|
||||
if (v.length > 1) { result += "\t"; }
|
||||
result += "}";
|
||||
}
|
||||
} else if (v != undefined) {
|
||||
v = "" + v;
|
||||
for(var j = 0; j < specialEncodings.length; ++j) {
|
||||
var e = specialEncodings[j];
|
||||
v = v.replace(e.decoded_Regex, e.encoded);
|
||||
}
|
||||
result += v;
|
||||
}
|
||||
result += "|";
|
||||
}
|
||||
result += "}";
|
||||
return result;
|
||||
}
|
||||
|
||||
function serializeObjectList(fieldList, obj) {
|
||||
var result = fieldList.getHeader() + ";\n";
|
||||
if(!obj) return result;
|
||||
|
||||
for(var i = 0; i < obj.length; ++i) {
|
||||
result += serializeObject(fieldList, obj[i]) + ";\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ATEditor.FieldList = FieldList;
|
||||
|
||||
ATEditor.legacy = ATEditor.legacy || {};
|
||||
ATEditor.legacy.deserialize = deserialize;
|
||||
ATEditor.legacy.serialize = serialize;
|
||||
ATEditor.legacy.findHeader = findHeader;
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor || {});
|
||||
195
AndorsTrailEdit/js/importexport.js
Normal file
195
AndorsTrailEdit/js/importexport.js
Normal file
@@ -0,0 +1,195 @@
|
||||
var ATEditor = (function(ATEditor, _) {
|
||||
|
||||
var prep = {};
|
||||
prep.actorcondition = function(o) {
|
||||
o.hasRoundEffect = ATEditor.utils.hasValues(_.omit(o.roundEffect, 'visualEffectID'));
|
||||
o.hasFullRoundEffect = ATEditor.utils.hasValues(_.omit(o.fullRoundEffect, 'visualEffectID'));
|
||||
o.hasAbilityEffect = ATEditor.utils.hasValues(o.abilityEffect);
|
||||
};
|
||||
prep.quest = function(o) {
|
||||
};
|
||||
prep.item = function(o) {
|
||||
o.hasEquipEffect = ATEditor.utils.hasValues(o.equipEffect);
|
||||
o.hasUseEffect = ATEditor.utils.hasValues(o.useEffect);
|
||||
o.hasHitEffect = ATEditor.utils.hasValues(o.hitEffect);
|
||||
o.hasKillEffect = ATEditor.utils.hasValues(o.killEffect);
|
||||
};
|
||||
prep.droplist = function(o) {
|
||||
};
|
||||
prep.dialogue = function(o) {
|
||||
o.hasRewards = ATEditor.utils.hasValues(o.rewards);
|
||||
if (o.replies.length === 1 && o.replies[0].text === "N") {
|
||||
o.nextPhraseID = o.replies[0].nextPhraseID;
|
||||
o.hasOnlyNextReply = true;
|
||||
} else {
|
||||
o.nextPhraseID = "";
|
||||
o.hasOnlyNextReply = false;
|
||||
}
|
||||
_.each(o.replies, function(reply) {
|
||||
ATEditor.defaults.addDefaults('reply', reply);
|
||||
if (reply.nextPhraseID && reply.nextPhraseID.length === 1) { reply.replyLeadsTo = reply.nextPhraseID; }
|
||||
reply.requiresItems = ATEditor.utils.hasValues(reply.requires.item);
|
||||
reply.requiresQuest = _.toBool(reply.requires.progress);
|
||||
});
|
||||
};
|
||||
prep.monster = function(o) {
|
||||
o.hasConversation = _.toBool(o.phraseID);
|
||||
o.hasHitEffect = _.toBool(o.hitEffect.increaseCurrentHP.min || o.hitEffect.increaseCurrentAP.min || _.some(o.hitEffect.conditionsSource) || _.some(o.hitEffect.conditionsTarget));
|
||||
o.hasCritical = _.toBool(o.criticalSkill || o.criticalMultiplier);
|
||||
o.hasCombatTraits = _.toBool(o.attackChance || o.attackDamage.min || o.hasCritical || o.blockChance || o.damageResistance || o.hasHitEffect);
|
||||
o.showAdvanced = _.toBool(o.faction || (o.size != '1x1'));
|
||||
};
|
||||
prep.itemcategory = function(o) {
|
||||
};
|
||||
|
||||
function prepareObjectsForEditor(section, objs) {
|
||||
var p = prep[section.id];
|
||||
_.each(objs, function(o) {
|
||||
ATEditor.defaults.addDefaults(section.id, o);
|
||||
if (p) { p(o); }
|
||||
ATEditor.utils.convertIntegersToStrings(o);
|
||||
});
|
||||
}
|
||||
|
||||
var unprep = {};
|
||||
unprep.actorcondition = function(o) {
|
||||
if (!o.hasRoundEffect) { delete o.roundEffect; }
|
||||
if (!o.hasFullRoundEffect) { delete o.fullRoundEffect; }
|
||||
if (!o.hasAbilityEffect) { delete o.abilityEffect; }
|
||||
delete o.hasRoundEffect;
|
||||
delete o.hasFullRoundEffect;
|
||||
delete o.hasAbilityEffect;
|
||||
};
|
||||
unprep.quest = function(o) {
|
||||
};
|
||||
unprep.item = function(o) {
|
||||
if (!o.hasEquipAPEffect) {
|
||||
var e = o.equipEffect;
|
||||
delete e.increaseMaxAP;
|
||||
delete e.increaseMoveCost;
|
||||
delete e.increaseUseItemCost;
|
||||
delete e.increaseReequipCost;
|
||||
}
|
||||
delete o.hasEquipAPEffect;
|
||||
if (!o.hasEquipEffect) { delete o.equipEffect; }
|
||||
if (_.isObject(o.category)) { o.category = o.category.id; }
|
||||
if (!o.hasUseEffect) { delete o.useEffect; }
|
||||
if (!o.hasHitEffect) { delete o.hitEffect; }
|
||||
if (!o.hasKillEffect) { delete o.killEffect; }
|
||||
delete o.hasEquipEffect;
|
||||
delete o.hasUseEffect;
|
||||
delete o.hasHitEffect;
|
||||
delete o.hasKillEffect;
|
||||
};
|
||||
unprep.droplist = function(o) {
|
||||
};
|
||||
unprep.dialogue = function(o) {
|
||||
if (!o.hasRewards) { delete o.rewards; }
|
||||
delete o.hasRewards;
|
||||
_.each(o.replies, function(reply) {
|
||||
if (reply.replyLeadsTo) { reply.text = reply.replyLeadsTo; }
|
||||
delete reply.replyLeadsTo;
|
||||
var requires = reply.requires;
|
||||
if (!reply.requiresItems) { delete requires.item; }
|
||||
delete reply.requiresItems;
|
||||
if (!reply.requiresQuest) { delete requires.progress; }
|
||||
delete reply.requiresQuest;
|
||||
});
|
||||
if (o.hasOnlyNextReply) {
|
||||
o.replies = [ { text: "N", nextPhraseID: o.nextPhraseID } ];
|
||||
}
|
||||
delete o.nextPhraseID;
|
||||
delete o.hasOnlyNextReply;
|
||||
delete o.tree;
|
||||
};
|
||||
unprep.monster = function(o) {
|
||||
if (!o.hasCritical) {
|
||||
delete o.criticalSkill;
|
||||
delete o.criticalMultiplier;
|
||||
}
|
||||
if (!o.showAdvanced) {
|
||||
delete o.faction;
|
||||
delete o.size;
|
||||
}
|
||||
delete o.showAdvanced;
|
||||
delete o.hasCritical;
|
||||
delete o.hasConversation;
|
||||
delete o.hasCombatTraits;
|
||||
delete o.hasHitEffect;
|
||||
};
|
||||
unprep.itemcategory = function(o) {
|
||||
};
|
||||
|
||||
function prepareObjectsForExport(section, objs) {
|
||||
var p = unprep[section.id];
|
||||
return _.map(objs, function(o) {
|
||||
o = ATEditor.utils.deepClone(o);
|
||||
ATEditor.utils.removeAngularFields(o);
|
||||
if (p) { p(o); }
|
||||
ATEditor.utils.convertStringsToIntegers(o);
|
||||
ATEditor.defaults.removeDefaults(section.id, o);
|
||||
ATEditor.utils.compact(o);
|
||||
return o;
|
||||
});
|
||||
}
|
||||
|
||||
function importDataObjects(section, data, success, error) {
|
||||
if (!data || _.isEmpty(data)) {
|
||||
if (error) { error("No data?"); }
|
||||
return;
|
||||
}
|
||||
|
||||
var first = data;
|
||||
if (_.isArray(data)) {
|
||||
first = _.first(data);
|
||||
} else if (_.isObject(data)) {
|
||||
data = [ data ];
|
||||
} else {
|
||||
if (error) { error("Malformed data? Expected array or object."); }
|
||||
return;
|
||||
}
|
||||
|
||||
if (!section.getId(first)) {
|
||||
if (error) { error("Malformed data? Expected to find at least an id field, but no such field was found."); }
|
||||
return;
|
||||
}
|
||||
|
||||
prepareObjectsForEditor(section, data);
|
||||
|
||||
_.each(data, section.add);
|
||||
if (success) { success(); }
|
||||
};
|
||||
|
||||
function importText(section, content, success, error) {
|
||||
var data = ATEditor.legacy.deserialize(content);
|
||||
if (data) {
|
||||
data = data.items;
|
||||
var convert = ATEditor.legacy.convertFromLegacyFormat[section.id];
|
||||
if (convert) {
|
||||
data = _.map(data, convert);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
data = JSON.parse(content);
|
||||
} catch(e) {
|
||||
if (error) { error("Unable to parse data as JSON."); }
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
importDataObjects(section, data, success, error);
|
||||
};
|
||||
function exportData(section) {
|
||||
var objs = section.items;
|
||||
var resultObjs = prepareObjectsForExport(section, objs);
|
||||
return JSON.stringify(resultObjs, undefined, 2);
|
||||
};
|
||||
|
||||
ATEditor.importExport = {
|
||||
importText: importText
|
||||
,importDataObjects: importDataObjects
|
||||
,exportData: exportData
|
||||
,prepareObjectsForEditor: prepareObjectsForEditor
|
||||
};
|
||||
return ATEditor;
|
||||
})(ATEditor || {}, _);
|
||||
335
AndorsTrailEdit/js/legacyimport.js
Normal file
335
AndorsTrailEdit/js/legacyimport.js
Normal file
@@ -0,0 +1,335 @@
|
||||
var ATEditor = (function(ATEditor, model, FieldList, _) {
|
||||
|
||||
function addLegacyFieldLists(model) {
|
||||
model.actorConditions.legacyFieldList = new FieldList("[id|name|iconID|category|isStacking|isPositive|"
|
||||
+ "hasRoundEffect|round_visualEffectID|round_boostHP_Min|round_boostHP_Max|round_boostAP_Min|round_boostAP_Max|"
|
||||
+ "hasFullRoundEffect|fullround_visualEffectID|fullround_boostHP_Min|fullround_boostHP_Max|fullround_boostAP_Min|fullround_boostAP_Max|"
|
||||
+ "hasAbilityEffect|boostMaxHP|boostMaxAP|moveCostPenalty|attackCost|attackChance|criticalChance|criticalMultiplier|attackDamage_Min|attackDamage_Max|blockChance|damageResistance|"
|
||||
+ "];"
|
||||
);
|
||||
model.quests.legacyFieldList = new FieldList("[id|name|showInLog|stages[progress|logText|rewardExperience|finishesQuest|]|];");
|
||||
model.items.legacyFieldList = new FieldList("[id|iconID|name|category|displaytype|hasManualPrice|baseMarketCost|"
|
||||
+ "hasEquipEffect|equip_boostMaxHP|equip_boostMaxAP|equip_moveCostPenalty|equip_attackCost|equip_attackChance|equip_criticalChance|equip_criticalMultiplier|equip_attackDamage_Min|equip_attackDamage_Max|equip_blockChance|equip_damageResistance|equip_conditions[condition|magnitude|]|"
|
||||
+ "hasUseEffect|use_boostHP_Min|use_boostHP_Max|use_boostAP_Min|use_boostAP_Max|use_conditionsSource[condition|magnitude|duration|chance|]|"
|
||||
+ "hasHitEffect|hit_boostHP_Min|hit_boostHP_Max|hit_boostAP_Min|hit_boostAP_Max|hit_conditionsSource[condition|magnitude|duration|chance|]|hit_conditionsTarget[condition|magnitude|duration|chance|]|"
|
||||
+ "hasKillEffect|kill_boostHP_Min|kill_boostHP_Max|kill_boostAP_Min|kill_boostAP_Max|kill_conditionsSource[condition|magnitude|duration|chance|]|"
|
||||
+ "];"
|
||||
);
|
||||
model.droplists.legacyFieldList = new FieldList("[id|items[itemID|quantity_Min|quantity_Max|chance|]|];");
|
||||
model.dialogue.legacyFieldList = new FieldList("[id|message|rewards[rewardType|rewardID|value|]|replies[text|nextPhraseID|requires_Progress|requires_itemID|requires_Quantity|requires_Type|]|];");
|
||||
model.monsters.legacyFieldList = new FieldList("[id|iconID|name|tags|size|monsterClass|unique|faction|maxHP|maxAP|moveCost|attackCost|attackChance|criticalChance|criticalMultiplier|attackDamage_Min|attackDamage_Max|blockChance|damageResistance|droplistID|phraseID|"
|
||||
+ "hasHitEffect|onHit_boostHP_Min|onHit_boostHP_Max|onHit_boostAP_Min|onHit_boostAP_Max|onHit_conditionsSource[condition|magnitude|duration|chance|]|onHit_conditionsTarget[condition|magnitude|duration|chance|]|"
|
||||
+ "];"
|
||||
);
|
||||
model.itemCategories.legacyFieldList = new FieldList("[id|name|actionType|inventorySlot|size|];");
|
||||
}
|
||||
addLegacyFieldLists(model);
|
||||
|
||||
ATEditor.legacy = ATEditor.legacy || {};
|
||||
ATEditor.legacy.convertFromLegacyFormat = {
|
||||
monster: convertMonster
|
||||
,quest: convertQuest
|
||||
,itemcategory: convertItemCategory
|
||||
,item: convertItem
|
||||
,droplist: convertDroplist
|
||||
,dialogue: convertConversation
|
||||
,actorcondition: convertCondition
|
||||
};
|
||||
|
||||
function convertMonster(obj) {
|
||||
// [id|iconID|name|tags|size|monsterClass|unique|faction|maxHP|maxAP|moveCost|attackCost|attackChance|criticalChance|criticalMultiplier|attackDamage_Min|attackDamage_Max|blockChance|
|
||||
// damageResistance|droplistID|phraseID|
|
||||
// hasHitEffect|onHit_boostHP_Min|onHit_boostHP_Max|onHit_boostAP_Min|onHit_boostAP_Max|onHit_conditionsSource[condition|magnitude|duration|chance|]|onHit_conditionsTarget[condition|magnitude|duration|chance|]|];
|
||||
|
||||
var result = {
|
||||
id: obj.id,
|
||||
iconID: obj.iconID,
|
||||
name: obj.name,
|
||||
spawnGroup: obj.tags,
|
||||
size: obj.size,
|
||||
monsterClass: obj.monsterClass,
|
||||
unique: obj.unique,
|
||||
faction: obj.faction,
|
||||
maxHP: obj.maxHP,
|
||||
maxAP: obj.maxAP,
|
||||
moveCost: obj.moveCost,
|
||||
attackCost: obj.attackCost,
|
||||
attackChance: obj.attackChance,
|
||||
criticalSkill: obj.criticalChance,
|
||||
criticalMultiplier: obj.criticalMultiplier,
|
||||
blockChance: obj.blockChance,
|
||||
damageResistance: obj.damageResistance,
|
||||
droplistID: obj.droplistID,
|
||||
phraseID: obj.phraseID
|
||||
};
|
||||
|
||||
if (obj.attackDamage_Min || obj.attackDamage_Max) {
|
||||
result.attackDamage = {
|
||||
min: (obj.attackDamage_Min || 0),
|
||||
max: (obj.attackDamage_Max || 0)
|
||||
};
|
||||
}
|
||||
|
||||
if (obj.hasHitEffect) {
|
||||
result.hitEffect = {};
|
||||
var e = result.hitEffect;
|
||||
if (obj.onHit_boostHP_Min || obj.onHit_boostHP_Max) {
|
||||
e.increaseCurrentHP = {
|
||||
min: (obj.onHit_boostHP_Min || 0),
|
||||
max: (obj.onHit_boostHP_Max || 0)
|
||||
};
|
||||
}
|
||||
if (obj.onHit_boostAP_Min || obj.onHit_boostAP_Max) {
|
||||
e.increaseCurrentAP = {
|
||||
min: (obj.onHit_boostAP_Min || 0),
|
||||
max: (obj.onHit_boostAP_Max || 0)
|
||||
};
|
||||
}
|
||||
if (obj.onHit_conditionsSource) { e.conditionsSource = obj.onHit_conditionsSource; }
|
||||
if (obj.onHit_conditionsTarget) { e.conditionsTarget = obj.onHit_conditionsTarget; }
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function convertQuest(obj) {
|
||||
// [id|name|showInLog|stages[progress|logText|rewardExperience|finishesQuest|]|];
|
||||
return obj;
|
||||
}
|
||||
|
||||
function convertItemCategory(obj) {
|
||||
// [id|name|actionType|inventorySlot|size|];
|
||||
return obj;
|
||||
}
|
||||
|
||||
function convertItem(obj) {
|
||||
//[id|iconID|name|category|displaytype|hasManualPrice|baseMarketCost|
|
||||
// hasEquipEffect|equip_boostMaxHP|equip_boostMaxAP|equip_moveCostPenalty|
|
||||
// equip_attackCost|equip_attackChance|equip_criticalChance|equip_criticalMultiplier|equip_attackDamage_Min|equip_attackDamage_Max|equip_blockChance|equip_damageResistance|
|
||||
// equip_conditions[condition|magnitude|]|
|
||||
// hasUseEffect|use_boostHP_Min|use_boostHP_Max|use_boostAP_Min|use_boostAP_Max|use_conditionsSource[condition|magnitude|duration|chance|]|
|
||||
// hasHitEffect|hit_boostHP_Min|hit_boostHP_Max|hit_boostAP_Min|hit_boostAP_Max|hit_conditionsSource[condition|magnitude|duration|chance|]|hit_conditionsTarget[condition|magnitude|duration|chance|]|
|
||||
// hasKillEffect|kill_boostHP_Min|kill_boostHP_Max|kill_boostAP_Min|kill_boostAP_Max|kill_conditionsSource[condition|magnitude|duration|chance|]|];
|
||||
|
||||
var result = {
|
||||
id: obj.id,
|
||||
iconID: obj.iconID,
|
||||
name: obj.name,
|
||||
category: obj.category,
|
||||
displaytype: obj.displaytype,
|
||||
hasManualPrice: obj.hasManualPrice,
|
||||
baseMarketCost: obj.baseMarketCost
|
||||
};
|
||||
|
||||
if (obj.hasEquipEffect) {
|
||||
result.equipEffect = {};
|
||||
var e = result.equipEffect;
|
||||
if (obj.equip_boostMaxHP) { e.increaseMaxHP = obj.equip_boostMaxHP; }
|
||||
if (obj.equip_boostMaxAP) { e.increaseMaxAP = obj.equip_boostMaxAP; }
|
||||
if (obj.equip_moveCostPenalty) { e.increaseMoveCost = obj.equip_moveCostPenalty; }
|
||||
if (obj.equip_attackCost) { e.increaseAttackCost = obj.equip_attackCost; }
|
||||
if (obj.equip_attackChance) { e.increaseAttackChance = obj.equip_attackChance; }
|
||||
if (obj.equip_criticalChance) { e.increaseCriticalSkill = obj.equip_criticalChance; }
|
||||
if (obj.equip_criticalMultiplier) { e.setCriticalMultiplier = obj.equip_criticalMultiplier; }
|
||||
if (obj.equip_attackDamage_Min || obj.equip_attackDamage_Max) {
|
||||
e.increaseAttackDamage = {
|
||||
min: (obj.equip_attackDamage_Min || 0),
|
||||
max: (obj.equip_attackDamage_Max || 0)
|
||||
};
|
||||
}
|
||||
if (obj.equip_blockChance) { e.increaseBlockChance = obj.equip_blockChance; }
|
||||
if (obj.equip_damageResistance) { e.increaseDamageResistance = obj.equip_damageResistance; }
|
||||
}
|
||||
|
||||
if (obj.equip_conditions) {
|
||||
result.equipEffect = result.equipEffect || {};
|
||||
result.equipEffect.addedConditions = obj.equip_conditions;
|
||||
}
|
||||
|
||||
if (obj.hasUseEffect) {
|
||||
result.useEffect = {};
|
||||
var e = result.useEffect;
|
||||
if (obj.use_boostHP_Min || obj.use_boostHP_Max) {
|
||||
e.increaseCurrentHP = {
|
||||
min: (obj.use_boostHP_Min || 0),
|
||||
max: (obj.use_boostHP_Max || 0)
|
||||
};
|
||||
}
|
||||
if (obj.use_boostAP_Min || obj.use_boostAP_Max) {
|
||||
e.increaseCurrentAP = {
|
||||
min: (obj.use_boostAP_Min || 0),
|
||||
max: (obj.use_boostAP_Max || 0)
|
||||
};
|
||||
}
|
||||
if (obj.use_conditionsSource) { e.conditionsSource = obj.use_conditionsSource; }
|
||||
}
|
||||
|
||||
if (obj.hasHitEffect) {
|
||||
result.hitEffect = {};
|
||||
var e = result.hitEffect;
|
||||
if (obj.hit_boostHP_Min || obj.hit_boostHP_Max) {
|
||||
e.increaseCurrentHP = {
|
||||
min: (obj.hit_boostHP_Min || 0),
|
||||
max: (obj.hit_boostHP_Max || 0)
|
||||
};
|
||||
}
|
||||
if (obj.hit_boostAP_Min || obj.hit_boostAP_Max) {
|
||||
e.increaseCurrentAP = {
|
||||
min: (obj.hit_boostAP_Min || 0),
|
||||
max: (obj.hit_boostAP_Max || 0)
|
||||
};
|
||||
}
|
||||
if (obj.hit_conditionsSource) { e.conditionsSource = obj.hit_conditionsSource; }
|
||||
if (obj.hit_conditionsTarget) { e.conditionsTarget = obj.hit_conditionsTarget; }
|
||||
}
|
||||
|
||||
if (obj.hasKillEffect) {
|
||||
result.killEffect = {};
|
||||
var e = result.killEffect;
|
||||
if (obj.kill_boostHP_Min || obj.kill_boostHP_Max) {
|
||||
e.increaseCurrentHP = {
|
||||
min: (obj.kill_boostHP_Min || 0),
|
||||
max: (obj.kill_boostHP_Max || 0)
|
||||
};
|
||||
}
|
||||
if (obj.kill_boostAP_Min || obj.kill_boostAP_Max) {
|
||||
e.increaseCurrentAP = {
|
||||
min: (obj.kill_boostAP_Min || 0),
|
||||
max: (obj.kill_boostAP_Max || 0)
|
||||
};
|
||||
}
|
||||
if (obj.kill_conditionsSource) { e.conditionsSource = obj.kill_conditionsSource; }
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function convertDroplist(obj) {
|
||||
// [id|items[itemID|quantity_Min|quantity_Max|chance|]|];
|
||||
var result = {
|
||||
id: obj.id,
|
||||
items: _.map(obj.items, function(obj) {
|
||||
return {
|
||||
itemID: obj.itemID,
|
||||
quantity: {
|
||||
min: (obj.quantity_Min || 0),
|
||||
max: (obj.quantity_Max || 0)
|
||||
},
|
||||
chance: obj.chance
|
||||
};
|
||||
})
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function convertConversation(obj) {
|
||||
// [id|message|rewards[rewardType|rewardID|value|]|replies[text|nextPhraseID|requires_Progress|requires_itemID|requires_Quantity|requires_Type|]|];
|
||||
|
||||
var result = {
|
||||
id: obj.id,
|
||||
message: obj.message,
|
||||
rewards: obj.rewards
|
||||
};
|
||||
if (obj.replies) {
|
||||
result.replies = _.map(obj.replies, function(obj) {
|
||||
var result = {
|
||||
text: obj.text,
|
||||
nextPhraseID: obj.nextPhraseID
|
||||
};
|
||||
|
||||
if (obj.requires_Progress) { result.requires = { progress: obj.requires_Progress }; }
|
||||
if (obj.requires_itemID) {
|
||||
result.requires = result.requires || {};
|
||||
result.requires.item = {
|
||||
itemID: obj.requires_itemID,
|
||||
quantity: obj.requires_Quantity,
|
||||
requireType: obj.requires_Type
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function convertCondition(obj) {
|
||||
// [id|name|iconID|category|isStacking|isPositive|
|
||||
// hasRoundEffect|round_visualEffectID|round_boostHP_Min|round_boostHP_Max|round_boostAP_Min|round_boostAP_Max|
|
||||
// hasFullRoundEffect|fullround_visualEffectID|fullround_boostHP_Min|fullround_boostHP_Max|fullround_boostAP_Min|fullround_boostAP_Max|
|
||||
// hasAbilityEffect|boostMaxHP|boostMaxAP|moveCostPenalty|attackCost|attackChance|criticalChance|criticalMultiplier|attackDamage_Min|attackDamage_Max|blockChance|damageResistance|];
|
||||
|
||||
var result = {
|
||||
id: obj.id,
|
||||
iconID: obj.iconID,
|
||||
name: obj.name,
|
||||
category: obj.category,
|
||||
isStacking: obj.isStacking,
|
||||
isPositive: obj.isPositive
|
||||
};
|
||||
|
||||
if (obj.hasRoundEffect) {
|
||||
result.roundEffect = {};
|
||||
var e = result.roundEffect;
|
||||
if (obj.round_visualEffectID || obj.round_visualEffectID === 0) { e.visualEffectID = obj.round_visualEffectID; }
|
||||
if (obj.round_boostHP_Min || obj.round_boostHP_Max) {
|
||||
e.increaseCurrentHP = {
|
||||
min: (obj.round_boostHP_Min || 0),
|
||||
max: (obj.round_boostHP_Max || 0)
|
||||
};
|
||||
}
|
||||
if (obj.round_boostAP_Min || obj.round_boostAP_Max) {
|
||||
e.increaseCurrentAP = {
|
||||
min: (obj.round_boostAP_Min || 0),
|
||||
max: (obj.round_boostAP_Max || 0)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.hasFullRoundEffect) {
|
||||
result.fullRoundEffect = {};
|
||||
var e = result.fullRoundEffect;
|
||||
if (obj.fullround_visualEffectID || obj.fullround_visualEffectID === 0) { e.visualEffectID = obj.fullround_visualEffectID; }
|
||||
if (obj.fullround_boostHP_Min || obj.fullround_boostHP_Max) {
|
||||
e.increaseCurrentHP = {
|
||||
min: (obj.fullround_boostHP_Min || 0),
|
||||
max: (obj.fullround_boostHP_Max || 0)
|
||||
};
|
||||
}
|
||||
if (obj.fullround_boostAP_Min || obj.fullround_boostAP_Max) {
|
||||
e.increaseCurrentAP = {
|
||||
min: (obj.fullround_boostAP_Min || 0),
|
||||
max: (obj.fullround_boostAP_Max || 0)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.hasAbilityEffect) {
|
||||
result.abilityEffect = {};
|
||||
var e = result.abilityEffect;
|
||||
if (obj.boostMaxHP) { e.increaseMaxHP = obj.boostMaxHP; }
|
||||
if (obj.boostMaxAP) { e.increaseMaxAP = obj.boostMaxAP; }
|
||||
if (obj.moveCostPenalty) { e.increaseMoveCost = obj.moveCostPenalty; }
|
||||
if (obj.attackCost) { e.increaseAttackCost = obj.attackCost; }
|
||||
if (obj.attackChance) { e.increaseAttackChance = obj.attackChance; }
|
||||
if (obj.criticalChance) { e.increaseCriticalSkill = obj.criticalChance; }
|
||||
if (obj.criticalMultiplier) { e.setCriticalMultiplier = obj.criticalMultiplier; }
|
||||
if (obj.attackDamage_Min || obj.attackDamage_Max) {
|
||||
e.increaseAttackDamage = {
|
||||
min: (obj.attackDamage_Min || 0),
|
||||
max: (obj.attackDamage_Max || 0)
|
||||
};
|
||||
}
|
||||
if (obj.blockChance) { e.increaseBlockChance = obj.blockChance; }
|
||||
if (obj.damageResistance) { e.increaseDamageResistance = obj.damageResistance; }
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.model, ATEditor.FieldList, _);
|
||||
51
AndorsTrailEdit/js/model.js
Normal file
51
AndorsTrailEdit/js/model.js
Normal file
@@ -0,0 +1,51 @@
|
||||
var ATEditor = (function(ATEditor, DataStore, FieldList, _) {
|
||||
|
||||
var model = {
|
||||
actorConditions: new DataStore({
|
||||
name: 'Actor Conditions'
|
||||
,id: 'actorcondition'
|
||||
,iconIDField: 'iconID'
|
||||
})
|
||||
,quests: new DataStore({
|
||||
name: 'Quests'
|
||||
,id: 'quest'
|
||||
})
|
||||
,items: new DataStore({
|
||||
name: 'Items'
|
||||
,id: 'item'
|
||||
,iconIDField: 'iconID'
|
||||
})
|
||||
,droplists: new DataStore({
|
||||
name: 'Droplists'
|
||||
,id: 'droplist'
|
||||
,nameField: 'id'
|
||||
})
|
||||
,dialogue: new DataStore({
|
||||
name: 'Dialogue'
|
||||
,id: 'dialogue'
|
||||
,nameField: 'id'
|
||||
})
|
||||
,monsters: new DataStore({
|
||||
name: 'Monsters'
|
||||
,id: 'monster'
|
||||
,iconIDField: 'iconID'
|
||||
})
|
||||
,itemCategories: new DataStore({
|
||||
name: 'Item Categories'
|
||||
,id: 'itemcategory'
|
||||
})
|
||||
};
|
||||
|
||||
var sections = [];
|
||||
var sectionIds = {};
|
||||
for (var key in model) {
|
||||
var ds = model[key];
|
||||
sections.push(ds);
|
||||
sectionIds[ds.id] = ds;
|
||||
}
|
||||
model.sections = sections;
|
||||
model.getSectionFromID = function(id) { return sectionIds[id]; };
|
||||
|
||||
ATEditor.model = ATEditor.model || model;
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.DataStore, ATEditor.FieldList, _);
|
||||
147
AndorsTrailEdit/js/tilesets.js
Normal file
147
AndorsTrailEdit/js/tilesets.js
Normal file
@@ -0,0 +1,147 @@
|
||||
var ATEditor = (function(ATEditor, utils) {
|
||||
|
||||
function TilesetImage(options) {
|
||||
var defaultOptions = {
|
||||
numTiles: { x: 1, y: 1 }
|
||||
,tileSize: { x: 32, y: 32 }
|
||||
,usedFor: []
|
||||
};
|
||||
_.defaults(options, defaultOptions);
|
||||
|
||||
this._name = options.name;
|
||||
this._numTiles = options.numTiles;
|
||||
this._tileSize = options.tileSize;
|
||||
this._usedFor = options.usedFor;
|
||||
|
||||
this.localIDToCoords = function(localID) {
|
||||
return {
|
||||
x: (localID % this._numTiles.x) * this._tileSize.x,
|
||||
y: Math.floor(localID / this._numTiles.x) * this._tileSize.y
|
||||
}
|
||||
}
|
||||
this.coordsToLocalID = function(x, y) {
|
||||
return Math.floor(x / this._tileSize.x)
|
||||
+ this._numTiles.x * Math.floor(y / this._tileSize.y)
|
||||
}
|
||||
}
|
||||
|
||||
var defaultImagePath = utils.getUrlRelativeToBaseSrcDir("AndorsTrail/res/drawable/");
|
||||
|
||||
var defaultimage = {
|
||||
tilesetName: 'defaultimage',
|
||||
localID: 0,
|
||||
path: ''
|
||||
};
|
||||
var defaultTileset = new TilesetImage({name: defaultimage.tilesetName });
|
||||
|
||||
var _tilesets = {};
|
||||
_tilesets[defaultimage.tilesetName] = defaultTileset;
|
||||
|
||||
var getTileset = function(name) {
|
||||
var result = _tilesets[name];
|
||||
if (!result) { return defaultTileset; }
|
||||
return result;
|
||||
}
|
||||
|
||||
var parseImageID = function(str) {
|
||||
if (!str || str == "") return defaultimage;
|
||||
var v = str.split(":");
|
||||
if (v.length < 1) return defaultimage;
|
||||
return {
|
||||
tilesetName: v[0],
|
||||
localID: v[1],
|
||||
path: defaultImagePath
|
||||
};
|
||||
}
|
||||
|
||||
var createImageID = function(tilesetName, localID) {
|
||||
if (!tilesetName) return "";
|
||||
return tilesetName + ":" + localID;
|
||||
}
|
||||
|
||||
|
||||
var add = function(tilesetName, numTiles, usedFor, tileSize) {
|
||||
_tilesets[tilesetName] = new TilesetImage({
|
||||
name: tilesetName
|
||||
,numTiles: numTiles
|
||||
,tileSize: tileSize
|
||||
,usedFor: usedFor
|
||||
});
|
||||
}
|
||||
|
||||
var getTilesetsForSection = function(section) {
|
||||
return _.filter(_tilesets, function(tileset) {
|
||||
return _.contains(tileset._usedFor, section);
|
||||
});
|
||||
}
|
||||
var getIconIDsForSection = function(section) {
|
||||
var result = [];
|
||||
_.each(getTilesetsForSection(section), function(tileset) {
|
||||
for(var i = 0; i < tileset._numTiles.y * tileset._numTiles.x; i++) {
|
||||
result.push(createImageID(tileset._name, i));
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
add("actorconditions_1", {x:14, y:8}, [ 'actorcondition' ] );
|
||||
add("actorconditions_2", {x:3, y:1}, [ 'actorcondition' ] );
|
||||
add("items_armours", {x:14, y:3}, [ 'item' ] );
|
||||
add("items_armours_3", {x:10, y:4}, [ 'item' ] );
|
||||
add("items_armours_2", {x:7, y:1}, [ 'item' ] );
|
||||
add("items_weapons", {x:14, y:6}, [ 'item' ] );
|
||||
add("items_weapons_3", {x:13, y:5}, [ 'item' ] );
|
||||
add("items_weapons_2", {x:7, y:1}, [ 'item' ] );
|
||||
add("items_jewelry", {x:14, y:1}, [ 'item' ] );
|
||||
add("items_rings_1", {x:10, y:3}, [ 'item' ] );
|
||||
add("items_necklaces_1", {x:10, y:3}, [ 'item' ] );
|
||||
add("items_consumables", {x:14, y:5}, [ 'item' ] );
|
||||
add("items_books", {x:11, y:1}, [ 'item' ] );
|
||||
add("items_misc", {x:14, y:4}, [ 'item' ] );
|
||||
add("items_misc_2", {x:20, y:12}, [ 'item' ] );
|
||||
add("items_misc_3", {x:20, y:12}, [ 'item' ] );
|
||||
add("items_misc_4", {x:20, y:4}, [ 'item' ] );
|
||||
add("monsters_armor1", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_demon1", {x: 1, y:1}, [ 'monster' ], {x:64, y:64} );
|
||||
add("monsters_dogs", {x: 7, y:1}, [ 'monster' ] );
|
||||
add("monsters_eye1", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_eye2", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_eye3", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_eye4", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_ghost1", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_hydra1", {x: 1, y:1}, [ 'monster' ], {x:64, y:64} );
|
||||
add("monsters_insects", {x: 6, y:1}, [ 'monster' ] );
|
||||
add("monsters_liches", {x: 4, y:1}, [ 'monster' ] );
|
||||
add("monsters_mage", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_mage2", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_man1", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_men", {x: 9, y:1}, [ 'monster' ] );
|
||||
add("monsters_men2", {x: 10, y:1}, [ 'monster' ] );
|
||||
add("monsters_misc", {x: 12, y:1}, [ 'monster' ] );
|
||||
add("monsters_rats", {x: 5, y:1}, [ 'monster' ] );
|
||||
add("monsters_rogue1", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_skeleton1", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_skeleton2", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_snakes", {x: 6, y:1}, [ 'monster' ] );
|
||||
add("monsters_cyclops", {x: 1, y:1}, [ 'monster' ], {x:64, y:96} );
|
||||
add("monsters_warrior1", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_wraiths", {x: 3, y:1}, [ 'monster' ] );
|
||||
add("monsters_zombie1", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_zombie2", {x: 1, y:1}, [ 'monster' ] );
|
||||
add("monsters_karvis1", {x: 2, y:1}, [ 'monster' ] );
|
||||
add("monsters_karvis2", {x: 9, y:1}, [ 'monster' ] );
|
||||
add("monsters_rltiles1", {x:20, y:8}, [ 'monster' ] );
|
||||
add("monsters_rltiles2", {x:20, y:9}, [ 'monster' ] );
|
||||
add("monsters_rltiles3", {x:10, y:3}, [ 'monster' ] );
|
||||
add("monsters_redshrike1", {x:6, y:1}, [ 'monster' ] );
|
||||
add("monsters_ld1", {x:20, y:12}, [ 'monster' ] );
|
||||
add("monsters_ld2", {x:20, y:12}, [ 'monster' ] );
|
||||
|
||||
ATEditor.tilesets = {
|
||||
getTileset: getTileset
|
||||
,parseImageID: parseImageID
|
||||
,createImageID: createImageID
|
||||
,getIconIDsForSection: getIconIDsForSection
|
||||
};
|
||||
return ATEditor;
|
||||
})(ATEditor, ATEditor.utils);
|
||||
134
AndorsTrailEdit/js/utils.js
Normal file
134
AndorsTrailEdit/js/utils.js
Normal file
@@ -0,0 +1,134 @@
|
||||
var ATEditor = (function(ATEditor, _) {
|
||||
|
||||
function deepClone(o) {
|
||||
// https://github.com/documentcloud/underscore/issues/162
|
||||
return JSON.parse(JSON.stringify(o));
|
||||
}
|
||||
|
||||
function removeDefaults(o, defaults) {
|
||||
for (var key in defaults) {
|
||||
if (o[key] === defaults[key]) {
|
||||
delete o[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function copyDefaults(o, defaults) {
|
||||
var key;
|
||||
for (key in defaults) {
|
||||
var v = defaults[key];
|
||||
if ((!o[key]) && (o[key] !== 0)) {
|
||||
o[key] = v;
|
||||
} else if (_.isObject(v)) {
|
||||
copyDefaults(o[key], v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeAngularFields(o) {
|
||||
var key;
|
||||
for (key in o) {
|
||||
var v = o[key];
|
||||
if (key.charAt(0) === '$') {
|
||||
delete o[key];
|
||||
} else if (_.isArray(v) || _.isObject(v)) {
|
||||
removeAngularFields(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
function compact(o) {
|
||||
if (!o) { return null; }
|
||||
var key;
|
||||
for (key in o) {
|
||||
var v = o[key];
|
||||
if (_.isArray(v)) {
|
||||
v = _.map(v, compact);
|
||||
} else if (_.isObject(v)) {
|
||||
v = compact(v);
|
||||
}
|
||||
if (!hasValues(v)) {
|
||||
delete o[key];
|
||||
} else {
|
||||
o[key] = v;
|
||||
}
|
||||
}
|
||||
if (!hasValues(o)) { return null; }
|
||||
return o;
|
||||
}
|
||||
|
||||
function hasValues(o) {
|
||||
if (_.isArray(o)) {
|
||||
return _.some(o, hasValues);
|
||||
} else if (_.isObject(o)) {
|
||||
var key;
|
||||
for (key in o) {
|
||||
if (hasValues(o[key])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
function convertStringsToIntegers(o) {
|
||||
var key;
|
||||
for (key in o) {
|
||||
var v = o[key];
|
||||
if (_.isString(v)) {
|
||||
v = parseInt(v);
|
||||
if (!_.isNaN(v)) {
|
||||
o[key] = v;
|
||||
}
|
||||
} else if (_.isArray(v)) {
|
||||
convertStringsToIntegers(v);
|
||||
} else if (_.isObject(v)) {
|
||||
convertStringsToIntegers(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function convertIntegersToStrings(o) {
|
||||
var key;
|
||||
for (key in o) {
|
||||
var v = o[key];
|
||||
if (_.isNumber(v)) {
|
||||
o[key] = String(v);
|
||||
} else if (_.isArray(v)) {
|
||||
convertIntegersToStrings(v);
|
||||
} else if (_.isObject(v)) {
|
||||
convertIntegersToStrings(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_.toBool = function(b) {
|
||||
return b ? true : false;
|
||||
};
|
||||
|
||||
function getUrlRelativeToBaseSrcDir(relativeUrl) {
|
||||
var url = document.location.href;
|
||||
var idx = url.lastIndexOf('#');
|
||||
if (idx > 0) {
|
||||
url = url.substring(0, idx);
|
||||
}
|
||||
url = url.substring(0, url.lastIndexOf('/'));
|
||||
url = url.substring(0, url.lastIndexOf('/'));
|
||||
url = url + "/" + relativeUrl;
|
||||
return url;
|
||||
}
|
||||
|
||||
ATEditor.utils = {
|
||||
deepClone: deepClone
|
||||
,removeDefaults: removeDefaults
|
||||
,copyDefaults: copyDefaults
|
||||
,removeAngularFields: removeAngularFields
|
||||
,compact: compact
|
||||
,hasValues: hasValues
|
||||
,convertStringsToIntegers: convertStringsToIntegers
|
||||
,convertIntegersToStrings: convertIntegersToStrings
|
||||
,getUrlRelativeToBaseSrcDir: getUrlRelativeToBaseSrcDir
|
||||
};
|
||||
|
||||
return ATEditor;
|
||||
})(ATEditor || {}, _);
|
||||
157
AndorsTrailEdit/partials/edit_actorcondition.html
Normal file
157
AndorsTrailEdit/partials/edit_actorcondition.html
Normal file
@@ -0,0 +1,157 @@
|
||||
<h3>Actor condition - {{obj.name}}</h3>
|
||||
<fieldset>
|
||||
<legend>General</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="iconID">Icon:</label>
|
||||
<span class="field">
|
||||
<div ng-tile-image="obj.iconID" class="at-input-icon" ng-select-image="actorcondition" ng-select-image-dest="obj.iconID"></div>
|
||||
<input type="text" id="iconID" class="at-input-iconID" ng-model="obj.iconID" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="id" class="hint hint--top" data-hint="The id is not displayed to the player anywhere. Must be a unique id (no two conditions may have the same id). Prefer short ids since it keeps savegames smaller.">Internal ID:</label>
|
||||
<input type="text" id="id" class="field at-input-id" ng-model="obj.id" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="name">Display name:</label>
|
||||
<input type="text" id="name" class="field at-input-name" ng-model="obj.name" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="category">Category:</label>
|
||||
<select class="field" id="category" ng-model="obj.category">
|
||||
<option value="0">Spiritual</option>
|
||||
<option value="1">Mental</option>
|
||||
<option value="2">Physical Capacity</option>
|
||||
<option value="3">Blood Disorder</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="isPositive" ng-model="obj.isPositive" ng-true-value="1" ng-false-value="0" />
|
||||
<span class="hint hint--top" data-hint="Positive effects are not affected by the Rejuvenation skill.">Positive effect</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="isStacking" ng-model="obj.isStacking" ng-true-value="1" ng-false-value="0" />
|
||||
<span class="hint hint--top" data-hint="If checked, then actors may have several of these, simultaneously. Otherwise, only one condition at a time may be active on an actor.">Is stacking</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasRoundEffect" ng-model="obj.hasRoundEffect" />Has effect every round (every 6s)</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasFullRoundEffect" ng-model="obj.hasFullRoundEffect" />Has effect every full round (every 25:th s)</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasAbilityEffect" ng-model="obj.hasAbilityEffect" />Has constant ability effect</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset id="hasRoundEffectDisplay" ng-ds-fade="obj.hasRoundEffect">
|
||||
<legend>Every round (6s)</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="round_visualEffectID">Visual effect:</label>
|
||||
<select class="field" id="round_visualEffectID" ng-model="obj.roundEffect.visualEffectID">
|
||||
<option value="-1">None</option>
|
||||
<option value="0">Red splatter</option>
|
||||
<option value="1">Blue swirl</option>
|
||||
<option value="2">Green splatter</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="round_boostHP">Boost current HP (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="round_boostHP_Min" class="at-input-stat-minmax" ng-model="obj.roundEffect.increaseCurrentHP.min" />
|
||||
-
|
||||
<input type="text" size="3" id="round_boostHP_Max" class="at-input-stat-minmax" ng-model="obj.roundEffect.increaseCurrentHP.max" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="round_boostAP">Boost current AP (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="round_boostAP_Min" class="at-input-stat-minmax" ng-model="obj.roundEffect.increaseCurrentAP.min" />
|
||||
-
|
||||
<input type="text" size="3" id="round_boostAP_Max" class="at-input-stat-minmax" ng-model="obj.roundEffect.increaseCurrentAP.max" />
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset id="hasFullRoundEffectDisplay" ng-ds-fade="obj.hasFullRoundEffect">
|
||||
<legend>Every full round (25s)</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="fullround_visualEffectID">Visual effect:</label>
|
||||
<select class="field" id="fullround_visualEffectID" ng-model="obj.fullRoundEffect.visualEffectID">
|
||||
<option value="-1">None</option>
|
||||
<option value="0">Red splatter</option>
|
||||
<option value="1">Blue swirl</option>
|
||||
<option value="2">Green splatter</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="fullround_boostHP">Boost current HP (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="fullround_boostHP_Min" class="at-input-stat-minmax" ng-model="obj.fullRoundEffect.increaseCurrentHP.min" />
|
||||
-
|
||||
<input type="text" size="3" id="fullround_boostHP_Max" class="at-input-stat-minmax" ng-model="obj.fullRoundEffect.increaseCurrentHP.max" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="fullround_boostAP">Boost current AP (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="fullround_boostAP_Min" class="at-input-stat-minmax" ng-model="obj.fullRoundEffect.increaseCurrentAP.min" />
|
||||
-
|
||||
<input type="text" size="3" id="fullround_boostAP_Max" class="at-input-stat-minmax" ng-model="obj.fullRoundEffect.increaseCurrentAP.max" />
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset id="hasAbilityEffectDisplay" ng-ds-fade="obj.hasAbilityEffect">
|
||||
<legend>Constant ability effect</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="boostMaxHP">Boost max HP:</label>
|
||||
<input type="text" size="5" id="boostMaxHP" class="field at-input-stat" ng-model="obj.abilityEffect.increaseMaxHP" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="boostMaxAP">Boost max AP:</label>
|
||||
<input type="text" size="5" id="boostMaxAP" class="field at-input-stat" ng-model="obj.abilityEffect.increaseMaxAP" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="moveCostPenalty">Increase move cost (AP):</label>
|
||||
<input type="text" size="5" id="moveCostPenalty" class="field at-input-stat" ng-model="obj.abilityEffect.increaseMoveCost" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="increaseUseItemCost">Increase use cost (AP):</label>
|
||||
<input type="text" size="5" id="increaseUseItemCost" class="field at-input-stat" ng-model="obj.abilityEffect.increaseUseItemCost" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="increaseReequipCost">Increase re-equip cost (AP):</label>
|
||||
<input type="text" size="5" id="increaseReequipCost" class="field at-input-stat" ng-model="obj.abilityEffect.increaseReequipCost" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="attackCost">Increase attack cost (AP):</label>
|
||||
<input type="text" size="5" id="attackCost" class="field at-input-stat" ng-model="obj.abilityEffect.increaseAttackCost" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="attackChance">Increase attack chance:</label>
|
||||
<input type="text" size="5" id="attackChance" class="field at-input-stat" ng-model="obj.abilityEffect.increaseAttackChance" />%
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="attackDamage">Increase attack damage (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="attackDamage_Min" class="at-input-stat-minmax" ng-model="obj.abilityEffect.increaseAttackDamage.min" />
|
||||
-
|
||||
<input type="text" size="3" id="attackDamage_Max" class="at-input-stat-minmax" ng-model="obj.abilityEffect.increaseAttackDamage.max" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="criticalChance">Increase critical skill:</label>
|
||||
<input type="text" size="5" id="criticalChance" class="field at-input-stat" ng-model="obj.abilityEffect.increaseCriticalSkill" />%
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="blockChance">Increase block chance:</label>
|
||||
<input type="text" size="5" id="blockChance" class="field at-input-stat" ng-model="obj.abilityEffect.increaseBlockChance" />%
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="damageResistance">Increase damage resistance:</label>
|
||||
<input type="text" size="5" id="damageResistance" class="field at-input-stat" ng-model="obj.abilityEffect.increaseDamageResistance" />
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="endSets"> </div>
|
||||
146
AndorsTrailEdit/partials/edit_dialogue.html
Normal file
146
AndorsTrailEdit/partials/edit_dialogue.html
Normal file
@@ -0,0 +1,146 @@
|
||||
<h3>Dialogue</h3>
|
||||
|
||||
<fieldset id="dialoguePhrase">
|
||||
<legend>NPC phrase</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="id">Phrase ID:</label>
|
||||
<input type="text" size="30" id="id" class="field at-input-id" ng-model="phrase.id" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="message">NPC says:</label>
|
||||
<textarea rows="4" cols="40" id="message" ng-model="phrase.message"></textarea>
|
||||
<p ng-ds-fade="!phrase.message && phrase.replies.length > 0" class="dialogueConditional">
|
||||
Since this phrase does not have any displayed<br />
|
||||
text, it will not be shown to the player.<br />
|
||||
Instead, the first reply that matches all<br />
|
||||
requirements will be automatically followed.
|
||||
</p>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasRewards" ng-model="phrase.hasRewards" />Reaching this phrase gives rewards</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="phrase.hasRewards">
|
||||
<label for="rewards">Rewards</label>
|
||||
<table class="field" id="rewards">
|
||||
<thead><tr>
|
||||
<th>Type</th>
|
||||
<th><span class="hint hint--top" data-hint="Id of the quest, droplist, skill, condition of cation to be affected.">ID</span></th>
|
||||
<th><span class="hint hint--top" data-hint="For quest rewards: quest stage to reward. For skill rewards: how many skill levels to reward. For conditions: duration of added effetct. For alignment: amount of faction change. Not used for droplists.">
|
||||
Value
|
||||
</span></th>
|
||||
<th></th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="reward in phrase.rewards">
|
||||
<td>
|
||||
<select class="field" id="rewardType" ng-model="reward.rewardType">
|
||||
<option value="0">Quest progress</option>
|
||||
<option value="1">Droplist</option>
|
||||
<option value="2">Skill increase</option>
|
||||
<option value="3">Actor condition</option>
|
||||
<option value="4">Alignment/faction change</option>
|
||||
</select>
|
||||
</td>
|
||||
<td><input type="text" size="30" ng-model="reward.rewardID" id="rewardID" class="at-input-id"/></td>
|
||||
<td><input type="text" size="3" ng-model="reward.value" class="at-input-quantity" /></td>
|
||||
<td><a ng-click="removeReward(phrase, reward)" class="btn btn-mini" title="Remove row"><i class="icon-trash"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button ng-click="addReward(phrase)" class="btn" title="Add reward"><i class="icon-plus-sign"></i> Add reward</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset id="dialoguePhraseReplies">
|
||||
<legend>Replies</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasOnlyNextReply" ng-model="phrase.hasOnlyNextReply" />Phrase leads directly to another<br />phrase without replies</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="phrase.hasOnlyNextReply">
|
||||
<label for="nextPhraseID">Phrase ID:</label>
|
||||
<div class="field">
|
||||
<input type="text" size="30" id="nextPhraseID" class="at-input-id" ng-model="phrase.nextPhraseID" placeholder="leave empty to generate id" />
|
||||
<a ng-click="proceedToPhrase(phrase, 'nextPhraseID')" class="btn" title="Open editor for the indicated phrase. Leave empty to automatically generate a new phrase id based on the prefix for this phrase, or supply a new phrase id that should be used.">
|
||||
<span ng-show="phrase.nextPhraseID"><i class="icon-forward"></i> Go</span>
|
||||
<span ng-show="!phrase.nextPhraseID"><i class="icon-star-empty"></i> Generate</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="!phrase.hasOnlyNextReply">
|
||||
<label for="replies">Replies</label>
|
||||
<table class="field" id="replies">
|
||||
<thead><tr>
|
||||
<th>Reply</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="reply in phrase.replies">
|
||||
<td ng-click="selectReply(reply)" class="clickToEdit">
|
||||
<span ng-show="reply.text">{{reply.text.substring(0, 40)}}</span>
|
||||
<span ng-show="!reply.text" class="dialogueConditional">(conditional evaluation)</span>
|
||||
</td>
|
||||
<td><a ng-click="removeReply(phrase, reply)" class="btn" title="Remove reply"><i class="icon-trash"></i></a></td>
|
||||
<td><a ng-click="proceedToPhrase(reply, 'nextPhraseID')" class="btn" title="Follow" ng-show="reply.nextPhraseID && reply.nextPhraseID.length > 1"><i class="icon-forward"></i> Go</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button ng-click="addReply(phrase)" class="btn" title="Add reply"><i class="icon-plus-sign"></i> Add reply</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset id="dialogueReply" ng-show="reply">
|
||||
<legend>Player reply</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="text">Player says:</label>
|
||||
<textarea rows="4" cols="40" id="text" ng-model="reply.text"></textarea>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="replyLeadsTo">Reply leads to:</label>
|
||||
<select class="field" id="replyLeadsTo" ng-model="reply.replyLeadsTo">
|
||||
<option value="">Another phrase</option>
|
||||
<option value="S">Trading screen</option>
|
||||
<option value="F">Combat</option>
|
||||
<option value="X">Conversation ends</option>
|
||||
<option value="R">NPC is removed from map</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="!reply.replyLeadsTo">
|
||||
<label for="nextPhraseID">Next phrase ID:</label>
|
||||
<div class="field">
|
||||
<input type="text" size="30" id="nextPhraseID" class="at-input-id" ng-model="reply.nextPhraseID" placeholder="leave empty to generate id" />
|
||||
<a ng-click="proceedToPhrase(reply, 'nextPhraseID')" class="btn" title="Open editor for the indicated phrase. Leave empty to automatically generate a new phrase id based on the prefix for this phrase, or supply a new phrase id that should be used.">
|
||||
<span ng-show="reply.nextPhraseID"><i class="icon-forward"></i> Go</span>
|
||||
<span ng-show="!reply.nextPhraseID"><i class="icon-star-empty"></i> Generate</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="requiresItems" ng-model="reply.requiresItems" />Player must have item(s) to select this reply</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="reply.requiresItems">
|
||||
<label for="requires_itemID">Required item ID</label>
|
||||
<input type="text" size="30" id="requires_itemID" class="field at-input-id" ng-model="reply.requires.item.itemID" />
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="reply.requiresItems">
|
||||
<label for="requires_Quantity">Required item quantity</label>
|
||||
<input type="text" size="5" id="requires_Quantity" class="field at-input-quantity" ng-model="reply.requires.item.quantity" />
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="reply.requiresItems">
|
||||
<label for="requires_Type">Player should have item in:</label>
|
||||
<select class="field" id="requires_Type" ng-model="reply.requires.item.requireType">
|
||||
<option value="0">Inventory & item will be removed</option>
|
||||
<option value="1">Inventory</option>
|
||||
<option value="2">Worn equipment</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="requiresQuest" ng-model="reply.requiresQuest" />Player must have progressed quest to select this reply</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="reply.requiresQuest">
|
||||
<label for="requires_Progress" class="hint hint--left" data-hint="For example, 'mikhail:20' would require that the quest mikhail is at at least stage 20.">Quest stage required:</label>
|
||||
<input type="text" size="30" id="requires_Progress" class="field at-input-id" ng-model="reply.requires.progress" placeholder="questname:stage"/>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
<div class="endSets"> </div>
|
||||
33
AndorsTrailEdit/partials/edit_droplist.html
Normal file
33
AndorsTrailEdit/partials/edit_droplist.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<h3>Droplist - {{obj.id}}</h3>
|
||||
<fieldset>
|
||||
<legend>General</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="id" class="hint hint--top" data-hint="The id is not displayed to the player anywhere. Must be a unique id (no two droplists may have the same id). This is the id that you can enter on monsters to make them drop all these items.">Droplist internal ID:</label>
|
||||
<input type="text" size="30" id="id" class="field at-input-id" ng-model="obj.id" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="stages">Items dropped</label>
|
||||
<table class="field" id="items">
|
||||
<thead><tr>
|
||||
<th id="itemID">Item (id)</th>
|
||||
<th id="quantity">Quantity (range)</th>
|
||||
<th id="chance"><span class="hint hint--top" data-hint="Percentage chance, integer value from 1 (very unlikely) to 100 (always).">Chance</span></th>
|
||||
<th></th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="dropItem in obj.items">
|
||||
<td><input type="text" ng-model="dropItem.itemID" class="at-input-id" /></td>
|
||||
<td>
|
||||
<input type="text" size="3" ng-model="dropItem.quantity.min" class="at-input-quantity" />
|
||||
-
|
||||
<input type="text" size="3" ng-model="dropItem.quantity.max" class="at-input-quantity" />
|
||||
</td>
|
||||
<td><input type="text" size="3" ng-model="dropItem.chance" class="at-input-chance" /></td>
|
||||
<td><a ng-click="removeDropItem(dropItem)" class="btn btn-mini" title="Remove row"><i class="icon-trash"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button ng-click="addDropItem()" class="btn" title="Add row"><i class="icon-plus-sign"></i> Add</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="endSets"> </div>
|
||||
290
AndorsTrailEdit/partials/edit_item.html
Normal file
290
AndorsTrailEdit/partials/edit_item.html
Normal file
@@ -0,0 +1,290 @@
|
||||
<h3>Item - {{obj.name}}</h3>
|
||||
<fieldset>
|
||||
<legend>General</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="iconID">Icon:</label>
|
||||
<span class="field">
|
||||
<div ng-tile-image="obj.iconID" class="at-input-icon" ng-select-image="item" ng-select-image-dest="obj.iconID"></div>
|
||||
<input type="text" id="iconID" class="at-input-iconID" ng-model="obj.iconID" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="name">Display name:</label>
|
||||
<input type="text" size="30" id="name" class="field at-input-name" ng-model="obj.name" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="id" class="hint hint--top" data-hint="The id is not displayed to the player anywhere. Must be a unique id (no two items may have the same id). Prefer short ids since it keeps savegames smaller.">Internal ID:</label>
|
||||
<input type="text" size="30" id="id" class="field at-input-id" ng-model="obj.id" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="category">Category:</label>
|
||||
<select class="field" id="category" ng-model="obj.category" ng-options="s.name for s in itemCategories">
|
||||
</select>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="displaytype">Display as:</label>
|
||||
<select class="field" id="displaytype" ng-model="obj.displaytype">
|
||||
<option value="0">Ordinary item</option>
|
||||
<option value="1">Quest item (yellow)</option>
|
||||
<option value="2">Legendary (green)</option>
|
||||
<option value="3">Extraordinary (blue)</option>
|
||||
<option value="4">Rare (purple)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasEquipEffect" ng-model="obj.hasEquipEffect" />Has equip effect</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasUseEffect" ng-model="obj.hasUseEffect" />Has use effect</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasHitEffect" ng-model="obj.hasHitEffect" />Has effect on every hit</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasKillEffect" ng-model="obj.hasKillEffect" />Has effect on every kill</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Price</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasManualPrice" ng-model="obj.hasManualPrice" ng-true-value="1" ng-false-value="0" />Item has manually specified store price</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="baseMarketCost">Base market cost (gold):</label>
|
||||
<input type="text" size="7" id="baseMarketCost" ng-show="obj.hasManualPrice == 0" class="field at-input-gold" readonly="readonly" value="{{getItemCost(obj)}}" />
|
||||
<input type="text" size="7" id="baseMarketCost" ng-show="obj.hasManualPrice == 1" class="field at-input-gold" ng-model="obj.baseMarketCost" title="The actual price is adjusted 15% depending on if the item is being bought or sold. Set to 0 to prohibit selling this item type (for example, for a quest item)." />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="marketCost_Sell">Actual price (gold):</label>
|
||||
<div class="field">
|
||||
<span>Sell: <input type="text" size="7" id="marketCost_Sell" class="at-input-gold" value="{{getItemSellingCost(obj)}}" readonly="readonly" /></span>
|
||||
<span>Buy: <input type="text" size="7" id="marketCost_Buy" class="at-input-gold" value="{{getItemBuyingCost(obj)}}" readonly="readonly" /></span>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset id="hasEquipEffectDisplay" ng-ds-fade="obj.hasEquipEffect">
|
||||
<legend>When equipped</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="equip_boostMaxHP">Increase max HP:</label>
|
||||
<input type="text" size="5" id="equip_boostMaxHP" class="field at-input-stat" ng-model="obj.equipEffect.increaseMaxHP" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasEquipEffect" ng-model="obj.hasEquipAPEffect" />Has AP effect</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="obj.hasEquipAPEffect">
|
||||
<label for="equip_boostMaxAP">Increase max AP:</label>
|
||||
<input type="text" size="5" id="equip_boostMaxAP" class="field at-input-stat" ng-model="obj.equipEffect.increaseMaxAP" />
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="obj.hasEquipAPEffect">
|
||||
<label for="equip_moveCostPenalty">Increase move cost (AP):</label>
|
||||
<input type="text" size="5" id="equip_moveCostPenalty" class="field at-input-stat" ng-model="obj.equipEffect.increaseMoveCost" />
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="obj.hasEquipAPEffect">
|
||||
<label for="equip_increaseUseItemCost">Increase use item cost (AP):</label>
|
||||
<input type="text" size="5" id="equip_increaseUseItemCost" class="field at-input-stat" ng-model="obj.equipEffect.increaseUseItemCost" />
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="obj.hasEquipAPEffect">
|
||||
<label for="equip_increaseReequipCost">Increase re-equip cost (AP):</label>
|
||||
<input type="text" size="5" id="equip_increaseReequipCost" class="field at-input-stat" ng-model="obj.equipEffect.increaseReequipCost" />
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="!isWeapon">
|
||||
<label for="equip_attackCost">Increase attack cost (AP):</label>
|
||||
<input type="text" size="5" id="equip_attackCost" class="field at-input-stat" ng-model="obj.equipEffect.increaseAttackCost" />
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="isWeapon">
|
||||
<label for="equip_attackCost">Attack cost (AP):</label>
|
||||
<input type="text" size="5" id="equip_attackCost" class="field at-input-stat" ng-model="obj.equipEffect.increaseAttackCost" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="equip_attackChance">Increase attack chance:</label>
|
||||
<input type="text" size="5" id="equip_attackChance" class="field at-input-stat" ng-model="obj.equipEffect.increaseAttackChance" />%
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="equip_attackDamage">Increase attack damage (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="equip_attackDamage_Min" class="at-input-stat-minmax" ng-model="obj.equipEffect.increaseAttackDamage.min" />
|
||||
-
|
||||
<input type="text" size="3" id="equip_attackDamage_Max" class="at-input-stat-minmax" ng-model="obj.equipEffect.increaseAttackDamage.max" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="equip_criticalChance">Increase critical skill:</label>
|
||||
<input type="text" size="5" id="equip_criticalChance" class="field at-input-stat" ng-model="obj.equipEffect.increaseCriticalSkill" />
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="isWeapon">
|
||||
<label for="equip_criticalMultiplier" class="hint hint--top" data-hint="Only for weapons">Critical multiplier:</label>
|
||||
<input type="text" size="5" id="equip_criticalMultiplier" class="field at-input-stat" ng-model="obj.equipEffect.setCriticalMultiplier" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="equip_blockChance">Increase block chance:</label>
|
||||
<input type="text" size="5" id="equip_blockChance" class="field at-input-stat" ng-model="obj.equipEffect.increaseBlockChance" />%
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="equip_damageResistance">Increase damage resistance:</label>
|
||||
<input type="text" size="5" id="equip_damageResistance" class="field at-input-stat" ng-model="obj.equipEffect.increaseDamageResistance" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="equip_conditions">Apply actor condition</label>
|
||||
<table class="field" id="equip_conditions">
|
||||
<thead><tr>
|
||||
<th><span class="hint hint--left" data-hint="Id of the actor condition to be applied.">Condition</span></th>
|
||||
<th><span class="hint hint--left" data-hint="How strong the effect should be. For example, magnitude=2 is equal to having two effects active at the same time. Use -99 to remove permanent effects.">Magnitude</span></th>
|
||||
<th></th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="condition in obj.equipEffect.addedConditions">
|
||||
<td><input type="text" ng-model="condition.condition" class="at-input-id" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.magnitude" class="at-input-magnitude" /></td>
|
||||
<td><a ng-click="removeCondition(obj.equipEffect.addedConditions, condition)" class="btn btn-mini" title="Remove row"><i class="icon-trash"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button ng-click="addCondition(obj.equipEffect.addedConditions)" class="btn" title="Add row"><i class="icon-plus-sign"></i> Add</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset id="hasUseEffectDisplay" ng-ds-fade="obj.hasUseEffect">
|
||||
<legend>When used</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="use_boostHP">Boost current HP (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="use_boostHP_Min" class="at-input-stat-minmax" ng-model="obj.useEffect.increaseCurrentHP.min" />
|
||||
-
|
||||
<input type="text" size="3" id="use_boostHP_Max" class="at-input-stat-minmax" ng-model="obj.useEffect.increaseCurrentHP.max" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="use_boostAP">Boost current AP (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="use_boostAP_Min" class="at-input-stat-minmax" ng-model="obj.useEffect.increaseCurrentAP.min" />
|
||||
-
|
||||
<input type="text" size="3" id="use_boostAP_Max" class="at-input-stat-minmax" ng-model="obj.useEffect.increaseCurrentAP.max" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="use_conditionsSource">Apply actor condition</label>
|
||||
<table class="field" id="use_conditionsSource">
|
||||
<thead><tr>
|
||||
<th><span class="hint hint--left" data-hint="Id of the actor condition to be applied.">Condition</span></th>
|
||||
<th><span class="hint hint--left" data-hint="How strong the effect should be. For example, magnitude=2 is equal to having two effects active at the same time. Use -99 to remove permanent effects.">Magnitude</span></th>
|
||||
<th><span class="hint hint--left" data-hint="How many rounds the actor condtions should last. Use 999 for a permanent effect.">Duration</span></th>
|
||||
<th><span class="hint hint--left" data-hint="Percentage chance, integer value from 1 (very unlikely) to 100 (always).">Chance</span></th>
|
||||
<th></th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="condition in obj.useEffect.conditionsSource">
|
||||
<td><input type="text" ng-model="condition.condition" class="at-input-id" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.magnitude" class="at-input-magnitude" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.duration" class="at-input-duration" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.chance" class="at-input-chance" /></td>
|
||||
<td><a ng-click="removeCondition(obj.useEffect.conditionsSource, condition)" class="btn btn-mini" title="Remove row"><i class="icon-trash"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button ng-click="addCondition(obj.useEffect.conditionsSource)" class="btn" title="Add row"><i class="icon-plus-sign"></i> Add</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset id="hasHitEffectDisplay" ng-ds-fade="obj.hasHitEffect">
|
||||
<legend>When making a successful hit</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="hit_boostHP">Boost current HP (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="hit_boostHP_Min" class="at-input-stat-minmax" ng-model="obj.hitEffect.increaseCurrentHP.min" />
|
||||
-
|
||||
<input type="text" size="3" id="hit_boostHP_Max" class="at-input-stat-minmax" ng-model="obj.hitEffect.increaseCurrentHP.max" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="hit_boostAP">Boost current AP (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="hit_boostAP_Min" class="at-input-stat-minmax" ng-model="obj.hitEffect.increaseCurrentAP.min" />
|
||||
-
|
||||
<input type="text" size="3" id="hit_boostAP_Max" class="at-input-stat-minmax" ng-model="obj.hitEffect.increaseCurrentAP.max" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="hit_conditionsSource">Apply actor condition to source</label>
|
||||
<table class="field" id="hit_conditionsSource">
|
||||
<thead><tr>
|
||||
<th><span class="hint hint--left" data-hint="Id of the actor condition to be applied.">Condition</span></th>
|
||||
<th><span class="hint hint--left" data-hint="How strong the effect should be. For example, magnitude=2 is equal to having two effects active at the same time. Use -99 to remove permanent effects.">Magnitude</span></th>
|
||||
<th><span class="hint hint--left" data-hint="How many rounds the actor condtions should last. Use 999 for a permanent effect.">Duration</span></th>
|
||||
<th><span class="hint hint--left" data-hint="Percentage chance, integer value from 1 (very unlikely) to 100 (always).">Chance</span></th>
|
||||
<th></th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="condition in obj.hitEffect.conditionsSource">
|
||||
<td><input type="text" ng-model="condition.condition" class="at-input-id" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.magnitude" class="at-input-magnitude" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.duration" class="at-input-duration" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.chance" class="at-input-chance" /></td>
|
||||
<td><a ng-click="removeCondition(obj.hitEffect.conditionsSource, condition)" class="btn btn-mini" title="Remove row"><i class="icon-trash"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button ng-click="addCondition(obj.hitEffect.conditionsSource)" class="btn" title="Add row"><i class="icon-plus-sign"></i> Add</button>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="hit_conditionsTarget">Apply actor condition to target</label>
|
||||
<table class="field" id="hit_conditionsTarget">
|
||||
<thead><tr>
|
||||
<th><span class="hint hint--left" data-hint="Id of the actor condition to be applied.">Condition</span></th>
|
||||
<th><span class="hint hint--left" data-hint="How strong the effect should be. For example, magnitude=2 is equal to having two effects active at the same time. Use -99 to remove permanent effects.">Magnitude</span></th>
|
||||
<th><span class="hint hint--left" data-hint="How many rounds the actor condtions should last. Use 999 for a permanent effect.">Duration</span></th>
|
||||
<th><span class="hint hint--left" data-hint="Percentage chance, integer value from 1 (very unlikely) to 100 (always).">Chance</span></th>
|
||||
<th></th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="condition in obj.hitEffect.conditionsTarget">
|
||||
<td><input type="text" ng-model="condition.condition" class="at-input-id" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.magnitude" class="at-input-magnitude" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.duration" class="at-input-duration" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.chance" class="at-input-chance" /></td>
|
||||
<td><a ng-click="removeCondition(obj.hitEffect.conditionsTarget, condition)" class="btn btn-mini" title="Remove row"><i class="icon-trash"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button ng-click="addCondition(obj.hitEffect.conditionsTarget)" class="btn" title="Add row"><i class="icon-plus-sign"></i> Add</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset id="hasKillEffectDisplay" ng-ds-fade="obj.hasKillEffect">
|
||||
<legend>On every kill</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="kill_boostHP">Boost current HP (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="kill_boostHP_Min" class="at-input-stat-minmax" ng-model="obj.killEffect.increaseCurrentHP.min" />
|
||||
-
|
||||
<input type="text" size="3" id="kill_boostHP_Max" class="at-input-stat-minmax" ng-model="obj.killEffect.increaseCurrentHP.max" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="kill_boostAP">Boost current AP (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="kill_boostAP_Min" class="at-input-stat-minmax" ng-model="obj.killEffect.increaseCurrentAP.min" />
|
||||
-
|
||||
<input type="text" size="3" id="kill_boostAP_Max" class="at-input-stat-minmax" ng-model="obj.killEffect.increaseCurrentAP.max" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="kill_conditionsSource">Apply actor condition</label>
|
||||
<table class="field" id="kill_conditionsSource">
|
||||
<thead><tr>
|
||||
<th><span class="hint hint--left" data-hint="Id of the actor condition to be applied.">Condition</span></th>
|
||||
<th><span class="hint hint--left" data-hint="How strong the effect should be. For example, magnitude=2 is equal to having two effects active at the same time. Use -99 to remove permanent effects.">Magnitude</span></th>
|
||||
<th><span class="hint hint--left" data-hint="How many rounds the actor condtions should last. Use 999 for a permanent effect.">Duration</span></th>
|
||||
<th><span class="hint hint--left" data-hint="Percentage chance, integer value from 1 (very unlikely) to 100 (always).">Chance</span></th>
|
||||
<th></th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="condition in obj.killEffect.conditionsSource">
|
||||
<td><input type="text" ng-model="condition.condition" class="at-input-id" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.magnitude" class="at-input-magnitude" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.duration" class="at-input-duration" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.chance" class="at-input-chance" /></td>
|
||||
<td><a ng-click="removeCondition(obj.killEffect.conditionsSource, condition)" class="btn btn-mini" title="Remove row"><i class="icon-trash"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button ng-click="addCondition(obj.killEffect.conditionsSource)" class="btn" title="Add row"><i class="icon-plus-sign"></i> Add</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="endSets"> </div>
|
||||
44
AndorsTrailEdit/partials/edit_itemcategory.html
Normal file
44
AndorsTrailEdit/partials/edit_itemcategory.html
Normal file
@@ -0,0 +1,44 @@
|
||||
<h3>Item Category - {{obj.name}}</h3>
|
||||
<fieldset>
|
||||
<legend>General</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="id">Internal id:</label>
|
||||
<input type="text" size="30" id="id" ng-model="obj.id" class="field at-input-id"/>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="name">Display name:</label>
|
||||
<input type="text" size="30" id="name" ng-model="obj.name" class="field at-input-name"/>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="actionType">Action type:</label>
|
||||
<select class="field" id="actionType" ng-model="obj.actionType">
|
||||
<option value="0">Non-usable</option>
|
||||
<option value="1">Usable</option>
|
||||
<option value="2">Equippable</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="obj.actionType == 2">
|
||||
<label for="inventorySlot">Equippable inventory slot:</label>
|
||||
<select class="field" id="inventorySlot" ng-model="obj.inventorySlot">
|
||||
<option value="-1">None</option>
|
||||
<option value="0">Weapon</option>
|
||||
<option value="1">Shield</option>
|
||||
<option value="2">Head</option>
|
||||
<option value="3">Body</option>
|
||||
<option value="4">Hand</option>
|
||||
<option value="5">Feet</option>
|
||||
<option value="6">Neck</option>
|
||||
<option value="7">Ring</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="size">Size:</label>
|
||||
<select class="field" id="size" ng-model="obj.size">
|
||||
<option value="0">None</option>
|
||||
<option value="1">Light</option>
|
||||
<option value="2">Standard</option>
|
||||
<option value="3">Large</option>
|
||||
</select>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="endSets"> </div>
|
||||
206
AndorsTrailEdit/partials/edit_monster.html
Normal file
206
AndorsTrailEdit/partials/edit_monster.html
Normal file
@@ -0,0 +1,206 @@
|
||||
<h3>Monster / NPC - {{obj.name}}</h3>
|
||||
<fieldset>
|
||||
<legend>General</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="iconID">Icon:</label>
|
||||
<span class="field">
|
||||
<div ng-tile-image="obj.iconID" class="at-input-icon" ng-select-image="monster" ng-select-image-dest="obj.iconID"></div>
|
||||
<input type="text" id="iconID" class="at-input-iconID" ng-model="obj.iconID" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="id" class="hint hint--top" data-hint="The id is not displayed to the player anywhere. Must be a unique id (no two monster may have the same id). Prefer short ids since it keeps savegames smaller.">Internal id:</label>
|
||||
<input type="text" size="30" id="id" class="field at-input-id" ng-model="obj.id"/>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="name">Display name:</label>
|
||||
<input type="text" size="30" id="name" class="field at-input-name" ng-model="obj.name"/>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="spawnGroup" class="hint hint--top" data-hint="The name to enter on spawn areas in TMX map files for spawning this type of monster. Several monster types may have the same spawngroup, which makes the game spawn one random monster type from the spawngroup.">Spawngroup:</label>
|
||||
<input type="text" size="30" id="spawnGroup" class="field at-input-id" ng-model="obj.spawnGroup" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" id="unique" ng-model="obj.unique" ng-true-value="1" ng-false-value="0" />
|
||||
<span class="hint hint--top" data-hint="Unique monsters will not respawn. Typically used for bosses.">Is unique (will not respawn)</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="monsterClass">Monster class:</label>
|
||||
<select class="field" id="monsterClass" ng-model="obj.monsterClass">
|
||||
<option value="0">Humanoid</option>
|
||||
<option value="1">Insect</option>
|
||||
<option value="2">Demon</option>
|
||||
<option value="3">Construct</option>
|
||||
<option value="4">Animal</option>
|
||||
<option value="5">Giant</option>
|
||||
<option value="6">Undead</option>
|
||||
<option value="7">Reptile</option>
|
||||
<option value="8">Ghost</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="showAdvanced" ng-model="obj.showAdvanced" />Show advanced properties</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="obj.showAdvanced">
|
||||
<label for="size">Size:</label>
|
||||
<select class="field" id="size" ng-model="obj.size">
|
||||
<option value="1x1">1x1</option>
|
||||
<option value="1x2">1x2</option>
|
||||
<option value="1x3">1x3</option>
|
||||
<option value="2x1">2x1</option>
|
||||
<option value="2x2">2x2</option>
|
||||
<option value="2x3">2x3</option>
|
||||
<option value="3x1">3x1</option>
|
||||
<option value="3x2">3x2</option>
|
||||
<option value="3x3">3x3</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="obj.showAdvanced">
|
||||
<label for="faction" class="hint hint--top" data-hint="Used for making whole groups of monsters aggressive from dialogue. Dialogue replies may affect the player's faction ratings, and having rating less than 0 for a faction will make all monsters in a faction automatically attack.">Faction:</label>
|
||||
<input type="text" size="30" id="faction" ng-model="obj.faction" class="field at-input-id"/>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasConversation" ng-model="obj.hasConversation" />Has conversation</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel" id="hasConversationDisplay" ng-ds-fade="obj.hasConversation">
|
||||
<label for="phraseID" class="hint hint--top" data-hint="ID of the starting conversation phrase that will be used when engaging in conversation with this NPC.">Conversation phrase ID:</label>
|
||||
<input type="text" size="30" id="phraseID" ng-model="obj.phraseID" class="field at-input-id" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="droplistID" class="hint hint--top" data-hint="ID of the droplist that will contain the items that are dropped when the monster is killed. If this monster is an NPC, this is the list of items that are available to buy as shop items.">Droplist ID (combat or shop):</label>
|
||||
<input type="text" size="30" id="droplistID" ng-model="obj.droplistID" class="field at-input-id"/>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Stats</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="maxAP">Total AP:</label>
|
||||
<input type="text" size="5" id="maxAP" ng-model="obj.maxAP" class="field at-input-stat" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="moveCost">Movement cost (AP):</label>
|
||||
<input type="text" size="5" id="moveCost" ng-model="obj.moveCost" class="field at-input-stat" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="maxHP">Max HP:</label>
|
||||
<input type="text" size="5" id="maxHP" ng-model="obj.maxHP" class="field at-input-stat" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasCombat" ng-model="obj.hasCombatTraits" />Has combat traits</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset id="hasCombatDisplay" ng-ds-fade="obj.hasCombatTraits">
|
||||
<legend>Combat</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="experience">Experience:</label>
|
||||
<input type="text" size="7" id="experience" value="{{getExperience()}}" class="field at-input-stat" readonly="readonly" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="attackCost">Attack cost (AP):</label>
|
||||
<input type="text" size="5" id="attackCost" ng-model="obj.attackCost" class="field at-input-stat" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="attackChance">Attack chance:</label>
|
||||
<input type="text" size="5" id="attackChance" ng-model="obj.attackChance" class="field at-input-stat" />%
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="attackDamage">Attack damage (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="attackDamage_Min" ng-model="obj.attackDamage.min" class="at-input-stat-minmax" />
|
||||
-
|
||||
<input type="text" size="3" id="attackDamage_Max" ng-model="obj.attackDamage.max" class="at-input-stat-minmax" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasCritical" ng-model="obj.hasCritical" />Has critical chance</label>
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="obj.hasCritical">
|
||||
<label for="criticalSkill">Critical skill:</label>
|
||||
<input type="text" size="5" id="criticalSkill" ng-model="obj.criticalSkill" class="field at-input-stat" />
|
||||
</div>
|
||||
<div class="fieldWithLabel" ng-ds-fade="obj.hasCritical">
|
||||
<label for="criticalMultiplier">Critical multiplier:</label>
|
||||
<input type="text" size="5" id="criticalMultiplier" ng-model="obj.criticalMultiplier" class="field at-input-stat" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="blockChance">Block chance:</label>
|
||||
<input type="text" size="5" id="blockChance" ng-model="obj.blockChance" class="field at-input-stat" />%
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="damageResistance">Damage resistance:</label>
|
||||
<input type="text" size="5" id="damageResistance" ng-model="obj.damageResistance" class="field at-input-stat" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="hasHitEffect" ng-model="obj.hasHitEffect" />Has effect on each hit</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset id="hasHitEffectDisplay" ng-ds-fade="obj.hasHitEffect && obj.hasCombatTraits">
|
||||
<legend>On every successful attack hit</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="onHit_boostHP">Boost current HP (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="onHit_boostHP_Min" ng-model="obj.hitEffect.increaseCurrentHP.min" class="at-input-stat-minmax" />
|
||||
-
|
||||
<input type="text" size="3" id="onHit_boostHP_Max" ng-model="obj.hitEffect.increaseCurrentHP.max" class="at-input-stat-minmax" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="onHit_boostAP">Boost current AP (range):</label>
|
||||
<div class="field">
|
||||
<input type="text" size="3" id="onHit_boostAP_Min" ng-model="obj.hitEffect.increaseCurrentAP.min" class="at-input-stat-minmax" />
|
||||
-
|
||||
<input type="text" size="3" id="onHit_boostAP_Max" ng-model="obj.hitEffect.increaseCurrentAP.max" class="at-input-stat-minmax" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="onHit_conditionsSource">Conditions added to source</label>
|
||||
<table class="field" id="onHit_conditionsSource">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><span class="hint hint--left" data-hint="Id of the actor condition to be applied.">Condition</span></th>
|
||||
<th><span class="hint hint--left" data-hint="How strong the effect should be. For example, magnitude=2 is equal to having two effects active at the same time. Use -99 to remove permanent effects.">Magnitude</span></th>
|
||||
<th><span class="hint hint--left" data-hint="How many rounds the actor condtions should last. Use 999 for a permanent effect.">Duration</span></th>
|
||||
<th><span class="hint hint--left" data-hint="Percentage chance, integer value from 1 (very unlikely) to 100 (always).">Chance</span></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="condition in obj.hitEffect.conditionsSource">
|
||||
<td><input type="text" ng-model="condition.condition" class="at-input-id" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.magnitude" class="at-input-magnitude" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.duration" class="at-input-duration" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.chance" class="at-input-chance" /></td>
|
||||
<td><a ng-click="removeCondition(obj.hitEffect.conditionsSource, condition)" class="btn btn-mini" title="Remove row"><i class="icon-trash"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button ng-click="addCondition(obj.hitEffect.conditionsSource)" class="btn" title="Add row"><i class="icon-plus-sign"></i> Add</button>
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="onHit_conditionsTarget">Conditions added to target</label>
|
||||
<table class="field" id="onHit_conditionsTarget">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><span class="hint hint--left" data-hint="Id of the actor condition to be applied.">Condition</span></th>
|
||||
<th><span class="hint hint--left" data-hint="How strong the effect should be. For example, magnitude=2 is equal to having two effects active at the same time. Use -99 to remove permanent effects.">Magnitude</span></th>
|
||||
<th><span class="hint hint--left" data-hint="How many rounds the actor condtions should last. Use 999 for a permanent effect.">Duration</span></th>
|
||||
<th><span class="hint hint--left" data-hint="Percentage chance, integer value from 1 (very unlikely) to 100 (always).">Chance</span></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="condition in obj.hitEffect.conditionsTarget">
|
||||
<td><input type="text" ng-model="condition.condition" class="at-input-id" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.magnitude" class="at-input-magnitude" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.duration" class="at-input-duration" /></td>
|
||||
<td><input type="text" size="3" ng-model="condition.chance" class="at-input-chance" /></td>
|
||||
<td><a ng-click="removeCondition(obj.hitEffect.conditionsTarget, condition)" class="btn btn-mini" title="Remove row"><i class="icon-trash"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button ng-click="addCondition(obj.hitEffect.conditionsTarget)" class="btn" title="Add row"><i class="icon-plus-sign"></i> Add</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="endSets"> </div>
|
||||
41
AndorsTrailEdit/partials/edit_quest.html
Normal file
41
AndorsTrailEdit/partials/edit_quest.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<h3>Quest</h3>
|
||||
<fieldset>
|
||||
<legend>General</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="id" class="hint hint--top" data-hint="This id will not be displayed to the player. Prefer short but descriptive ids since it keeps the savegames smaller.">Internal ID:</label>
|
||||
<input type="text" size="30" id="id" class="field at-input-id" ng-model="obj.id" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="name">Display name:</label>
|
||||
<input type="text" size="30" id="name" class="field at-input-name" ng-model="obj.name" />
|
||||
</div>
|
||||
<div class="fieldWithLabel">
|
||||
<label class="checkbox"><input type="checkbox" id="showInLog" ng-model="obj.showInLog" ng-true-value="1" ng-false-value="0" />Show in quest log</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Stages</legend>
|
||||
<div class="fieldWithLabel">
|
||||
<label for="stages">Stages shown in quest log</label>
|
||||
<table class="field" id="stages">
|
||||
<thead><tr>
|
||||
<th><span class="hint hint--top" data-hint="This number will not be displayed to the player. Must be some unique number for this quest though. Prefer values from 10-100.">Progress</span></th>
|
||||
<th>Logtext</th>
|
||||
<th><span class="hint hint--top" data-hint="Reaching this quest stage gives this much experience">Experience</span></th>
|
||||
<th>Finishes quest</th>
|
||||
<th></th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="stage in obj.stages">
|
||||
<td><input type="text" size="3" ng-model="stage.progress" class="at-input-stat"/></td>
|
||||
<td><textarea rows="2" cols="40" ng-model="stage.logText"></textarea></td>
|
||||
<td><input type="text" size="7" ng-model="stage.rewardExperience" class="at-input-stat"/></td>
|
||||
<td><input type="checkbox" ng-model="stage.finishesQuest" ng-true-value="1" ng-false-value="0" /></td>
|
||||
<td><a ng-click="removeQuestStage(stage)" class="btn btn-mini" title="Remove row"><i class="icon-trash"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button ng-click="addQuestStage()" class="btn" title="Add row"><i class="icon-plus-sign"></i> Add</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="endSets"> </div>
|
||||
16
AndorsTrailEdit/partials/export.html
Normal file
16
AndorsTrailEdit/partials/export.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<h3>Export</h3>
|
||||
<fieldset>
|
||||
Export
|
||||
<select ng-model="selectedSection" ng-options="s.name for s in sections">
|
||||
</select>
|
||||
|
||||
<button ng-click="exportData()" class="btn btn-primary"><i class="icon-download"></i> Export</button>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<div ng-ds-fade="content">
|
||||
<textarea id="importExportTextArea" rows="9" cols="80" ng-model="content"></textarea>
|
||||
<br /><br />
|
||||
<p>Exported data should be placed in the files named <a href="http://code.google.com/p/andors-trail/source/browse/#git%2FAndorsTrail%2Fres">res/raw/*.json</a> in the source code.</p>
|
||||
</div>
|
||||
</div>
|
||||
34
AndorsTrailEdit/partials/import.html
Normal file
34
AndorsTrailEdit/partials/import.html
Normal file
@@ -0,0 +1,34 @@
|
||||
<h3>Import</h3>
|
||||
<fieldset>
|
||||
<p>Data to import can be found in the files named <a href="http://code.google.com/p/andors-trail/source/browse/#git%2FAndorsTrail%2Fres">res/raw/*.json</a> in the source code.</p>
|
||||
Import as
|
||||
<select ng-model="selectedSection" ng-options="s.name for s in sections"></select>
|
||||
|
||||
<p>
|
||||
<label for="importExisting">
|
||||
<input type="radio" name="importType" id="importExisting" value="existing" ng-model="importType"></input>
|
||||
Import content from existing files
|
||||
</label>
|
||||
<label for="importPasted">
|
||||
<input type="radio" name="importType" id="importPasted" value="paste" ng-model="importType"></input>
|
||||
Paste data to import
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<div ng-show="importType == 'paste'">
|
||||
<p>
|
||||
<textarea id="importExportTextArea" rows="9" cols="80" ng-model="content" placeholder="paste json or old resource format here"></textarea>
|
||||
</p>
|
||||
<button ng-click="importPastedData()" class="btn btn-primary pull-right"><i class="icon-upload"></i> Import</button>
|
||||
</div>
|
||||
|
||||
<div ng-show="importType == 'existing'">
|
||||
<p>
|
||||
<select ng-model="selectedFile" ng-options="f for f in availableFiles[selectedSection.id]"></select>
|
||||
</p>
|
||||
<button ng-click="importExistingData()" class="btn btn-primary pull-right"><i class="icon-upload"></i> Import</button>
|
||||
</div>
|
||||
|
||||
<div style="color: red;" ng-ds-fade="errorMsg">{{errorMsg}}</div>
|
||||
<div style="color: green;" ng-ds-fade="importedMsg">{{importedMsg}}</div>
|
||||
</div>
|
||||
5
AndorsTrailEdit/partials/start.html
Normal file
5
AndorsTrailEdit/partials/start.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<h3>Welcome to the content editor for Andor's Trail.</h3>
|
||||
|
||||
Start by importing some content from the game by pressing the top right "Import" button.<br />
|
||||
Or you could start by creating new content by selecting something from the left list.<br />
|
||||
<br />
|
||||
198
AndorsTrailEdit/partials/table_item.html
Normal file
198
AndorsTrailEdit/partials/table_item.html
Normal file
@@ -0,0 +1,198 @@
|
||||
<h3>Items</h3>
|
||||
|
||||
<label class="checkbox"><input type="checkbox" ng-model="iconID" />Icon</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="id" />Id</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="name" />Name</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="category" />Category</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="displaytype" />Display type</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="hasManualPrice" />Has manual price</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="price" />Base market cost</label>
|
||||
|
||||
<label class="checkbox"><input type="checkbox" ng-model="hasEquipEffect" />Has equip effect</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="equipEffect_increaseMaxHP" />MaxHP</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="equipEffect_increaseMaxAP" />MaxAP</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="equipEffect_increaseMoveCost" />Increase move cost</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="equipEffect_increaseUseItemCost" />Increase use item cost</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="equipEffect_increaseReequipCost" />Increase re-equip cost</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="equipEffect_increaseAttackCost" />Attack cost</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="equipEffect_increaseAttackChance" />Attack chance</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="equipEffect_increaseAttackDamage" />Attack damage</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="equipEffect_increaseCriticalSkill" />Critical skill</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="equipEffect_setCriticalMultiplier" />Critical multiplier</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="equipEffect_increaseBlockChance" />Block chance</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="equipEffect_increaseDamageResistance" />Damage resistance</label>
|
||||
|
||||
<label class="checkbox"><input type="checkbox" ng-model="useEffect" />Use effect</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="hitEffect" />Hit effect</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="killEffect" />Kill effect</label>
|
||||
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th ng-ds-fade="iconID">Icon</th>
|
||||
<th ng-ds-fade="id">
|
||||
<span class="hint hint--top" data-hint="The id is not displayed to the player anywhere. Must be a unique id (no two items may have the same id). Prefer short ids since it keeps savegames smaller.">
|
||||
Id
|
||||
</span>
|
||||
</th>
|
||||
<th ng-ds-fade="name">Name</th>
|
||||
<th ng-ds-fade="category">Category</th>
|
||||
<th ng-ds-fade="displaytype">Type</th>
|
||||
<th ng-ds-fade="hasManualPrice">Manual price?</th>
|
||||
<th ng-ds-fade="price">
|
||||
<span class="hint hint--top" data-hint="Base market cost">Price</span>
|
||||
</th>
|
||||
<th ng-ds-fade="hasEquipEffect">
|
||||
<span class="hint hint--top" data-hint="Item has an effect when equipped">Equip?</span>
|
||||
</th>
|
||||
<th ng-ds-fade="equipEffect_increaseMaxHP">
|
||||
<span class="hint hint--top" data-hint="Increase maximum HP">+MaxHP</span>
|
||||
</th>
|
||||
<th ng-ds-fade="equipEffect_increaseMaxAP">
|
||||
<span class="hint hint--top" data-hint="Increase maximum AP">+MaxAP</span>
|
||||
</th>
|
||||
<th ng-ds-fade="equipEffect_increaseMoveCost">
|
||||
<span class="hint hint--top" data-hint="Increase in AP cost of moving one tile">+MoveCost</span>
|
||||
</th>
|
||||
<th ng-ds-fade="equipEffect_increaseUseItemCost">
|
||||
<span class="hint hint--top" data-hint="Increase in AP cost of using items">+UseItemCost</span>
|
||||
</th>
|
||||
<th ng-ds-fade="equipEffect_increaseReequipCost">
|
||||
<span class="hint hint--top" data-hint="Increase in AP cost of equipping and un-equipping wearable items">+ReequipCost</span>
|
||||
</th>
|
||||
<th ng-ds-fade="equipEffect_increaseAttackCost">
|
||||
<span class="hint hint--top" data-hint="Incease in AP cost of making one attack">AtkCost</span>
|
||||
</th>
|
||||
<th ng-ds-fade="equipEffect_increaseAttackChance">
|
||||
<span class="hint hint--top" data-hint="Increase attack chance">+AC</span>
|
||||
</th>
|
||||
<th ng-ds-fade="equipEffect_increaseAttackDamage">
|
||||
<span class="hint hint--top" data-hint="Increase attack damage (min - max)">+AD</span>
|
||||
</th>
|
||||
<th ng-ds-fade="equipEffect_increaseCriticalSkill">
|
||||
<span class="hint hint--top" data-hint="Increase critical skill">+CS</span>
|
||||
</th>
|
||||
<th ng-ds-fade="equipEffect_setCriticalMultiplier">
|
||||
<span class="hint hint--top" data-hint="Set critical modifier (only for weapons)">CM</span>
|
||||
</th>
|
||||
<th ng-ds-fade="equipEffect_increaseBlockChance">
|
||||
<span class="hint hint--top" data-hint="Increase block chance">+BC</span>
|
||||
</th>
|
||||
<th ng-ds-fade="equipEffect_increaseDamageResistance">
|
||||
<span class="hint hint--top" data-hint="Increase damage resistance">+DR</span>
|
||||
</th>
|
||||
|
||||
<th ng-ds-fade="useEffect">
|
||||
<span class="hint hint--top" data-hint="Item has an effect when using it">Use?</span>
|
||||
</th>
|
||||
<th ng-ds-fade="useEffect">
|
||||
<span class="hint hint--top" data-hint="Increase current HP when using item">+HP</span>
|
||||
</th>
|
||||
<th ng-ds-fade="useEffect">
|
||||
<span class="hint hint--top" data-hint="Increase current AP when using item">+AP</span>
|
||||
</th>
|
||||
<th ng-ds-fade="hitEffect">
|
||||
<span class="hint hint--top" data-hint="Item has an effect when hitting a monster in combat">Hit?</span>
|
||||
</th>
|
||||
<th ng-ds-fade="hitEffect">
|
||||
<span class="hint hint--top" data-hint="Increase current HP when hitting monster in combat">+HP</span>
|
||||
</th>
|
||||
<th ng-ds-fade="hitEffect">
|
||||
<span class="hint hint--top" data-hint="Increase current AP when hitting monster in combat">+AP</span>
|
||||
</th>
|
||||
<th ng-ds-fade="killEffect">
|
||||
<span class="hint hint--top" data-hint="Item has an effect when killing a monster in combat">Kill?</span>
|
||||
</th>
|
||||
<th ng-ds-fade="killEffect">
|
||||
<span class="hint hint--top" data-hint="Increase current HP when killing monster in combat">+HP</span>
|
||||
</th>
|
||||
<th ng-ds-fade="killEffect">
|
||||
<span class="hint hint--top" data-hint="Increase current AP when killing monster in combat">+AP</span>
|
||||
</th>
|
||||
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="item in items">
|
||||
<td ng-ds-fade="iconID"><div ng-tile-image="item.iconID" class="at-input-icon" ng-select-image="item" ng-select-image-dest="item.iconID"></div></td>
|
||||
<td ng-ds-fade="id"><input type="text" ng-model="item.id" class="at-input-id" /></td>
|
||||
<td ng-ds-fade="name"><input type="text" ng-model="item.name" class="at-input-name" /></td>
|
||||
<td ng-ds-fade="category">
|
||||
<select ng-model="item.category" ng-options="s.name for s in itemCategories"></select>
|
||||
</td>
|
||||
<td ng-ds-fade="displaytype">
|
||||
<select ng-model="item.displaytype">
|
||||
<option value="0">Ordinary item</option>
|
||||
<option value="1">Quest item (yellow)</option>
|
||||
<option value="2">Legendary (green)</option>
|
||||
<option value="3">Extraordinary (blue)</option>
|
||||
<option value="4">Rare (purple)</option>
|
||||
</select>
|
||||
</td>
|
||||
<td ng-ds-fade="hasManualPrice"><input type="checkbox" ng-model="item.hasManualPrice" ng-true-value="1" ng-false-value="0" ng-change="updateCost(item)" /></td>
|
||||
<td ng-ds-fade="price">
|
||||
<input type="text" ng-show="item.hasManualPrice == 0" value="{{getItemCost(item)}}" readonly="readonly" class="at-input-gold" />
|
||||
<input type="text" ng-show="item.hasManualPrice == 1" ng-model="item.baseMarketCost" class="at-input-gold" />
|
||||
</td>
|
||||
<td ng-ds-fade="hasEquipEffect"><input type="checkbox" ng-model="item.hasEquipEffect" title="Has effect when equipping item?" /></td>
|
||||
<td ng-ds-fade="equipEffect_increaseMaxHP"><input type="text" ng-model="item.equipEffect.increaseMaxHP" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="equipEffect_increaseMaxAP"><input type="text" ng-model="item.equipEffect.increaseMaxAP" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="equipEffect_increaseMoveCost"><input type="text" ng-model="item.equipEffect.increaseMoveCost" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="equipEffect_increaseUseItemCost"><input type="text" ng-model="item.equipEffect.increaseUseItemCost" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="equipEffect_increaseReequipCost"><input type="text" ng-model="item.equipEffect.increaseReequipCost" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="equipEffect_increaseAttackCost"><input type="text" ng-model="item.equipEffect.increaseAttackCost" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="equipEffect_increaseAttackChance"><input type="text" ng-model="item.equipEffect.increaseAttackChance" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="equipEffect_increaseAttackDamage">
|
||||
<input type="text" ng-model="item.equipEffect.increaseAttackDamage.min" class="at-input-stat-minmax" />
|
||||
-
|
||||
<input type="text" ng-model="item.equipEffect.increaseAttackDamage.max" class="at-input-stat-minmax" />
|
||||
</td>
|
||||
<td ng-ds-fade="equipEffect_increaseCriticalSkill"><input type="text" ng-model="item.equipEffect.increaseCriticalSkill" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="equipEffect_setCriticalMultiplier"><input type="text" ng-model="item.equipEffect.setCriticalMultiplier" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="equipEffect_increaseBlockChance"><input type="text" ng-model="item.equipEffect.increaseBlockChance" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="equipEffect_increaseDamageResistance"><input type="text" ng-model="item.equipEffect.increaseDamageResistance" class="at-input-stat" /></td>
|
||||
|
||||
<td ng-ds-fade="useEffect"><input type="checkbox" ng-model="item.hasUseEffect" title="Has effect when using item?" /></td>
|
||||
<td ng-ds-fade="useEffect">
|
||||
<input type="text" ng-model="item.useEffect.increaseCurrentHP.min" class="at-input-stat-minmax" />
|
||||
-
|
||||
<input type="text" ng-model="item.useEffect.increaseCurrentHP.max" class="at-input-stat-minmax" />
|
||||
</td>
|
||||
<td ng-ds-fade="useEffect">
|
||||
<input type="text" ng-model="item.useEffect.increaseCurrentAP.min" class="at-input-stat-minmax" />
|
||||
-
|
||||
<input type="text" ng-model="item.useEffect.increaseCurrentAP.max" class="at-input-stat-minmax" />
|
||||
</td>
|
||||
|
||||
<td ng-ds-fade="hitEffect"><input type="checkbox" ng-model="item.hasHitEffect" title="Has effect when hitting a target in combat?" /></td>
|
||||
<td ng-ds-fade="hitEffect">
|
||||
<input type="text" ng-model="item.hitEffect.increaseCurrentHP.min" class="at-input-stat-minmax" />
|
||||
-
|
||||
<input type="text" ng-model="item.hitEffect.increaseCurrentHP.max" class="at-input-stat-minmax" />
|
||||
</td>
|
||||
<td ng-ds-fade="hitEffect">
|
||||
<input type="text" ng-model="item.hitEffect.increaseCurrentAP.min" class="at-input-stat-minmax" />
|
||||
-
|
||||
<input type="text" ng-model="item.hitEffect.increaseCurrentAP.max" class="at-input-stat-minmax" />
|
||||
</td>
|
||||
|
||||
<td ng-ds-fade="killEffect"><input type="checkbox" ng-model="item.hasKillEffect" title="Has effect when killing a target in combat?" /></td>
|
||||
<td ng-ds-fade="killEffect">
|
||||
<input type="text" ng-model="item.killEffect.increaseCurrentHP.min" class="at-input-stat-minmax" />
|
||||
-
|
||||
<input type="text" ng-model="item.killEffect.increaseCurrentHP.max" class="at-input-stat-minmax" />
|
||||
</td>
|
||||
<td ng-ds-fade="killEffect">
|
||||
<input type="text" ng-model="item.killEffect.increaseCurrentAP.min" class="at-input-stat-minmax" />
|
||||
-
|
||||
<input type="text" ng-model="item.killEffect.increaseCurrentAP.max" class="at-input-stat-minmax" />
|
||||
</td>
|
||||
|
||||
<td><a ng-click="edit(item)" class="btn"><i class="icon-forward"></i> Edit</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="endSets"> </div>
|
||||
133
AndorsTrailEdit/partials/table_monster.html
Normal file
133
AndorsTrailEdit/partials/table_monster.html
Normal file
@@ -0,0 +1,133 @@
|
||||
<h3>Monsters / NPCs</h3>
|
||||
|
||||
<label class="checkbox"><input type="checkbox" ng-model="iconID" />Icon</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="id" />Id</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="name" />Name</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="spawnGroup" />Spawngroup</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="unique" />Unique</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="monsterClass" />Class</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="phraseID" />Phrase</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="droplistID" />Droplist</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="experience" />Experience</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="maxAP" />Max AP</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="moveCost" />Move cost</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="maxHP" />Max health</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="attackCost" />Attack cost</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="attackChance" />Attack chance</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="attackDamage" />Attack damage</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="hasCritical" />Has critical hits</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="criticalSkill" />Critical skill</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="criticalMultiplier" />Critical multiplier</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="blockChance" />Clock chance</label>
|
||||
<label class="checkbox"><input type="checkbox" ng-model="damageResistance" />Damage resistance</label>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th ng-ds-fade="iconID">Icon</th>
|
||||
<th ng-ds-fade="id">
|
||||
<span class="hint hint--top" data-hint="The id is not displayed to the player anywhere. Must be a unique id (no two monster may have the same id). Prefer short ids since it keeps savegames smaller.">
|
||||
Id
|
||||
</span>
|
||||
</th>
|
||||
<th ng-ds-fade="name">Name</th>
|
||||
<th ng-ds-fade="spawnGroup">
|
||||
<span class="hint hint--top" data-hint="The name to enter on spawn areas in TMX map files for spawning this type of monster. Several monster types may have the same spawngroup, which makes the game spawn one random monster type from the spawngroup.">
|
||||
Spawngroup
|
||||
</span>
|
||||
</th>
|
||||
<th ng-ds-fade="unique">
|
||||
<span class="hint hint--top" data-hint="Unique monsters will not respawn. Typically used for bosses.">Unique</span>
|
||||
</th>
|
||||
<th ng-ds-fade="monsterClass">Class</th>
|
||||
<th ng-ds-fade="phraseID">
|
||||
<span class="hint hint--top" data-hint="ID of the starting conversation phrase that will be used when engaging in conversation with this NPC.">Phrase</span>
|
||||
</th>
|
||||
<th ng-ds-fade="droplistID">
|
||||
<span class="hint hint--top" data-hint="ID of the droplist that will contain the items that are dropped when the monster is killed. If this monster is an NPC, this is the list of items that are available to buy as shop items.">
|
||||
Droplist
|
||||
</span>
|
||||
</th>
|
||||
<th ng-ds-fade="experience">
|
||||
<span class="hint hint--top" data-hint="Experience">Exp</span>
|
||||
</th>
|
||||
<th ng-ds-fade="maxAP">
|
||||
<span class="hint hint--top" data-hint="Maximum action points">AP</span>
|
||||
</th>
|
||||
<th ng-ds-fade="moveCost">
|
||||
<span class="hint hint--top" data-hint="AP cost of moving one tile">MoveCost</span>
|
||||
</th>
|
||||
<th ng-ds-fade="maxHP">
|
||||
<span class="hint hint--top" data-hint="Maximum health points">HP</span>
|
||||
</th>
|
||||
<th ng-ds-fade="attackCost">
|
||||
<span class="hint hint--top" data-hint="AP cost of doing one attack">AttackCost</span>
|
||||
</th>
|
||||
<th ng-ds-fade="attackChance">
|
||||
<span class="hint hint--top" data-hint="Attack chance">AC</span>
|
||||
</th>
|
||||
<th ng-ds-fade="attackDamage">
|
||||
<span class="hint hint--top" data-hint="Attack damage (min - max)">AD</span>
|
||||
</th>
|
||||
<th ng-ds-fade="hasCritical">
|
||||
<span class="hint hint--top" data-hint="May cause critical attacks">Crit?</span>
|
||||
</th>
|
||||
<th ng-ds-fade="criticalSkill">
|
||||
<span class="hint hint--top" data-hint="Critical skill">CS</span>
|
||||
</th>
|
||||
<th ng-ds-fade="criticalMultiplier">
|
||||
<span class="hint hint--top" data-hint="Critical multiplier">CM</span>
|
||||
</th>
|
||||
<th ng-ds-fade="blockChance">
|
||||
<span class="hint hint--top" data-hint="Block chance">BC</span>
|
||||
</th>
|
||||
<th ng-ds-fade="damageResistance">
|
||||
<span class="hint hint--top" data-hint="Damage resistance">DR</span>
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="monster in monsters">
|
||||
<td ng-ds-fade="iconID"><div ng-tile-image="monster.iconID" class="at-input-icon" ng-select-image="monster" ng-select-image-dest="monster.iconID"></div></td>
|
||||
<td ng-ds-fade="id"><input type="text" ng-model="monster.id" class="at-input-id" /></td>
|
||||
<td ng-ds-fade="name"><input type="text" ng-model="monster.name" class="at-input-name" /></td>
|
||||
<td ng-ds-fade="spawnGroup"><input type="text" ng-model="monster.spawnGroup" class="at-input-id" /></td>
|
||||
<td ng-ds-fade="unique"><input type="checkbox" ng-model="monster.unique" ng-true-value="1" ng-false-value="0" /></td>
|
||||
<td ng-ds-fade="monsterClass">
|
||||
<select ng-model="monster.monsterClass">
|
||||
<option value="0">Humanoid</option>
|
||||
<option value="1">Insect</option>
|
||||
<option value="2">Demon</option>
|
||||
<option value="3">Construct</option>
|
||||
<option value="4">Animal</option>
|
||||
<option value="5">Giant</option>
|
||||
<option value="6">Undead</option>
|
||||
<option value="7">Reptile</option>
|
||||
<option value="8">Ghost</option>
|
||||
</select>
|
||||
</td>
|
||||
<td ng-ds-fade="phraseID"><input type="text" ng-model="monster.phraseID" class="at-input-id" /></td>
|
||||
<td ng-ds-fade="droplistID"><input type="text" ng-model="monster.droplistID" class="at-input-id" /></td>
|
||||
<td ng-ds-fade="experience"><input type="text" value="{{getExperience(monster)}}" class="at-input-stat" readonly="readonly" /></td>
|
||||
<td ng-ds-fade="maxAP"><input type="text" ng-model="monster.maxAP" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="moveCost"><input type="text" ng-model="monster.moveCost" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="maxHP"><input type="text" ng-model="monster.maxHP" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="attackCost"><input type="text" ng-model="monster.attackCost" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="attackChance"><input type="text" ng-model="monster.attackChance" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="attackDamage">
|
||||
<input type="text" ng-model="monster.attackDamage.min" class="at-input-stat-minmax" />
|
||||
-
|
||||
<input type="text" ng-model="monster.attackDamage.max" class="at-input-stat-minmax" />
|
||||
</td>
|
||||
<td ng-ds-fade="hasCritical"><input type="checkbox" ng-model="monster.hasCritical" /></td>
|
||||
<td ng-ds-fade="criticalSkill"><input type="text" ng-model="monster.criticalSkill" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="criticalMultiplier"><input type="text" ng-model="monster.criticalMultiplier" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="blockChance"><input type="text" ng-model="monster.blockChance" class="at-input-stat" /></td>
|
||||
<td ng-ds-fade="damageResistance"><input type="text" ng-model="monster.damageResistance" class="at-input-stat" /></td>
|
||||
<td><a ng-click="edit(monster)" class="btn"><i class="icon-forward"></i> Edit</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="endSets"> </div>
|
||||
74
AndorsTrailEdit/styles.css
Normal file
74
AndorsTrailEdit/styles.css
Normal file
@@ -0,0 +1,74 @@
|
||||
html, body { margin:0; padding:0; }
|
||||
#top { background-color: #a0c0ff; color: #eeeeee; }
|
||||
#top #title { font-size: 2em; float: left; text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; vertical-align: middle; }
|
||||
#top #version { font-size: 10pt; margin-left: 3ex; }
|
||||
.andorsTrailLogo { background-image: url(logo.png); background-repeat: no-repeat; background-position: 3px 3px; padding:20px 0px 15px 50px; }
|
||||
#top #buttons { float: right; font-size: 1.2em; margin: 10px; }
|
||||
.workarea { margin: 5px; position: absolute; top: 54px; }
|
||||
#left { width: 250px; padding: 0px; font-size: 1em; }
|
||||
#center { left: 265px; right: 0; border-left: 2px #c0d0ff solid; padding-left: 5px; }
|
||||
|
||||
.hidden { display: none; }
|
||||
|
||||
.at-input-id, .at-input-name
|
||||
{ width: 200px; }
|
||||
.at-input-stat, .at-input-stat-minmax, .at-input-quantity, .at-input-chance, .at-input-magnitude, .at-input-duration
|
||||
{ width: 50px; }
|
||||
.at-input-gold { width: 80px; }
|
||||
.at-input-iconID { width: 120px; }
|
||||
.at-input-icon { display: inline-block; vertical-align: top; }
|
||||
.at-input-icon:hover { -moz-box-shadow: 0 0 15px blue; -webkit-box-shadow: 0 0 15px blue; box-shadow: 0 0 15px blue; }
|
||||
|
||||
.workarea h3 { font-size: 18px; margin: 0 0 0 5px; }
|
||||
.workarea legend { font-size: 16px; margin: 0 0 5px 0; }
|
||||
.workarea fieldset { float:left; margin: 1ex; border-right: 1px solid #ddd; padding-right: 5px; }
|
||||
.workarea .endSets { clear: both; }
|
||||
|
||||
#left .accordion-group { background-color: #e0e0e0; border: 1px solid #bbb; margin-bottom: 6px; -moz-box-shadow: 4px 4px 5px #bbb; -webkit-box-shadow: 4px 4px 5px #bbb; box-shadow: 4px 4px 5px #bbb; }
|
||||
.itemlist { list-style: none; padding: 0px; margin: 0px; border: 1px solid #bbb; }
|
||||
.itemlist li { padding: 2px 5px 2px 5px; }
|
||||
.itemlist li img { float: left; margin-right: 0.5ex; }
|
||||
.itemlist li:nth-child(odd) { background-color: #eee; }
|
||||
.itemlist li:hover { background-color: #d7d7ff; cursor: pointer; }
|
||||
.itemlist li img { float: left; }
|
||||
|
||||
.fieldWithLabel label { margin-top: 1.1ex; }
|
||||
.fieldWithLabel table { border-collapse: collapse; margin-bottom: 1ex; }
|
||||
.fieldWithLabel table th { border: 1px #ccc solid; padding: 0.5ex; }
|
||||
.fieldWithLabel table td { border: 1px #ccc solid; padding: 0.5ex; }
|
||||
.fieldWithLabel table tbody tr:nth-child(even) { background-color: #eee }
|
||||
.fieldWithLabel table tbody tr:hover { background-color: #d7d7ff; }
|
||||
|
||||
#dialogueTree { width: 400px; }
|
||||
#dialogueTree ul { list-style: none; margin-left: 10px; }
|
||||
#dialogueTree li { }
|
||||
#dialogueTree .selected { background-color: #d7d7ff; }
|
||||
.dialogueConditional { color: #855; }
|
||||
|
||||
.tools-buttons { padding-bottom: 10px; }
|
||||
#importExportTextArea { width: 500px; }
|
||||
|
||||
.validateStep { border: 1px #d7d7ff solid; background-color: white; padding: 1em; margin: 2em; float: left; }
|
||||
.validateStep h1 { font-size: 1.1em; }
|
||||
.validateStep h1 .number { font-size: 1.3em; font-weight: bold; text-shadow: rgba(0, 0, 0, 0.3) 1px 1px 1px; }
|
||||
.validateStep .buttons { padding-top: 10px; }
|
||||
|
||||
#validateResultContent table { border-collapse: collapse; margin-bottom: 1ex; }
|
||||
#validateResultContent table th,td { border: 1px #ccc solid; text-align: left; }
|
||||
#validateResultContent table tbody tr:nth-child(even) { background-color: #eee }
|
||||
#validateResultContent table .ok { background-color: green; }
|
||||
#validateResultContent table .red { background-color: red; }
|
||||
#validateResultContent table .yellow { background-color: yellow; }
|
||||
#showValidationWarnings { cursor: pointer; }
|
||||
#showValidationWarnings:hover { background-color: #d7d7ff; }
|
||||
|
||||
.clickToEdit { cursor: pointer; }
|
||||
.clickToEdit:hover { background-color: #d7d7ff; }
|
||||
|
||||
#validateResultContent { width: 400px; float: left; }
|
||||
#editorForms { width: 670px; float: right;}
|
||||
#editorForms #translation_edit_list { table-layout: fixed; }
|
||||
#editorForms #translation_edit_list tr:nth-child(1) { width: 17em }
|
||||
#editorForms #translation_edit_list tr:nth-child(2) { width: 8em }
|
||||
#editorForms #translation_edit_list textarea { width: 100%; height: 8em; }
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
html,body { margin:0; padding:0; height: 100%; font-size: 0.9em; }
|
||||
#screen { height: 100%; background-color: #a0c0ff; color: black; position: relative; font-family: sans-serif; }
|
||||
#screen #top { height: 50px; color: #eeeeee; }
|
||||
#screen #top #title { font-size: 2em; float: left; text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; }
|
||||
#screen #top #version { font-size: 10pt; margin-left: 3ex; }
|
||||
.andorsTrailLogo { background-image: url(logo.png); background-repeat: no-repeat; background-position: 3px 3px; padding:10px 0px 15px 50px; }
|
||||
#screen #top #buttons { float: right; font-size: 1.2em; margin: 10px; }
|
||||
#screen .workarea { margin: 5px; border: 1px #c0d0ff solid; background-color: #eeeeee; position: absolute; top: 50px; bottom: 0; }
|
||||
#screen #left { width: 250px; padding: 0px; font-size: 1em; }
|
||||
#screen #center { left: 256px; right: 0; }
|
||||
#screen #center #tabs { border: 0px; padding: 0px; }
|
||||
#screen #centerwide { left: 0px; right: 0; }
|
||||
|
||||
.ui-icon-close { float: left; margin: 0.4em 0.2em 0 0; cursor: pointer; }
|
||||
.hidden { display: none; }
|
||||
|
||||
.fieldWithLabel { font-size: 0.9em; }
|
||||
.fieldWithLabel .label { display: block; margin-top: 1ex; }
|
||||
.fieldWithLabel .field { display: block; }
|
||||
.fieldWithLabel .hint { }
|
||||
.fieldWithLabel .fieldInput { vertical-align: top; }
|
||||
.fieldSet { float: left; margin: 1ex; background-color: #f7f7ff; }
|
||||
.endSets { clear: both; }
|
||||
|
||||
#screen #left div { }
|
||||
.itemlist { border: 1px #bbb solid; list-style: none; padding: 0px; margin: 0px; line-height: 1.3; margin-bottom: 2ex; }
|
||||
.itemlist li { cursor: pointer; padding: 0.5ex 1ex 0.5ex 1ex; }
|
||||
.itemlist li img { float: left; margin-right: 0.5ex; }
|
||||
.itemlist li:nth-child(odd) { background-color: #eee; border-top: 1px #ddd solid; border-bottom: 1px #ddd solid; }
|
||||
.itemlist li:hover { background-color: #d7d7ff; }
|
||||
.importexport-header { font-weight: bold; padding-top: 1ex; }
|
||||
#dialog-importexport #value { font-family: monospace; font-size: 7pt; }
|
||||
.fieldWithLabel table { border-collapse: collapse; margin-bottom: 1ex; }
|
||||
.fieldWithLabel table th { border: 1px #ccc solid; padding: 0.5ex; }
|
||||
.fieldWithLabel table td { border: 1px #ccc solid; padding: 0.5ex; cursor: pointer; }
|
||||
.fieldWithLabel table tbody tr:nth-child(even) { background-color: #eee }
|
||||
.fieldWithLabel table tbody tr:hover { background-color: #d7d7ff; }
|
||||
#dialogueTreeContainer { }
|
||||
#dialogueTree { width: 400px; }
|
||||
#dialogueData { }
|
||||
input[readonly] { color: #888; }
|
||||
.imageButton { padding: 5px; }
|
||||
.importexport-description { padding: 15px; text-align: right; }
|
||||
.tools-buttons { padding-bottom: 10px; }
|
||||
|
||||
.validateStep { border: 1px #d7d7ff solid; background-color: white; padding: 1em; margin: 2em; float: left; }
|
||||
.validateStep h1 { font-size: 1.1em; }
|
||||
.validateStep h1 .number { font-size: 1.3em; font-weight: bold; text-shadow: rgba(0, 0, 0, 0.3) 1px 1px 1px; }
|
||||
.validateStep .buttons { padding-top: 10px; }
|
||||
|
||||
#validateResultContent table { border-collapse: collapse; margin-bottom: 1ex; }
|
||||
#validateResultContent table th,td { border: 1px #ccc solid; text-align: left; }
|
||||
#validateResultContent table tbody tr:nth-child(even) { background-color: #eee }
|
||||
#validateResultContent table .ok { background-color: green; }
|
||||
#validateResultContent table .red { background-color: red; }
|
||||
#validateResultContent table .yellow { background-color: yellow; }
|
||||
#showValidationWarnings { cursor: pointer; }
|
||||
#showValidationWarnings:hover { background-color: #d7d7ff; }
|
||||
|
||||
.clickToEdit { cursor: pointer; }
|
||||
.clickToEdit:hover { background-color: #d7d7ff; }
|
||||
|
||||
#validateResultContent { width: 400px; float: left;d }
|
||||
#editorForms { width: 670px; float: right;}
|
||||
#editorForms #translation_edit_list { table-layout: fixed; }
|
||||
#editorForms #translation_edit_list tr:nth-child(1) { width: 17em }
|
||||
#editorForms #translation_edit_list tr:nth-child(2) { width: 8em }
|
||||
#editorForms #translation_edit_list textarea { width: 100%; height: 8em; }
|
||||
|
||||
@@ -1,479 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Andor's Trail editor unit tests</title>
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" type="text/css" media="screen" />
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js"></script>
|
||||
<script type="text/javascript" src="AndorsTrailEditor.js"></script>
|
||||
<script type="text/javascript" src="inc/qunit.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
// ========================================================
|
||||
|
||||
module("FieldList");
|
||||
|
||||
test("Deserialization of header", function() {
|
||||
var header = "[Id|Name|Spells[SpellID|SpellName|]|Size|]";
|
||||
var ds = new FieldList(header);
|
||||
equals(ds._fields.length, 4);
|
||||
equals(ds._fields[0], "Id");
|
||||
equals(ds._fields[1], "Name");
|
||||
equals(ds._fields[2]._name, "Spells");
|
||||
equals(ds._fields[2]._fields.length, 2);
|
||||
equals(ds._fields[2]._fields[0], "SpellID");
|
||||
equals(ds._fields[2]._fields[1], "SpellName");
|
||||
equals(ds._fields[3], "Size");
|
||||
});
|
||||
|
||||
test("Deserialization of header with multiple lists", function() {
|
||||
var header = "[Id|Name|Spells[SpellID|SpellName|]|Size|Drops[ItemID|]|]";
|
||||
var ds = new FieldList(header);
|
||||
equals(ds._fields.length, 5);
|
||||
equals(ds._fields[0], "Id");
|
||||
equals(ds._fields[1], "Name");
|
||||
equals(ds._fields[2]._name, "Spells");
|
||||
equals(ds._fields[2]._fields.length, 2);
|
||||
equals(ds._fields[2]._fields[0], "SpellID");
|
||||
equals(ds._fields[2]._fields[1], "SpellName");
|
||||
equals(ds._fields[3], "Size");
|
||||
equals(ds._fields[4]._name, "Drops");
|
||||
equals(ds._fields[4]._fields.length, 1);
|
||||
equals(ds._fields[4]._fields[0], "ItemID");
|
||||
});
|
||||
|
||||
test("Serialization of header", function() {
|
||||
var header = "[Id|Name|Spells[SpellID|SpellName|]|Size|]";
|
||||
var ds = new FieldList(header);
|
||||
equals(ds.getHeader(), header);
|
||||
equals(ds.getHeaderLine(), header + ";");
|
||||
});
|
||||
|
||||
test("Finding header in text", function() {
|
||||
var ds = findHeader("[Id|Name|[SpellID|SpellName|]|Size|];");
|
||||
ok(ds);
|
||||
equals(ds._fields.length, 4);
|
||||
|
||||
ds = findHeader("[Id|Name|[SpellID|SpellName|]|Size|]");
|
||||
ok(!ds);
|
||||
|
||||
ds = findHeader("\n[Id|Name|[SpellID|SpellName|]|Size|];");
|
||||
ok(ds);
|
||||
equals(ds._fields.length, 4);
|
||||
|
||||
ds = findHeader("\ntest\n[Id|Name|[SpellID|SpellName|]|Size|];");
|
||||
ok(ds);
|
||||
equals(ds._fields.length, 4);
|
||||
|
||||
ds = findHeader("\ntest\n[Id|Name|[SpellID|SpellName|]|Size|];\ntest2\n");
|
||||
ok(ds);
|
||||
equals(ds._fields.length, 4);
|
||||
|
||||
ds = findHeader("\ntest\n{Test|Foo|};\n[Id|Name|[SpellID|SpellName|]|Size|];\ntest2\n");
|
||||
ok(ds);
|
||||
equals(ds._fields.length, 4);
|
||||
|
||||
ds = findHeader("\ntest\n[Id|Name|[SpellID|SpellName|]|Size|];\n{Test|Foo|};\n");
|
||||
ok(ds);
|
||||
equals(ds._fields.length, 4);
|
||||
});
|
||||
|
||||
// ========================================================
|
||||
|
||||
module("deserializeObject");
|
||||
|
||||
test("Simple object deserialization", function() {
|
||||
var ds = new FieldList("[Id|Name|SpellID|]");
|
||||
var obj = deserializeObject(ds, "{23|TestObject|50|}");
|
||||
ok(obj);
|
||||
equals(obj.Id, 23);
|
||||
equals(obj.Name, "TestObject");
|
||||
equals(obj.SpellID, 50);
|
||||
});
|
||||
|
||||
test("Hierarcical object deserialization", function() {
|
||||
var ds = new FieldList("[Id|Name|Spells[SpellID|SpellName|]|Size|]");
|
||||
var obj = deserializeObject(ds, "{23|TestObject|{{50|Heal|}{51|Curse|}}|Large|}");
|
||||
ok(obj);
|
||||
equals(obj.Id, 23);
|
||||
equals(obj.Name, "TestObject");
|
||||
ok(obj.Spells);
|
||||
equals(obj.Spells.length, 2);
|
||||
equals(obj.Spells[0].SpellID, 50);
|
||||
equals(obj.Spells[0].SpellName, "Heal");
|
||||
equals(obj.Spells[1].SpellID, 51);
|
||||
equals(obj.Spells[1].SpellName, "Curse");
|
||||
equals(obj.Size, "Large");
|
||||
});
|
||||
|
||||
test("Multiple hierarcical object deserialization", function() {
|
||||
var ds = new FieldList("[Id|Name|Spells[SpellID|SpellName|]|Size|Drops[ItemID|]|Effects[EffectID|]|]");
|
||||
var obj = deserializeObject(ds, "{23|TestObject|{{50|Heal|}{51|Curse|}}|Large|{{4|}}||}");
|
||||
ok(obj);
|
||||
equals(obj.Id, 23);
|
||||
equals(obj.Name, "TestObject");
|
||||
ok(obj.Spells);
|
||||
equals(obj.Spells.length, 2);
|
||||
equals(obj.Spells[0].SpellID, 50);
|
||||
equals(obj.Spells[0].SpellName, "Heal");
|
||||
equals(obj.Spells[1].SpellID, 51);
|
||||
equals(obj.Spells[1].SpellName, "Curse");
|
||||
equals(obj.Size, "Large");
|
||||
ok(obj.Drops);
|
||||
equals(obj.Drops.length, 1);
|
||||
equals(obj.Drops[0].ItemID, 4);
|
||||
ok(obj.Effects);
|
||||
equals(obj.Effects.length, 0);
|
||||
});
|
||||
|
||||
test("Hierarcical object deserialization with whitespaces", function() {
|
||||
var ds = new FieldList("[Id|Name|Spells[SpellID|SpellName|]|Size|]");
|
||||
var obj = deserializeObject(ds, "{23|TestObject|{\n\t{50|Heal|}\n\t{51|Curse|}\n\t}|Large|}");
|
||||
ok(obj);
|
||||
equals(obj.Id, 23);
|
||||
equals(obj.Name, "TestObject");
|
||||
ok(obj.Spells);
|
||||
equals(obj.Spells.length, 2);
|
||||
equals(obj.Spells[0].SpellID, 50);
|
||||
equals(obj.Spells[0].SpellName, "Heal");
|
||||
equals(obj.Spells[1].SpellID, 51);
|
||||
equals(obj.Spells[1].SpellName, "Curse");
|
||||
equals(obj.Size, "Large");
|
||||
});
|
||||
|
||||
// ========================================================
|
||||
|
||||
module("serializeObject");
|
||||
|
||||
test("Simple object serialization", function() {
|
||||
var ds = new FieldList("[Id|Name|SpellID|]");
|
||||
var obj = new Object();
|
||||
obj.Id = 23;
|
||||
obj.Name = "TestObject";
|
||||
obj.SpellID = 50;
|
||||
|
||||
equals(serializeObject(ds, obj), "{23|TestObject|50|}");
|
||||
});
|
||||
|
||||
test("Hierarcical object serialization", function() {
|
||||
var ds = new FieldList("[Id|Name|Spells[SpellID|SpellName|]|Size|]");
|
||||
var obj = new Object();
|
||||
obj.Id = 23;
|
||||
obj.Name = "TestObject";
|
||||
obj.Spells = [];
|
||||
obj.Spells[0] = new Object();
|
||||
obj.Spells[0].SpellID = 50;
|
||||
obj.Spells[0].SpellName = "Heal";
|
||||
obj.Spells[1] = new Object();
|
||||
obj.Spells[1].SpellID = 51;
|
||||
obj.Spells[1].SpellName = "Curse";
|
||||
obj.Size = "Large";
|
||||
|
||||
equals(serializeObject(ds, obj), "{23|TestObject|{\n\t{50|Heal|}\n\t{51|Curse|}\n\t}|Large|}");
|
||||
});
|
||||
|
||||
test("Multiple hierarcical object serialization", function() {
|
||||
var ds = new FieldList("[Id|Name|Spells[SpellID|SpellName|]|Size|Drops[ItemID|]|Effects[EffectID|]|]");
|
||||
var obj = new Object();
|
||||
obj.Id = 23;
|
||||
obj.Name = "TestObject";
|
||||
obj.Spells = [];
|
||||
obj.Spells[0] = new Object();
|
||||
obj.Spells[0].SpellID = 50;
|
||||
obj.Spells[0].SpellName = "Heal";
|
||||
obj.Spells[1] = new Object();
|
||||
obj.Spells[1].SpellID = 51;
|
||||
obj.Spells[1].SpellName = "Curse";
|
||||
obj.Size = "Large";
|
||||
obj.Drops = [];
|
||||
obj.Drops[0] = new Object();
|
||||
obj.Drops[0].ItemID = 4;
|
||||
obj.Effects = [];
|
||||
|
||||
equals(serializeObject(ds, obj), "{23|TestObject|{\n\t{50|Heal|}\n\t{51|Curse|}\n\t}|Large|{{4|}}||}");
|
||||
});
|
||||
|
||||
test("Object serialization with undefined fields", function() {
|
||||
var ds = new FieldList("[Id|Name|SpellID|]");
|
||||
var obj = new Object();
|
||||
obj.Name = "TestObject";
|
||||
obj.SpellID = 50;
|
||||
|
||||
equals(serializeObject(ds, obj), "{|TestObject|50|}");
|
||||
});
|
||||
|
||||
// ========================================================
|
||||
|
||||
module("serializeObjectList");
|
||||
|
||||
test("Simple object serialization", function() {
|
||||
var ds = new FieldList("[Id|Name|SpellID|]");
|
||||
var list = [];
|
||||
var obj = new Object();
|
||||
obj.Id = 23;
|
||||
obj.Name = "TestObject";
|
||||
obj.SpellID = 50;
|
||||
list[0] = obj;
|
||||
obj = new Object();
|
||||
obj.Id = 25;
|
||||
obj.Name = "Foo";
|
||||
obj.SpellID = 9;
|
||||
list[1] = obj;
|
||||
|
||||
equals(serializeObjectList(ds, list), "[Id|Name|SpellID|];\n{23|TestObject|50|};\n{25|Foo|9|};\n");
|
||||
});
|
||||
|
||||
test("Serialize empty list", function() {
|
||||
var ds = new FieldList("[Id|Name|SpellID|]");
|
||||
var list = [];
|
||||
equals(serializeObjectList(ds, list), "[Id|Name|SpellID|];\n");
|
||||
});
|
||||
|
||||
// ========================================================
|
||||
|
||||
module("deserializeObjectList");
|
||||
|
||||
test("Simple object deserialization", function() {
|
||||
var ds = new FieldList("[Id|Name|SpellID|]");
|
||||
var list = deserializeObjectList(ds, "{23|TestObject|50|};\n{25|Foo|9|};");
|
||||
ok(list);
|
||||
equals(list.length, 2);
|
||||
|
||||
var obj = list[0];
|
||||
ok(obj);
|
||||
equals(obj.Id, 23);
|
||||
equals(obj.Name, "TestObject");
|
||||
equals(obj.SpellID, 50);
|
||||
|
||||
var obj = list[1];
|
||||
ok(obj);
|
||||
equals(obj.Id, 25);
|
||||
equals(obj.Name, "Foo");
|
||||
equals(obj.SpellID, 9);
|
||||
});
|
||||
|
||||
test("Deserialize empty list", function() {
|
||||
var ds = new FieldList("[Id|Name|SpellID|]");
|
||||
var list = deserializeObjectList(ds, "");
|
||||
ok(list);
|
||||
equals(list.length, 0);
|
||||
|
||||
list = deserializeObjectList(ds, "test value};");
|
||||
ok(list);
|
||||
equals(list.length, 0);
|
||||
});
|
||||
|
||||
test("Deserialize garbage values", function() {
|
||||
var ds = new FieldList("[Id|Name|SpellID|]");
|
||||
var list = deserializeObjectList(ds, "test value};");
|
||||
ok(list);
|
||||
equals(list.length, 0);
|
||||
|
||||
list = deserializeObjectList(ds, "{23|TestObject|50|};\nfoo\n\n{25|Foo|9|};\nbaz\n");
|
||||
ok(list);
|
||||
equals(list.length, 2);
|
||||
|
||||
var obj = list[0];
|
||||
ok(obj);
|
||||
equals(obj.Id, 23);
|
||||
equals(obj.Name, "TestObject");
|
||||
equals(obj.SpellID, 50);
|
||||
|
||||
var obj = list[1];
|
||||
ok(obj);
|
||||
equals(obj.Id, 25);
|
||||
equals(obj.Name, "Foo");
|
||||
equals(obj.SpellID, 9);
|
||||
});
|
||||
|
||||
// ========================================================
|
||||
|
||||
module("Combined serialization");
|
||||
|
||||
test("Serialization -> deserialization", function() {
|
||||
var ds = new FieldList("[Id|Name|Spells[SpellID|SpellName|]|Size|Drops[ItemID|]|Effects[EffectID|]|]");
|
||||
var obj = new Object();
|
||||
obj.Id = 23;
|
||||
obj.Name = "TestObject";
|
||||
obj.Spells = [];
|
||||
obj.Spells[0] = new Object();
|
||||
obj.Spells[0].SpellID = 50;
|
||||
obj.Spells[0].SpellName = "Heal";
|
||||
obj.Spells[1] = new Object();
|
||||
obj.Spells[1].SpellID = 51;
|
||||
obj.Spells[1].SpellName = "Curse";
|
||||
obj.Size = "Large";
|
||||
obj.Drops = [];
|
||||
obj.Drops[0] = new Object();
|
||||
obj.Drops[0].ItemID = 4;
|
||||
obj.Effects = [];
|
||||
|
||||
|
||||
var obj = deserializeObject(ds, serializeObject(ds, obj));
|
||||
ok(obj);
|
||||
equals(obj.Id, 23);
|
||||
equals(obj.Name, "TestObject");
|
||||
ok(obj.Spells);
|
||||
equals(obj.Spells.length, 2);
|
||||
equals(obj.Spells[0].SpellID, 50);
|
||||
equals(obj.Spells[0].SpellName, "Heal");
|
||||
equals(obj.Spells[1].SpellID, 51);
|
||||
equals(obj.Spells[1].SpellName, "Curse");
|
||||
equals(obj.Size, "Large");
|
||||
ok(obj.Drops);
|
||||
equals(obj.Drops.length, 1);
|
||||
equals(obj.Drops[0].ItemID, 4);
|
||||
ok(obj.Effects);
|
||||
equals(obj.Effects.length, 0);
|
||||
|
||||
});
|
||||
|
||||
// ========================================================
|
||||
|
||||
module("Regex test");
|
||||
|
||||
test("test1", function() {
|
||||
var expression = /'/gm;
|
||||
var str = "Test'value'";
|
||||
|
||||
var str2 = str.replace(expression, '_');
|
||||
equals(str2, "Test_value_");
|
||||
|
||||
str2 = str.replace(expression, "\\'");
|
||||
equals(str2, "Test\\'value\\'");
|
||||
|
||||
});
|
||||
|
||||
// ========================================================
|
||||
|
||||
module("Serialization and deserialization with special characters");
|
||||
|
||||
test("Serialization of newline", function() {
|
||||
var ds = new FieldList("[Id|Name|SpellID|]");
|
||||
var obj = new Object();
|
||||
obj.Id = 3;
|
||||
obj.Name = "Test\nObject\nValue";
|
||||
obj.SpellID = 50;
|
||||
|
||||
equals(serializeObject(ds, obj), "{3|Test\\nObject\\nValue|50|}");
|
||||
});
|
||||
|
||||
test("Deserialization of newline", function() {
|
||||
var ds = new FieldList("[Id|Name|SpellID|]");
|
||||
var obj = deserializeObject(ds, "{3|Test\\nObject\\nValue|50|}");
|
||||
ok(obj);
|
||||
equals(obj.Id, 3);
|
||||
equals(obj.Name, "Test\nObject\nValue");
|
||||
equals(obj.SpellID, 50);
|
||||
});
|
||||
|
||||
test("Serialization of single quote", function() {
|
||||
var ds = new FieldList("[Id|Name|SpellID|]");
|
||||
var obj = new Object();
|
||||
obj.Id = 3;
|
||||
obj.Name = "Test 'Object'";
|
||||
obj.SpellID = 50;
|
||||
|
||||
equals(serializeObject(ds, obj), "{3|Test \\'Object\\'|50|}");
|
||||
});
|
||||
|
||||
test("Deserialization of single quote", function() {
|
||||
var ds = new FieldList("[Id|Name|SpellID|]");
|
||||
var obj = deserializeObject(ds, "{3|Test \\'Object\\'|50|}");
|
||||
ok(obj);
|
||||
equals(obj.Id, 3);
|
||||
equals(obj.Name, "Test 'Object'");
|
||||
equals(obj.SpellID, 50);
|
||||
});
|
||||
|
||||
// ========================================================
|
||||
|
||||
module("DataStore");
|
||||
|
||||
test("Getting and putting items", function() {
|
||||
var ds = new DataStore({objectTypename: 'item', fieldList: new FieldList("[iconID|name|];")});
|
||||
equals(ds.items.length, 0);
|
||||
ds.add({iconID: 3, name: 'Test'});
|
||||
equals(ds.items.length, 1);
|
||||
equals(ds.items[0].iconID, 3);
|
||||
equals(ds.items[0].name, 'Test');
|
||||
});
|
||||
|
||||
test("Serialization of datastore", function() {
|
||||
var ds = new DataStore({objectTypename: 'item', fieldList: new FieldList("[iconID|name|];")});
|
||||
ds.add({iconID: 3, name: 'Test'});
|
||||
equals(ds.serialize(), '[iconID|name|];\n{3|Test|};\n');
|
||||
});
|
||||
|
||||
// ========================================================
|
||||
|
||||
module("TilesetImage");
|
||||
|
||||
test("Image bounds", function() {
|
||||
var img = new TilesetImage("defaultimage.png", { x:1, y:1 });
|
||||
equals(img._tileSize.x, 32);
|
||||
equals(img._tileSize.y, 32);
|
||||
|
||||
var c = img.localIDToCoords(0);
|
||||
equals(img.coordsToLocalID(c.x, c.y), 0);
|
||||
equals(c.x, 0);
|
||||
equals(c.y, 0);
|
||||
equals(img.coordsToLocalID(0, 0), 0);
|
||||
equals(img.coordsToLocalID(1, 1), 0);
|
||||
equals(img.coordsToLocalID(10, 10), 0);
|
||||
equals(img.coordsToLocalID(31, 31), 0);
|
||||
|
||||
img = new TilesetImage("defaultimage.png", { x:10, y:2 });
|
||||
c = img.localIDToCoords(0);
|
||||
equals(img.coordsToLocalID(c.x, c.y), 0);
|
||||
equals(c.x, 0);
|
||||
equals(c.y, 0);
|
||||
equals(img.coordsToLocalID(0, 0), 0);
|
||||
equals(img.coordsToLocalID(1, 1), 0);
|
||||
equals(img.coordsToLocalID(10, 10), 0);
|
||||
equals(img.coordsToLocalID(31, 31), 0);
|
||||
|
||||
c = img.localIDToCoords(1);
|
||||
equals(img.coordsToLocalID(c.x, c.y), 1);
|
||||
equals(c.x, 32);
|
||||
equals(c.y, 0);
|
||||
equals(img.coordsToLocalID(32, 0), 1);
|
||||
equals(img.coordsToLocalID(33, 1), 1);
|
||||
equals(img.coordsToLocalID(40, 10), 1);
|
||||
equals(img.coordsToLocalID(63, 31), 1);
|
||||
|
||||
c = img.localIDToCoords(10);
|
||||
equals(img.coordsToLocalID(c.x, c.y), 10);
|
||||
equals(c.x, 0);
|
||||
equals(c.y, 32);
|
||||
equals(img.coordsToLocalID(0, 32), 10);
|
||||
equals(img.coordsToLocalID(1, 33), 10);
|
||||
equals(img.coordsToLocalID(10, 40), 10);
|
||||
equals(img.coordsToLocalID(31, 63), 10);
|
||||
|
||||
c = img.localIDToCoords(12);
|
||||
equals(img.coordsToLocalID(c.x, c.y), 12);
|
||||
equals(c.x, 64);
|
||||
equals(c.y, 32);
|
||||
equals(img.coordsToLocalID(64, 32), 12);
|
||||
equals(img.coordsToLocalID(65, 33), 12);
|
||||
equals(img.coordsToLocalID(70, 40), 12);
|
||||
equals(img.coordsToLocalID(95, 63), 12);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Andor's Trail editor unit tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="qunit-fixture">test markup, will be hidden</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user