Index: binaries/data/mods/public/gui/session/session.xml
===================================================================
--- binaries/data/mods/public/gui/session/session.xml	(revision 10359)
+++ binaries/data/mods/public/gui/session/session.xml	(working copy)
@@ -535,7 +535,6 @@
 						<!-- Resource carrying icon/counter -->
 						<object size="0 40 48 88" type="image" name="resourceCarryingIcon" style="resourceIcon"/>
 						<object size="0 80 48 100" type="text" name="resourceCarryingText" style="statsText"/>
-
 					</object>
 
 					<!-- Big unit icon -->
@@ -690,6 +689,18 @@
 					</object>
 				</object>
 
+				<object name="unitTradingPanel"
+					size="14 12 100% 100%"
+				>
+					<object size="0 0 100% 100%">
+						<repeat count="4">
+							<object name="unitTradingButton[n]" style="iconButton" type="button" size="0 0 46 46" tooltip_style="sessionToolTipBottom">
+								<object name="unitTradingIcon[n]" type="image" ghost="true" size="3 3 43 43"/>
+							</object>
+						</repeat>
+					</object>
+				</object>
+
 				<object name="unitQueuePanel"
 					size="4 -56 100% 0"
 					type="image"
Index: binaries/data/mods/public/gui/session/selection_details.js
===================================================================
--- binaries/data/mods/public/gui/session/selection_details.js	(revision 10359)
+++ binaries/data/mods/public/gui/session/selection_details.js	(working copy)
@@ -135,6 +135,14 @@
 	//		getGUIObjectByName("resourceCarryingText").hidden = true;
 	//	}
 	}
+	// Use the same indicators for traders
+	else if (entState.trader && entState.trader.goods.amount > 0)
+	{
+		getGUIObjectByName("resourceCarryingIcon").hidden = false;
+		getGUIObjectByName("resourceCarryingText").hidden = false;
+		getGUIObjectByName("resourceCarryingIcon").cell_id = RESOURCE_ICON_CELL_IDS[entState.trader.goods.type];
+		getGUIObjectByName("resourceCarryingText").caption = entState.trader.goods.amount;
+	}
 	else
 	{
 		getGUIObjectByName("resourceCarryingIcon").hidden = true;
Index: binaries/data/mods/public/gui/session/utility_functions.js
===================================================================
--- binaries/data/mods/public/gui/session/utility_functions.js	(revision 10359)
+++ binaries/data/mods/public/gui/session/utility_functions.js	(working copy)
@@ -82,6 +82,17 @@
 			player.offline = true;
 }
 
+function hasClass(entState, className)
+{
+	if (entState.identity)
+	{
+		var classes = entState.identity.classes;
+		if (classes && classes.length)
+			return (classes.indexOf(className) != -1);
+	}
+	return false;
+}
+
 function isUnit(entState)
 {
 	if (entState.identity)
Index: binaries/data/mods/public/gui/session/input.js
===================================================================
--- binaries/data/mods/public/gui/session/input.js	(revision 10359)
+++ binaries/data/mods/public/gui/session/input.js	(working copy)
@@ -195,6 +195,12 @@
 				}
 			}
 			break;
+		case "setup-trade-route":
+			// If ground or sea trade possible
+			if ((entState.trader && hasClass(entState, "Organic") && (playerOwned || allyOwned) && hasClass(targetState, "Market")) ||
+				(entState.trader && hasClass(entState, "Ship") && (playerOwned || allyOwned) && hasClass(targetState, "SeaMarket")))
+				return {"possible": true};
+			break;
 		case "gather":
 			if (targetState.resourceSupply && (playerOwned || gaiaOwned))
 			{
@@ -218,6 +224,7 @@
 		case "attack":
 			if (entState.attack && targetState.hitpoints && enemyOwned)
 				return {"possible": true};
+			break;
 		}
 	}
 	if (action == "move")
@@ -302,7 +309,9 @@
 	else
 	{
 		var actionInfo = undefined;
-		if ((actionInfo = getActionInfo("gather", target)).possible)
+		if (getActionInfo("setup-trade-route", target).possible)
+			return {"type": "setup-trade-route", "cursor": "action-setup-trade-route", "target": target};
+		else if ((actionInfo = getActionInfo("gather", target)).possible)
 			return {"type": "gather", "cursor": actionInfo.cursor, "target": target};
 		else if ((actionInfo = getActionInfo("returnresource", target)).possible)
 			return {"type": "returnresource", "cursor": actionInfo.cursor, "target": target};
@@ -880,7 +889,6 @@
 				updateBuildingPlacementPreview();
 				break;
 			}
-
 			break;
 
 		}
@@ -926,6 +934,10 @@
 		Engine.GuiInterfaceCall("PlaySound", { "name": "order_gather", "entity": selection[0] });
 		return true;
 
+	case "setup-trade-route":
+		Engine.PostNetworkCommand({"type": "setup-trade-route", "entities": selection, "target": action.target});
+		return true;
+
 	case "garrison":
 		Engine.PostNetworkCommand({"type": "garrison", "entities": selection, "target": action.target, "queued": queued});
 		// TODO: Play a sound?
@@ -1008,6 +1020,13 @@
 	inputState = INPUT_BUILDING_PLACEMENT;
 }
 
+// Called by GUI when user changes preferred trading goods
+function selectTradingPreferredGoods(data)
+{
+	warn(data.trader + " " + data.preferredGoods);
+	Engine.PostNetworkCommand({"type": "select-trading-goods", "trader": data.trader, "preferredGoods": data.preferredGoods });
+}
+
 // Batch training:
 // When the user shift-clicks, we set these variables and switch to INPUT_BATCHTRAINING
 // When the user releases shift, or clicks on a different training button, we create the batched units
Index: binaries/data/mods/public/gui/session/unit_commands.js
===================================================================
--- binaries/data/mods/public/gui/session/unit_commands.js	(revision 10359)
+++ binaries/data/mods/public/gui/session/unit_commands.js	(working copy)
@@ -13,11 +13,14 @@
 const UNIT_PANEL_BASE = -52; // QUEUE: The offset above the main panel (will often be negative)
 const UNIT_PANEL_HEIGHT = 44; // QUEUE: The height needed for a row of buttons
 
+// Trading constants
+const TRADING_RESOURCES = ["food", "wood", "stone", "metal"];
+
 // The number of currently visible buttons (used to optimise showing/hiding)
-var g_unitPanelButtons = {"Selection": 0, "Queue": 0, "Formation": 0, "Garrison": 0, "Training": 0, "Construction": 0, "Command": 0, "Stance": 0};
+var g_unitPanelButtons = {"Selection": 0, "Queue": 0, "Formation": 0, "Garrison": 0, "Training": 0, "Trading": 0, "Construction": 0, "Command": 0, "Stance": 0};
 
 // Unit panels are panels with row(s) of buttons
-var g_unitPanels = ["Selection", "Queue", "Formation", "Garrison", "Training", "Construction", "Research", "Stance", "Command"];
+var g_unitPanels = ["Selection", "Queue", "Formation", "Garrison", "Training", "Trading", "Construction", "Research", "Stance", "Command"];
 
 // Lay out a row of centered buttons (does not work inside a loop like the other function)
 function layoutButtonRowCentered(rowNumber, guiName, startIndex, endIndex, width)
@@ -112,6 +115,14 @@
 function setupUnitPanel(guiName, usedPanels, unitEntState, items, callback)
 {
 	usedPanels[guiName] = 1;
+
+	// Use separate logic for trading panel
+	if (guiName == "Trading")
+	{
+		setupUnitTradingPanel(unitEntState);
+		return;
+	}
+
 	var numberOfItems = items.length;
 	var selection = g_Selection.toList();
 	var garrisonGroups = new EntityGroups();
@@ -354,6 +365,25 @@
 	g_unitPanelButtons[guiName] = numButtons;
 }
 
+// Sets up "unit trading panel" - special case for setupUnitPanel
+function setupUnitTradingPanel(unitEntState)
+{
+	for (var i = 0; i < TRADING_RESOURCES.length; i++)
+	{
+		var resource = TRADING_RESOURCES[i];
+		var button = getGUIObjectByName("unitTradingButton["+i+"]");
+		button.size = (i * 46) + " 0 " + ((i + 1) * 46) + " 46";
+		var selectTradingPreferredGoodsData = { "trader": unitEntState.id, "preferredGoods": resource };
+		button.onpress = (function(e){ return function() { selectTradingPreferredGoods(e); } })(selectTradingPreferredGoodsData);
+		button.enabled = true;
+		button.tooltip = "Set " + resource + " as trading goods";
+		var icon = getGUIObjectByName("unitTradingIcon["+i+"]");
+		var preferredGoods = unitEntState.trader.preferredGoods;
+		var imageNameSuffix = (resource == preferredGoods) ? "selected" : "inactive";
+		icon.sprite = "stretched:session/resources/" + resource + "_" + imageNameSuffix + ".png";
+	}
+}
+
 // Updates right Unit Commands Panel - runs in the main session loop via updateSelectionDetails()
 function updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection)
 {
@@ -427,6 +457,11 @@
 			setupUnitPanel("Queue", usedPanels, entState, entState.training.queue,
 				function (item) { removeFromTrainingQueue(entState.id, item.id); } );
 
+		if (entState.trader)
+		{
+			setupUnitPanel("Trading", usedPanels, entState, [], null);
+		}
+
 //		supplementalDetailsPanel.hidden = false;
 //		commandsPanel.hidden = isInvisible;
 	}
Index: binaries/data/mods/public/simulation/helpers/Commands.js
===================================================================
--- binaries/data/mods/public/simulation/helpers/Commands.js	(revision 10359)
+++ binaries/data/mods/public/simulation/helpers/Commands.js	(working copy)
@@ -323,6 +323,20 @@
 		}
 		break;
 
+	case "setup-trade-route":
+		for each (var ent in cmd.entities)
+		{
+			var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
+			if (cmpUnitAI)
+				cmpUnitAI.SetupTradeRoute(cmd.target);
+		}
+		break;
+
+	case "select-trading-goods":
+		var cmpTrader = Engine.QueryInterface(cmd.trader, IID_Trader);
+		cmpTrader.SetPreferredGoods(cmd.preferredGoods);
+		break;
+
 	default:
 		error("Ignoring unrecognised command type '" + cmd.type + "'");
 	}
Index: binaries/data/mods/public/simulation/components/GuiInterface.js
===================================================================
--- binaries/data/mods/public/simulation/components/GuiInterface.js	(revision 10359)
+++ binaries/data/mods/public/simulation/components/GuiInterface.js	(working copy)
@@ -179,6 +179,15 @@
 		};
 	}
 
+	var cmpTrader = Engine.QueryInterface(ent, IID_Trader);
+	if (cmpTrader)
+	{
+		ret.trader = {
+			"goods": cmpTrader.GetGoods(),
+			"preferredGoods": cmpTrader.GetPreferredGoods()
+		};
+	}
+
 	var cmpFoundation = Engine.QueryInterface(ent, IID_Foundation);
 	if (cmpFoundation)
 	{
Index: binaries/data/mods/public/simulation/components/interfaces/Trader.js
===================================================================
--- binaries/data/mods/public/simulation/components/interfaces/Trader.js	(revision 0)
+++ binaries/data/mods/public/simulation/components/interfaces/Trader.js	(revision 0)
@@ -0,0 +1 @@
+Engine.RegisterInterface("Trader");
Index: binaries/data/mods/public/simulation/components/Identity.js
===================================================================
--- binaries/data/mods/public/simulation/components/Identity.js	(revision 10359)
+++ binaries/data/mods/public/simulation/components/Identity.js	(working copy)
@@ -89,6 +89,8 @@
 						"<value>Worker</value>" +
 						"<value>CitizenSoldier</value>" +
 						"<value>Trade</value>" +
+						"<value>Market</value>" +
+						"<value>SeaMarket</value>" +
 						"<value>Warship</value>" +
 						"<value>SeaCreature</value>" +
 						"<value>ForestPlant</value>" +
Index: binaries/data/mods/public/simulation/components/UnitAI.js
===================================================================
--- binaries/data/mods/public/simulation/components/UnitAI.js	(revision 10359)
+++ binaries/data/mods/public/simulation/components/UnitAI.js	(working copy)
@@ -334,7 +334,15 @@
 			return;
 		}
 	},
-	
+
+	"Order.Trade": function(msg) {
+		if (this.MoveToMarket(this.order.data.firstMarket))
+		{
+			// We've started walking to the first market
+			this.SetNextState("INDIVIDUAL.TRADE.APPROACHINGFIRSTMARKET");
+		}
+	},
+
 	"Order.Repair": function(msg) {
 		// Try to move within range
 		if (this.MoveToTargetRange(this.order.data.target, IID_Builder))
@@ -1007,6 +1015,39 @@
 			},
 		},
 
+		"TRADE": {
+			"APPROACHINGFIRSTMARKET": {
+				"enter": function () {
+					this.SelectAnimation("move");
+				},
+
+				"MoveCompleted": function() {
+					this.PerformTrade();
+					if (this.MoveToMarket(this.order.data.secondMarket))
+					{
+						// We've started walking to the second market
+						this.SetNextState("INDIVIDUAL.TRADE.APPROACHINGSECONDMARKET");
+					}
+				},
+			},
+
+			"APPROACHINGSECONDMARKET": {
+				"enter": function () {
+					this.SelectAnimation("move");
+				},
+
+				"MoveCompleted": function() {
+					this.order.data.firstPass = false;
+					this.PerformTrade();
+					if (this.MoveToMarket(this.order.data.firstMarket))
+					{
+						// We've started walking to the first market
+						this.SetNextState("INDIVIDUAL.TRADE.APPROACHINGFIRSTMARKET");
+					}
+				},
+			},
+		},
+
 		"REPAIR": {
 			"APPROACHING": {
 				"enter": function () {
@@ -2313,6 +2354,45 @@
 	this.AddOrder("ReturnResource", { "target": target }, queued);
 };
 
+UnitAI.prototype.SetupTradeRoute = function(target, queued)
+{
+	if (!this.CanTrade(target))
+	{
+		this.WalkToTarget(target, queued);
+		return;
+	}
+
+	var cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
+	var secondMarketChanged = cmpTrader.SetTargetMarket(target);
+	if (secondMarketChanged)
+	{
+		this.AddOrder("Trade", { "firstMarket": cmpTrader.GetFirstMarket(), "secondMarket": cmpTrader.GetSecondMarket() }, queued);
+	}
+}
+
+UnitAI.prototype.MoveToMarket = function(targetMarket)
+{
+	if (this.MoveToTarget(targetMarket))
+	{
+		// We've started walking to the first market
+		return true;
+	}
+	else
+	{
+		// We can't reach the frist market.
+		// Give up.
+		this.StopMoving();
+		this.FinishOrder();
+		return false;
+	}
+}
+
+UnitAI.prototype.PerformTrade = function()
+{
+	var cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
+	cmpTrader.PerformTrade();
+}
+
 UnitAI.prototype.Repair = function(target, autocontinue, queued)
 {
 	if (!this.CanRepair(target))
@@ -2505,6 +2585,21 @@
 	return true;
 };
 
+UnitAI.prototype.CanTrade = function(target)
+{
+	// Formation controllers should always respond to commands
+	// (then the individual units can make up their own minds)
+	if (this.IsFormationController())
+		return true;
+
+	// Verify that we're able to respond to Trade commands
+	var cmpTrader = Engine.QueryInterface(this.entity, IID_Trader);
+	if (!cmpTrader)
+		return false;
+
+	return true;
+}
+
 UnitAI.prototype.CanRepair = function(target)
 {
 	// Formation controllers should always respond to commands
Index: binaries/data/mods/public/simulation/components/Trader.js
===================================================================
--- binaries/data/mods/public/simulation/components/Trader.js	(revision 0)
+++ binaries/data/mods/public/simulation/components/Trader.js	(revision 0)
@@ -0,0 +1,142 @@
+// This constant used to adjust gain value depending on distance
+const DISTANCE_FACTOR = 1 / 50;
+
+// Additional gain for trading perfromed between markets of different players, in percents
+const INTERNATIONAL_TRADING_ADDITION = 50;
+// Additional gain for ships for each garrisoned trader, in percents
+const GARRISONED_TRADER_ADDITION = 20;
+
+function Trader() {}
+
+Trader.prototype.Schema =
+	"<a:help>Lets the unit generate resouces while moving between markets (or docks in case of water trading).</a:help>" +
+	"<empty/>";
+
+Trader.prototype.Init = function()
+{
+	this.firstMarket = null;
+	this.secondMarket = null;
+	// Gain from one pass between markets
+	this.gain = null;
+	// Selected resource for trading
+	this.preferredGoods = "metal";
+	// Currently carried goods
+	this.goods = { "type": null, "amount": 0 };
+}
+
+Trader.prototype.CalculateGain = function()
+{
+	var cmpFirstMarketPosition = Engine.QueryInterface(this.firstMarket, IID_Position);
+	var cmpSecondMarketPosition = Engine.QueryInterface(this.secondMarket, IID_Position);
+	var firstMarketPosition = cmpFirstMarketPosition.GetPosition2D();
+	var secondMarketPosition = cmpSecondMarketPosition.GetPosition2D();
+	// Calculate ordinary Euclidean distance between markets.
+	// We don't use pathfinder, because ordinary distance looks more fair.
+	var distance = Math.sqrt(Math.pow(firstMarketPosition.x - secondMarketPosition.x, 2) + Math.pow(firstMarketPosition.y - secondMarketPosition.y, 2));
+	// We calculate gain as square of distance to encourage trading between remote markets
+	this.gain = Math.round(Math.pow(distance * DISTANCE_FACTOR, 2));
+	// If markets belongs to different players, multiple gain to INTERNATIONAL_TRADING_MULTIPLIER
+	var cmpFirstMarketOwnership = Engine.QueryInterface(this.firstMarket, IID_Ownership);
+	var cmpSecondMarketOwnership = Engine.QueryInterface(this.secondMarket, IID_Ownership);
+	if (cmpFirstMarketOwnership.GetOwner() != cmpSecondMarketOwnership.GetOwner())
+		this.gain *= (100 + INTERNATIONAL_TRADING_ADDITION) / 100;
+	// For ship increase gain for each garrisoned trader
+	var cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity);
+	if (cmpIdentity.HasClass("Ship"))
+	{
+		warn("Ship");
+		var cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder);
+		if (cmpGarrisonHolder)
+		{
+			warn("Garrison holder");
+			var garrisonedTradersCount = 0;
+			for each (var entity in cmpGarrisonHolder.GetEntities())
+			{
+				var cmpGarrisonedUnitTrader = Engine.QueryInterface(entity, IID_Trader);
+				if (cmpGarrisonedUnitTrader)
+					garrisonedTradersCount++;
+			}
+			warn("Garrisoned traders count: " + garrisonedTradersCount);
+			this.gain *= (100 + GARRISONED_TRADER_ADDITION * garrisonedTradersCount) / 100;
+		}
+	}
+	this.gain = Math.round(this.gain);
+	warn("gain: " + this.gain);
+}
+
+// Set target as last of target markets.
+// Return true if both markets defined and second market was changed,
+// i.e. we should start trading.
+Trader.prototype.SetTargetMarket = function(target)
+{
+	if (this.secondMarket)
+	{
+		if (target != this.secondMarket)
+		{
+			this.firstMarket = this.secondMarket;
+			this.secondMarket = target;
+		}
+		else
+		{
+			return false;
+		}
+	}
+	else if (this.firstMarket)
+	{
+		if (target != this.firstMarket)
+		{
+			this.secondMarket = target;
+		}
+		else
+		{
+			return false;
+		}
+	}
+	else
+	{
+		this.firstMarket = target;
+		return false;
+	}
+	this.CalculateGain();
+	// Drop carried goods
+	this.goods.amount = 0;
+	return true;
+}
+
+Trader.prototype.GetFirstMarket = function()
+{
+	return this.firstMarket;
+}
+
+Trader.prototype.GetSecondMarket = function()
+{
+	return this.secondMarket;
+}
+
+Trader.prototype.GetPreferredGoods = function()
+{
+	return this.preferredGoods;
+}
+
+Trader.prototype.SetPreferredGoods = function(preferredGoods)
+{
+	this.preferredGoods = preferredGoods;
+}
+
+Trader.prototype.PerformTrade = function()
+{
+	if (this.goods.amount > 0)
+	{
+		var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
+		cmpPlayer.AddResource(this.goods.type, this.goods.amount);
+	}
+	this.goods.type = this.preferredGoods;
+	this.goods.amount = this.gain;
+}
+
+Trader.prototype.GetGoods = function()
+{
+	return this.goods;
+}
+
+Engine.RegisterComponentType(IID_Trader, "Trader", Trader);
Index: binaries/data/mods/public/simulation/templates/template_unit_support_trader.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit_support_trader.xml	(revision 10359)
+++ binaries/data/mods/public/simulation/templates/template_unit_support_trader.xml	(working copy)
@@ -18,8 +18,8 @@
     <GenericName>Trader</GenericName>
     <Rollover>Trade was a very important part of ancient civilisation - effective trading and control of trade routes equaled wealth. Trade took place by many forms from foot to caravans to merchant ships. One of the most notorious examples of the power of trade was the Silk Road.</Rollover>
     <Tooltip>Trades resources between allied Markets.</Tooltip>
-	<Classes datatype="tokens">Trade</Classes>
   </Identity>
+  <Trader/>
   <UnitMotion>
     <WalkSpeed>7.0</WalkSpeed>
   </UnitMotion>
Index: binaries/data/mods/public/simulation/templates/template_structure_economic_market.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_economic_market.xml	(revision 10359)
+++ binaries/data/mods/public/simulation/templates/template_structure_economic_market.xml	(working copy)
@@ -24,7 +24,7 @@
   <Identity>
     <GenericName>Market</GenericName>
     <Tooltip>Create Trade units and Barter resources. (Currently a useless structure)</Tooltip>
-    <Classes datatype="tokens">Town</Classes>
+    <Classes datatype="tokens">Town Market</Classes>
     <Icon>structures/market.png</Icon>
   </Identity>
   <Obstruction>
Index: binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_merchant.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_merchant.xml	(revision 10359)
+++ binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_merchant.xml	(working copy)
@@ -38,6 +38,7 @@
     <BarHeight>0.5</BarHeight>
     <HeightOffset>6.0</HeightOffset>
   </StatusBars>
+  <Trader/>
   <UnitMotion>
     <WalkSpeed>10.5</WalkSpeed>
   </UnitMotion>
Index: binaries/data/mods/public/simulation/templates/template_structure_military_dock.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure_military_dock.xml	(revision 10359)
+++ binaries/data/mods/public/simulation/templates/template_structure_military_dock.xml	(working copy)
@@ -27,7 +27,7 @@
   <Identity>
     <GenericName>Dock</GenericName>
     <Tooltip>Build upon a shoreline to construct naval vessels and to open sea trade.</Tooltip>
-    <Classes datatype="tokens">Town</Classes>
+    <Classes datatype="tokens">Town Market SeaMarket</Classes>
     <Icon>structures/dock.png</Icon>
   </Identity>
   <Obstruction>
Index: binaries/data/mods/public/art/textures/cursors/action-setup-trade-route.txt
===================================================================
--- binaries/data/mods/public/art/textures/cursors/action-setup-trade-route.txt	(revision 0)
+++ binaries/data/mods/public/art/textures/cursors/action-setup-trade-route.txt	(revision 0)
@@ -0,0 +1 @@
+1 1
Index: binaries/data/mods/public/art/textures/cursors/action-setup-trade-route.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: binaries/data/mods/public/art/textures/cursors/action-setup-trade-route.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: binaries/data/mods/public/art/textures/ui/session/resources/food_selected.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/food_selected.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: binaries/data/mods/public/art/textures/ui/session/resources/wood_selected.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/wood_selected.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: binaries/data/mods/public/art/textures/ui/session/resources/stone_selected.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/stone_selected.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: binaries/data/mods/public/art/textures/ui/session/resources/metal_inactive.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/metal_inactive.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: binaries/data/mods/public/art/textures/ui/session/resources/food_inactive.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/food_inactive.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: binaries/data/mods/public/art/textures/ui/session/resources/wood_inactive.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/wood_inactive.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: binaries/data/mods/public/art/textures/ui/session/resources/stone_inactive.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/stone_inactive.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: binaries/data/mods/public/art/textures/ui/session/resources/metal_selected.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: binaries/data/mods/public/art/textures/ui/session/resources/metal_selected.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

