--To create the Air Tasking Order
--Initiated by Main_NextMission.lua
------------------------------------------------------------------------------------------------------- 
-- last modification:  cleancode_d adjustment_Ab M11A_bk Debug_t
if not versionDCE then versionDCE = {} end
versionDCE["ATO_Generator.lua"] = "1.20.134"
------------------------------------------------------------------------------------------------------- 
-- cleancode_d				(d springCleaning)
-- adjustment_Ab			(b target priority (again))(low Red flight)(score & sort)(a country table)(z target priority)(y nb of Cap & Firepower)(v: depreciated variable capability)(u score & strikeOnlyWithEscorte)(minscore)(s tasks table)(op ne donne pas tout en CAP)(o info loadout)(N ne donne pas tout en CAP)(lM: MP) (ghi:donne une alti aléatoire) (f:altitude en fonction diff entre role)(e: random loadout temp)(cd:support équitable entre escadron)(b: TASK Coef)(a: escort mandatory or not)
-- Debug_t					(t boost priority in MP)(s no Choice Plane MP with SEAD)(r priority again)(q sort C broken)(p multipack broken)(o #Draft_sorties)(n db_loadouts)(m strikeOnlyWithEscorte)(l AltitudeFloorNew)(k too tanker&Awacs)(jk number entre 0 et1)(i info2000)(h:reecriture loadout_eligible) (f:interdit l'escorte avion/helico)(de:correction targetName)(c: mauvaise insertion dans la base)(b: haut score)(a: Fin de campagne)
-- modification M68_a		add AFAC task
-- modification M61_a		SAR
-- modification M56_b		AssignCallnameSquad (b: callsignId)
-- modification M53_b		automatic update of the conf_mod file (b conf_mod reconfiguration)
-- modification M49_c		big central db_loadout (c: loadout statistics)
-- modification M43			assignation des numeros de parking du type C08 
-- modification M42			liveryModex
-- modification M38_t		Check and Help CampaignMaker (t debug/debugGenerator)(r +)(o _affiche) (e: loadout Task?)
-- modification M16_b		SpawnAir B1b & B-52 need BaseAirStart = true in db_aibase
-- modification M13_e		Performance Scripting
-- modification M11A_bk		Multiplayer	(bk tente d obtenir ce que l'on souahite)(bj same target)(bi bug CAP)(bb: rapport entre escorte et cap)(wxy: force same package)(z: debug MP avec 1 Plane)(y: interdit l'escorte avion/helico) (x: EscorteTot-max) (w: choix EscorteMax) (v: interdit Strike sans escorte)(u: reserve avion Escorte) (t: different Type possible/task)
-- modification M06			helicopter playable
------------------------------------------------------------------------------------------------------- 	


DebugAssignAll = false
AltiHelicoMap = {}
AltitudeFloorNew = {}
PlayerSquad = {}
DebugRoute = false


--to track what caused lack of playable sortie for the player
Playability_criterium = {}
function TrackPlayability(player_unit, criterium)																				--function that tracks whether a playability criterium has been met
	if player_unit == true then																									--unit in question is playable by player
		Playability_criterium[criterium] = true																					--set playability criterium to be met
	end
end

--table to hold availability of aircraft
if not camp.Aircraft_availability and not camp.aircraft_availability then
	camp.Aircraft_availability = {}
elseif  camp.aircraft_availability then
	camp.Aircraft_availability = Deepcopy(camp.aircraft_availability)
	camp.aircraft_availability = nil
end
AcftAvail = camp.Aircraft_availability																				--link to table for easier reference

local debuGenTxt = ""
local debugLogs = {}

local denom_NeDonnePasTOUT = 1.5 --1.3		--nb, coef, dénominateur pour ne pas donner tous les chasseurs à l'escorte, en garder pour les intercepteur/cap
--plus le chiffre est petit, moins il y a de CAP et intercepteur
-- if AcftAvail[draft.name].unassigned - test_Aircraftnumber <= AcftAvail[draft.name].serviceable/denom_NeDonnePasTOUT then

local multipackByTargetName = {}

local bias = 4 -- Pondération pour target.firepower : plus grand = plus proche de `min

--calcul le nb d'avion en tout
local checkNbPlane = {
	blue = {
		beforMission = {
			ready = 0,
			reserve = 0,
			alreadyInFlight = 0,
		},
		thisMission = {
			used = 0,
			reserve = 0
		}
	},
	red = {
		beforMission = {
			ready = 0,
			reserve = 0,
			alreadyInFlight = 0,
		},
		thisMission = {
			used = 0,
			reserve = 0
		}
	},
}

local priorityRef = {
	blue =0,
	red = 0,
}
local newDraftByPriority = {
	blue = {},
	red = {},
}

--creation du targetlist par ordre de priorité
local targetListPrio = {
	blue = {},
	red = {},
}
local targetListPrioCheck = {
	blue = {},
	red = {},
}
local targetNamePrio = {
	blue = {},
	red = {},
}

if Debug.debug and oob_air then

	for side, units in pairs(oob_air) do
		for unitN, unit in pairs(units) do
			if not unit.inactive or unit.inactive == nil then
				if not unit.roster then
					checkNbPlane[side]["beforMission"].ready = checkNbPlane[side]["beforMission"].ready + unit.number
					checkNbPlane[side]["beforMission"].reserve = checkNbPlane[side]["beforMission"].reserve + unit.reserve
				else
					if unit.roster.ready then
						checkNbPlane[side]["beforMission"].ready = checkNbPlane[side]["beforMission"].ready + unit.roster.ready
					else
						print("AtoG strange, no roster.ready on this unit ")
						_affiche(unit, "unit")
						if Debug.debug then os.execute 'pause'
						end
					end

					if unit.roster.reserve then
						checkNbPlane[side]["beforMission"].reserve = checkNbPlane[side]["beforMission"].reserve + unit.roster.reserve
					-- else
					-- 	print("AtoG strange, no roster.reserve on this unit ")
					-- 	_affiche(unit, "unit")
					end


				end
			end
		end
	end

	if camp.Aircraft_availability then
		for squadName, squad in pairs(camp.Aircraft_availability) do
			if squad then
				if squad.unavailable then
					local squadSide = FoundSquadSide(squadName)
					if squadSide then

						checkNbPlane[squadSide]["beforMission"].alreadyInFlight = checkNbPlane[squadSide]["beforMission"].alreadyInFlight + #squad.unavailable
					else
						print("AtoG strange, squad.unavailable on this squad ")
						_affiche(squad, "squad")
						if Debug.debug then os.execute 'pause'
						end

					end
				end
			end
		end

	end
end

--crer une table identique, en enlevant les infos des layers 
for mapName, layers in pairs(AltitudeFloor) do
	if string.lower(mapName) == string.lower(mission.theatre) then
		for alti, layer in pairs(layers) do

			if not AltitudeFloorNew then AltitudeFloorNew = {} end
			if not AltitudeFloorNew[alti] then AltitudeFloorNew[alti] = {} end

			--structure relevant des dessins de ligne de l editeur de mission
			if layer[1].mapY then
				for PolyN = 1, #layer do

					local tempAlti = {}

					for pointN, point in ipairs(layer[PolyN].points) do
						tempAlti[pointN] = {
							x = point.x + layer[PolyN].mapX,
							y = point.y + layer[PolyN].mapY,
						}

					end
					table.insert(AltitudeFloorNew[alti], tempAlti)
				end
			--structure épuré, issue d un plan de vol, avec un seul polygone
			else
				AltitudeFloorNew[alti] = layer
			end
		end
	end
end


local totalPlanePerTask = {
	red = {},
	blue = {},
	neutral = {},
}

require("Active/Loadouts_archive")
local error = 0
-- oob_air = oob_air or {} -- Assurez que c'est une table, même après un reset
for side, units in pairs(oob_air) do
-- db_loadouts = {
	-- ["AV8BNA"] = {
		-- ["Anti-ship Strike"] = {

	for unitN, unit in pairs(units) do
		if not unit.inactive then
			if type(unit.tasks) == "table" then
				for task, task_bool in pairs(unit.tasks) do
					if task_bool and task ~= "Spotter" then

						local foundTaskAndCountry = false

						if db_loadouts[unit.type] and db_loadouts[unit.type] ~= nil then

							if db_loadouts[unit.type][task] and db_loadouts[unit.type][task] ~= nil then

								for loadout_name, ltable in pairs(db_loadouts[unit.type][task]) do
									if ltable and type(ltable) == "table" then

										local countryEligible = false
										if ltable.country == nil  then
											countryEligible = true
											foundTaskAndCountry = true
										elseif type(ltable.country) == "string" then
											if string.lower(ltable.country) == string.lower(unit.country) or string.lower(ltable.country) == "all" then
												countryEligible = true
												foundTaskAndCountry = true
											end

										elseif type(ltable.country) == "table" then
											for n, countryLabel in pairs(ltable.country) do
												if string.lower(countryLabel) == string.lower(unit.country) or string.lower(countryLabel) == "all" then
													countryEligible = true
													foundTaskAndCountry = true
													break
												end
											end
										end


										if countryEligible then
											--creation table du nombre d'avion dispo pour une task
											if unit.roster and unit.roster.ready then
												if not totalPlanePerTask[side][task] then totalPlanePerTask[side][task] = 0 end
												totalPlanePerTask[side][task] = totalPlanePerTask[side][task] +	unit.roster.ready
											end
										end
									else
										-- print("AtoG error_A unit.type: |"..unit.type.."| not found in db_loadouts")
										print("AtoG error_A: no task |"..tostring(task).."| in the loadout for this unit:? "..tostring(unit.type).."|")
										error = error + 1
									end
								end

							elseif task ~= "Spotter" then

								print("AtoG error_B: no task |"..tostring(task).."| in the loadout for this unit:? "..tostring(unit.type).."|")
								error = error + 1
							end

						else
							print("AtoG error_C: |"..unit.type.."| not found in db_loadouts. A problem with the campaigns_code_loadout code? |"..tostring(campConfMod.code_loadout).."|")
							error = error + 1
						end

						if not foundTaskAndCountry then
							print("AtoG error_D: |"..unit.type.."| |"..task.."| not found in db_loadouts for this country: |"..tostring(unit.country).."|")
							error = error + 1
						end
					end
				end
			end
		end
	end
end

if error >= 1 and error < 5 then os.execute 'pause'
end


if error >= 5 then
	if string.lower(campMod.selectLoadout) == "init" then

	else
		print()
		print("================================================ATTENTION====================================================")
		print("AtoG error: ".." With so many errors using the Central loadout, there may be a custom loadout in the /Init folder \n "
		.."To do this, set the \"selectLoadout\" variable to \"init\" in the conf_mod") os.execute 'pause'
	end
end

local function mysort(s)
    -- convert hash to array
    local t = {}
    for k, v in pairs(s) do
        table.insert(t, v)
    end

    -- sort
    table.sort(t, function(a, b)
        if a.players ~= b.players then
            return a.priorityIni > b.priorityIni
        end

        return a.score > b.score
    end)
    return t
end

local function table_move(src, start, stop, dest, tbl)
    tbl = tbl or src
    local offset = dest - start
    if offset > 0 then -- Décalage vers l'avant
        for i = stop, start, -1 do
            tbl[i + offset] = src[i]
        end
    else -- Décalage vers l'arrière
        for i = start, stop do
            tbl[i + offset] = src[i]
        end
    end
    return tbl
end


local function round(num)
local dec = 2
  local mult = 10^(dec or 0)
  return math.floor(num * mult + 0.5) / mult
end


local function debugLog(message)
    table.insert(debugLogs, message)
end


--status report counters
local status_counter_sorties = 0
local status_counter_escorts = 0
local status_counter_ATO = 0



--table to store draft sorties (all valid unit/task/loadout/target combinations)
Draft_sorties = {
	blue = {},
	red = {}
}


local multiPlaneSet = {}

for k=1, Multi.NbGroup do
	--TODO beurk, à refaire ça propre
	if not multiPlaneSet[Multi.Group[k].side] then multiPlaneSet[Multi.Group[k].side] = {} end
	if not multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType] then multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType] = {} end
	-- multiPlaneSet[Multi.Group[k].PlaneType][Multi.Group[k].task] = true

	if not multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType][Multi.Group[k].task] then multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType][Multi.Group[k].task] = {} end
	if not multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType][Multi.Group[k].task]["NbPlane"] then multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType][Multi.Group[k].task]["NbPlane"] = 0 end

	multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType][Multi.Group[k].task].NbPlane = Multi.Group[k].NbPlane + multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType][Multi.Group[k].task].NbPlane
	multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType][Multi.Group[k].task].InitNbPlaneByTask =  multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType][Multi.Group[k].task].NbPlane

	if not multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType].InitNbPlane then multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType].InitNbPlane = 0 end
			multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType].InitNbPlane = multiPlaneSet[Multi.Group[k].side][Multi.Group[k].PlaneType].InitNbPlane + Multi.Group[k].NbPlane
end


if Debug.debug and Debug.Generator.affiche then
	_affiche(Multi, "ATO_G_A Multi")
	_affiche(multiPlaneSet, "ATO_G_B multiPlaneSet B")
end

if Debug.debug then
	for side, units in pairs(oob_air) do
		if units and units ~= nil then
			for unitN, unit in pairs(units) do
				if unit.player then
					if Debug.debug then
						print("ATO_G_C playable "..unit.type.." ready "..unit.roster.ready)
					end
				end
			end
		end
	end

	for side, units in pairs(oob_air) do
		if units and units ~= nil then
			for unitN, unit in pairs(units) do
				if unit.player then
					if Debug.debug then
						print("ATO_G_D TOUS "..unit.type.." ready "..unit.roster.ready)
					end
				end
			end
		end
	end
end

if Multi and Multi.Group then
	for kGroupN, multiGroup in pairs(Multi.Group) do
		for side, units in pairs(oob_air) do
			if units and units ~= nil then
				for unitN, unit in pairs(units) do
					if not unit.inactive and unit.type == multiGroup.PlaneType and side == multiGroup.side and unit.roster.ready < multiGroup.NbPlane   then
						unit.roster.ready = multiGroup.NbPlane * 2
						if Debug.debug then
							print("ATO_G_E set Nplane "..unit.type.." ready "..unit.roster.ready)
						end
					end
				end
			end
		end
	end

	--augmente la priority de la cible choisie
	for kGroupN, multiGroup in pairs(Multi.Group) do
		for targetN, target in pairs(targetlist[multiGroup.side]) do
			if not target.inactive and not target.priorityINIT and Multi.Target and target.titleName == Multi.Target[multiGroup.side] then
				target.priorityINIT = target.priority
				target.priority = target.priority * 4
				if Debug.debug then print("ATO_G_F multiGroup target.priority "..target.priority.." titleName "..target.titleName) end
				break
			end
		end
	end


end

table.sort(targetlist["blue"], function(a,b) return a.priority > b.priority  end)
table.sort(targetlist["red"], function(a,b) return a.priority > b.priority  end)


--creat draft sorties
for side, units in pairs(oob_air) do
	--determine enemy side
	local enemy																													--determine enemy side (opposite of unit side)
	if side == "blue" then
		enemy = "red"
	else
		enemy = "blue"
	end
	local draftId = 1
	if Debug.Generator.affiche then
		debugLog(draftId.." AtoG passe A_0 chapter: "..Debug.Generator.chapter.." SpySquad:  "..Debug.Generator.SpySquad.." SpyTask: "..Debug.Generator.SpyTask)

		if Debug.Generator.SpyTarget then
			debugLog(draftId.." \n\n"..Debug.Generator.SpyTarget)
		end
	end

	if units then

		for unitN, unit in pairs(units) do
			local overRideMP_A = false

			if unit.inactive and unit.player then
				print("AtoG attention, the player's squad is inactive. Activate it via DCE_Manager or directly in Init\\oob_air and Active\\oob_air ") os.execute 'pause'
			end

			if not unit.inactive then
				
				local clientPlayer = false

				local isDebugModeA = Debug.Generator.affiche and string.find(Debug.Generator.chapter, "A")
					and (Debug.Generator.SpySquad and Debug.Generator.SpySquad == unit.name )

				if isDebugModeA then
					debugLog(draftId.." AtoG passe A_00 "..unit.type.." Befor Airbase Condition ")
				end

				TrackPlayability(unit.player, "active_unit")																		--track playabilty criterium has been met

				if db_airbases[unit.base] and db_airbases[unit.base].inactive ~= true and db_airbases[unit.base].x and db_airbases[unit.base].y then	--base exists and is active and has a position value (carrier that exists)
					
					if isDebugModeA then
						debugLog(draftId.." AtoG passe A_01 "..unit.type.." Befor roster.ready Condition  ")
					end

					TrackPlayability(unit.player, "base")																		--track playabilty criterium has been met


					local overRideReady = false
					if multiPlaneSet and  multiPlaneSet[side] and  multiPlaneSet[side][unit.type] then
						if unit.roster.ready < multiPlaneSet[side][unit.type].InitNbPlane then
							unit.roster.ready = multiPlaneSet[side][unit.type].InitNbPlane + 1
							if isDebugModeA then
								debugLog(draftId.." AtoG 1_A multiPlaneSetPass  ")
							end
						end
						overRideReady = true
					end

					if Multi.NbGroup == 0 then
						clientPlayer = unit.player
					end

					if unit.player then
						PlayerSquad = unit
					end
					-- if overRideReady or unit.roster.ready > 0 then																				--has ready aircraft
					-- if unit.roster.ready > 0 then

						if isDebugModeA then
							debugLog(draftId.." AtoG passe A_02 "..unit.type.." Befor aircraft_available Condition ")
						end

						if Multi and Multi.Group and Debug.debug then
							for k=1, #Multi.Group do
								if Multi.Group[k].PlaneType == unit.type then
									-- print("AtoG type: "..unit.type.." rosterReady: "..unit.roster.ready)
									if isDebugModeA then
										debugLog(draftId.." AtoG type: "..unit.type.." rosterReady: "..unit.roster.ready)
									end
								end
							end
						end

						TrackPlayability(unit.player, "ready_aircraft")															--track playabilty criterium has been met

						if AcftAvail[unit.name] == nil then															--unit has no aircraft availability entry yet
							AcftAvail[unit.name] = {}																--make an aircraft availability entry for this unit
						end

						if AcftAvail[unit.name].unavailable == nil then												--unit has no unavailable table yet
							if unit.unavailable then																--there are preset unavailabilities in oob_air
								AcftAvail[unit.name].unavailable = unit.unavailable									--use this as initial unavailability
							else
								AcftAvail[unit.name].unavailable = {}												--create an empty unavailable table
							end
						end


						--serviceable aircraft
						local aircraft_serviceable = 0																				--serviceable aircraft of unit
						local serviceability = 0.8																					--defaults unit serviceability rating
						if unit.serviceability then																				--if serviceability for unit is defined
							serviceability = unit.serviceability																	--use it instead
						end

						if multiPlaneSet and multiPlaneSet[side] and multiPlaneSet[side][unit.type]   then
							aircraft_serviceable = unit.roster.ready
						else
							for s = 1, unit.roster.ready do																				--iterate through ready aircraft
								if math.random(1, 100) <= serviceability * 100 then														--default 80% chance that it is mission ready
									aircraft_serviceable = aircraft_serviceable + 1														--sum serviceable aircraft
								end
							end
						end

						AcftAvail[unit.name].ready = unit.roster.ready												--store ready aircraft un availability table
						AcftAvail[unit.name].serviceable = aircraft_serviceable										--store serviceable aircraft in availability table

						if DebugAssignAll then
							print("AtoGen&PA CampTotalTimeS "..tostring(CampTotalTimeS).." CampTotalTimeS en H "..CampTotalTimeS / 3600)
						end
						--unavailable aircraft
						local u_entry = 0

						for u = #AcftAvail[unit.name].unavailable, 1, -1 do											--iterate backwards through unavailable aircraft from this unit
							u_entry = u_entry + 1

							if DebugAssignAll then print("AtoGen AcftAvail  "..unit.type.." || "..unit.name) end

							-- if AcftAvail[unit.name].unavailable[u] > ((CampTotalTimeS / 3600)*2)   then
							if AcftAvail[unit.name].unavailable[u] > ((CampTotalTimeS / 3600))   then
								AcftAvail[unit.name].unavailable[u] = 0
							end

							-- print("AtoGen AcftAvail ____***______ "..tostring(CampTotalTimeS / 3600).." >=? UnitUnavailable?? "..tostring(AcftAvail[unit.name].unavailable[u]))
							if (CampTotalTimeS / 3600) >= AcftAvail[unit.name].unavailable[u] then
								table.remove(AcftAvail[unit.name].unavailable, u)								--remove this entry
								if DebugAssignAll then  print("AtoGen AcftAvail     ____***______ REMOVE ") end
							end
						end

						local aircraft_available = unit.roster.ready - #AcftAvail[unit.name].unavailable			--number of available aircraft

						if aircraft_serviceable < aircraft_available then
							aircraft_available = aircraft_serviceable
						end

						AcftAvail[unit.name].available = aircraft_available											--store available aircraft in availability table
						AcftAvail[unit.name].assigned = 0
						AcftAvail[unit.name].unassigned = aircraft_available										--store unassigned aircraft in availability table

						-- _affiche(AcftAvail[unit.name], "AcftAvail "..unit.name..": ")

						if aircraft_available > 0 then																				--unit has available aircraft
							if isDebugModeA then
								debugLog(draftId.." AtoG passe A_03 ".." Befor tasks Boucle ")
							end

							TrackPlayability(unit.player, "available_aircraft")													--track playabilty criterium has been met


							for task,task_bool in pairs(unit.tasks) do																		--iterate through all tasks of unit		
								if task_bool and task ~= "SEAD" and task ~= "Escort" and task ~= "Escort Jammer" and task ~= "Flare Illumination" and task ~= "Laser Illumination" then		--task is true and is no support task

									isDebugModeA = Debug.Generator.affiche and string.find(Debug.Generator.chapter, "A")
												and (Debug.Generator.SpySquad and Debug.Generator.SpySquad == unit.name  and  Debug.Generator.SpyTask == task)

									if isDebugModeA then
										debugLog(draftId.." AtoG passe A_04b "..unit.type.." Befor task Condition | task: "..task)
									end

									--get possible loadouts
									local unit_loadouts = {}																					--table to hold all loadouts for this aircraft type and task

									if db_loadouts[unit.type] and db_loadouts[unit.type][task] then																		--db_loadouts table has loadouts for this task

										for loadout_name, ltable in pairs(db_loadouts[unit.type][task]) do									--iterate through all loadouts for the aircraft type and task

											local countryEligible = false
											if ltable.country == nil  then
												countryEligible = true
											elseif type(ltable.country) == "string" then
												if string.lower(ltable.country) == string.lower(unit.country) or string.lower(ltable.country) == "all" then
													countryEligible = true
												end

											elseif type(ltable.country) == "table" then
												for n, countryLabel in pairs(ltable.country) do
													if string.lower(countryLabel) == string.lower(unit.country) or string.lower(countryLabel) == "all" then
														countryEligible = true
														break
													end
												end
											end

											-- if ltable.country == nil or ltable.country == unit.country then									--loadout is country unspecific or applies to unit country
											if countryEligible then
												ltable.name = loadout_name																		--store loadout name
												-- table.insert(unit_loadouts, ltable)																--add loadout to local table

												ltable["hCruiseREF"] = ltable.hCruise
												ltable["hAttackREF"] = ltable.hAttack

												--ceci est un anti PBO_Corse66 ^^
												-- donne une alti aléatoire pour éviter de connaitre le type d'avion pas l'altitude habituellement utilisée
												if ltable.hCruise and ltable.hCruise > 2000 then
													local altiRandom = 0
													local RandomChance = math.random(0,100)

													if RandomChance < 50 then										--20% de chance d'avoir une alti de 1000 à 2000m de difference 
														altiRandom = math.random(100 ,200)

													elseif RandomChance < 70 then									--30% de chance d'avoir une alti de 1000m de difference
														altiRandom = math.random(0,100)
													end																--50% de chance d'avoir une alti de 0 de difference

													altiRandom = altiRandom *10 * (math.random(0, 1)*2-1)			--choisi si c'est une diff positive ou negative												
													ltable.hCruise = ltable.hCruise + altiRandom
													if ltable.hCruise < 300 then
														ltable.hCruise = 300
													end


													if ltable.hAttack then
														ltable.hAttack = ltable.hAttack + (altiRandom /2)
														if ltable.hAttack < 300 then
															ltable.hAttack = 300
														end
													end
												end


												--ajoute une task obligatoire en fonction du learning des missions précédentes
												if camp.newTaskRequest then
													for rSide, rSides in pairs(camp.newTaskRequest) do
														if rSide == side then
															for rTypeName, rTypes in pairs(rSides) do
																if rTypeName == unit.type then
																	for rTaskEnCours, rNewTasks in pairs(rTypes) do
																		if rTaskEnCours == task then
																			for rNewTask, value in pairs(rNewTasks) do
																				if value then
																					if not ltable.support then ltable.support = {} end
																					ltable.support[rNewTask] = true
																				end
																			end
																		end
																	end
																end
															end
														end
													end
												end


												unit_loadouts[#unit_loadouts+1] = ltable
												unit_loadouts[#unit_loadouts]["loadout_name"] = loadout_name
											end
										end
									end


									--mix the list of available loadouts so that you don't always have the same ones 
									--https://programming-idioms.org/idiom/10/shuffle-a-list/1313/lua
									for i = #unit_loadouts, 2, -1 do
										local j = math.random(i)
										unit_loadouts[i], unit_loadouts[j] = unit_loadouts[j], unit_loadouts[i]
									end

									for l = 1, #unit_loadouts do																				--iterate through all available loadouts				
										if isDebugModeA then
											debugLog(draftId.." AtoG passe A_05 "..unit.type.." "..unit_loadouts[l].loadout_name.." Befor Loadouts Day/Night Condition")
										end

										if unit_loadouts[l].day == nil then
											unit_loadouts[l].day = true
										end

										--get possible Time on Target
										local tot_from = 0																						--earliest Time on Target for this loadout
										local tot_to = 0																						--latest Time on target for this loadout

										if unit_loadouts[l].day and unit_loadouts[l].night then													--loadout is day and night capable
											tot_from = 0																						--from mission start
											tot_to = mission_ini.mission_duration																		--to mission end
											if task == "Intercept" or task == "SAR" then																			--for interceptors, tot_to is not limitted by mission duration
												tot_to = 999999
											end
										elseif unit_loadouts[l].day then																		--loadout is day capable
											if Daytime == "night-day" then
												tot_from = mission_ini.dawn - camp.time																--from dawn
												tot_to = mission_ini.mission_duration																	--to mission end
												if task == "Intercept" or task == "SAR" then																		--for interceptors, tot_to is not limitted by mission duration
													tot_to = mission_ini.dusk - camp.time
												end
											elseif Daytime == "day" then
												tot_from = 0																					--from missiom start
												tot_to = mission_ini.mission_duration																	--to mission end
												if task == "Intercept" or task == "SAR" then																		--for interceptors, tot_to is not limitted by mission duration
													tot_to = mission_ini.dusk - camp.time
												end
											elseif Daytime == "day-night" then
												tot_from = 0																					--from mission start
												tot_to = mission_ini.dusk - camp.time																	--to dusk
											end
										elseif unit_loadouts[l].night then																		--loadout is night capable
											if Daytime == "day-night" then
												tot_from = mission_ini.dusk - camp.time																--from dusk
												tot_to = mission_ini.mission_duration																	--to mission end
												if task == "Intercept" or task == "SAR" then																		--for interceptors, tot_to is not limitted by mission duration
													tot_to = mission_ini.dawn - camp.time
												end
											elseif Daytime == "night" then
												tot_from = 0																					--from mission start
												tot_to = mission_ini.mission_duration																	--to mission end
												if task == "Intercept"  or task == "SAR" then																		--for interceptors, tot_to is not limitted by mission duration
													tot_to = mission_ini.dawn - camp.time
												end
											elseif Daytime == "night-day" then
												tot_from = 0																					--from mission start
												tot_to = mission_ini.dawn - camp.time																	--to dawn
											end
										end


										if tot_to < 0 then
											tot_to = tot_to + 86400
										end
										if tot_from < 0 then
											tot_from = tot_from + 86400
										end

										if tot_to ~= 0 then
											-- if tot_from ~= 0 or tot_to ~= 0 then																	--loadout has an eligible time on target
											if isDebugModeA then
												debugLog(draftId.." AtoG passe A_06 ".." Befor targetlist Boucle")
											end

											if tot_from == 0 then																				--player is only allowed to start at mission start
												TrackPlayability(unit.player, "tot")															--track playabilty criterium has been met
											end

											local i_timmer01 = 0
											for target_side_name, target_side in pairs(targetlist) do											--iterate through sides in targetlist				
												i_timmer01 = i_timmer01 +1
												if side == target_side_name then																--if the target is hostile
													local totalTarget = 0
													for target_name, target in pairs(target_side) do
														totalTarget = totalTarget + 1
													end

													local iTarget = 0
													for targetN, target in pairs(target_side) do											--iterate through all hostile targets
														iTarget = iTarget + 1

														local target_name = target.titleName

														if not target.inactive and target.ATO then											--if target is active and should be added to ATO
															isDebugModeA = Debug.Generator.affiche and string.find(Debug.Generator.chapter, "A")
																and (Debug.Generator.SpySquad and Debug.Generator.SpySquad == unit.name and Debug.Generator.SpyTask == task
																or (Debug.Generator.SpyTarget and Debug.Generator.SpyTarget == target.titleName ))

															if isDebugModeA then
																debugLog(draftId.."  AtoG passe A_07c :"..unit.type.." "..target.titleName.." Befor task Condition: "..target.task .." ==? task? "..task.." || "..target_name)
															end

															if target.task == task then															--if target is valid for aircaft-loadout															

																--ajoute la task au loadout du main pour que cette task/support devienne obligatoire

																if camp.newTaskPerTarget then
																	for tableTargetName, targetTask in pairs(camp.newTaskPerTarget) do
																		if tableTargetName == target_name and targetTask.tasks then
																			for task_, value in pairs(targetTask.tasks) do
																				if not unit_loadouts[l].support then unit_loadouts[l].support = {} end
																				unit_loadouts[l].support[task_] = true
																			end
																		end
																	end
																end


																--check target/loadout attributes
																local loadout_eligible = true																					--boolean if loadout matches any target attributes (default true, because target might have no attributes)
																if target.attributes and target.attributes[1] and target.attributes[1] ~= "" then																					--target has attributes
																	loadout_eligible = false
																	for target_attribute_number, target_attribute in ipairs(target.attributes) do								--Iterate through target attributes																
																		for loadout_attribute_number, loadout_attribute in ipairs(unit_loadouts[l].attributes) do				--Iterate through loadout attributes												

																			if isDebugModeA then
																				debugLog(draftId.."  AtoG passe A_10b Befor loadout_eligible: target_attribute?: "..tostring(target_attribute).."  || loadout_attribute: "..tostring(loadout_attribute).." || "..target_name.." || "..tostring(unit_loadouts[l].name) )
																			end

																			if target_attribute == loadout_attribute then														--if match is found													
																				loadout_eligible = true																			--set variable true
																				break																							--break the loadout attributes iteration
																			end
																		end
																	end
																end


																if target.attributes and target.attributes[1] and target.attributes[1] ~= "" then
																	for tgt_attributeN, target_attribute in ipairs(target.attributes) do
																		if target_attribute == "Helicopter" and IsHelicopter[unit.type] then

																			if #target.attributes == 1 then
																				loadout_eligible = true
																				break
																			end
																		elseif target_attribute == "Helicopter" and not IsHelicopter[unit.type] then

																			loadout_eligible = false
																			break

																		elseif target_attribute == "Plane" and not IsHelicopter[unit.type] then

																			if #target.attributes == 1 then
																				loadout_eligible = true
																				break
																			end
																		elseif target_attribute == "Plane" and IsHelicopter[unit.type] then

																			loadout_eligible = false
																			break

																		end
																	end
																end

																if isDebugModeA then
																	debugLog(draftId.." AtoG passe A_10c Befor Condition loadout_eligible?: "..tostring(loadout_eligible).." |unit.name: "..unit.name.." |target_name: "..target_name.." |target.base: "..tostring(target.base).." |unit.base: "..unit.base)
																end

																if loadout_eligible then
																--continue if loadout is eligible

																	if ( target.base
																		and  ((task == "Intercept" and target.base == unit.base) or (task == "SAR" and target.base == unit.base) ) or (task == "Transport" and target.base == unit.base) or (task == "Nothing" and target.base == unit.base)
																		)
																		or (task ~= "Intercept" and task ~= "Transport" and task ~= "Nothing" and task ~= "SAR") then	--intercept and transport missions are only assigned to units of a certain base as per targetlist	

																		TrackPlayability(unit.player, "target")																							--track playabilty criterium has been met

																		if isDebugModeA then
																			debugLog(draftId.." AtoG passe A_11 overRideMP_A? "..tostring(overRideMP_A).." Befor firepower Condition".." || "..target_name
																			.." "..unit.type
																			.." firepower.min? "..target.firepower.min
																			.." <= aircraft_available: ".. aircraft_available
																			.." * firepower "..unit_loadouts[l].firepower
																			)
																		end

																		if target.firepower.min <= aircraft_available * unit_loadouts[l].firepower or overRideMP_A then				--enough aircraft are available to satisfy minimum firepower requirement of target	

																			if isDebugModeA then
																				debugLog(draftId.." AtoG passe A_12  Befor weather Condition || overRideReady: "..tostring(overRideReady).." || "..target_name)
																			end

																			TrackPlayability(unit.player, "target_firepower")																			--track playabilty criterium has been met

																			--check weather
																			local weather_eligible = true
																			if mission.weather["clouds"]["density"] > 8 then																				--overcast clouds

																				if isDebugModeA then
																					debugLog(draftId.." AtoG passe A_13a "..unit_loadouts[l].loadout_name.." After weather Condition "..target_name)
																				end

																				local cloud_base = mission.weather["clouds"]["base"]
																				local cloud_top = mission.weather["clouds"]["base"] + mission.weather["clouds"]["thickness"]
																				if db_airbases[unit.base].elevation + 333 > cloud_base then																--cloud base is less than 1000 ft above airbase elevation
																					if unit_loadouts[l].adverseWeather == false then																		--loadout is not adverse weather capable
																						weather_eligible = false																							--not eligible for this weather
																					end
																				else
																					if unit_loadouts[l].hCruise and unit_loadouts[l].hCruise > cloud_base and unit_loadouts[l].hCruise < cloud_top then			--cruise alt is in the clouds
																						if unit_loadouts[l].adverseWeather == false then																	--loadout is not adverse weather capable
																							weather_eligible = false																						--not eligible for this weather
																						end
																					elseif unit_loadouts[l].hAttack and unit_loadouts[l].hAttack > cloud_base and unit_loadouts[l].hAttack < cloud_top then		--attack alt is in the clouds
																						if unit_loadouts[l].adverseWeather == false then																	--loadout is not adverse weather capable
																							weather_eligible = false																						--not eligible for this weather
																						end
																					end

																					if task == "Strike" or task == "Anti-ship Strike" or task == "Reconnaissance" then										--extra requirement for A-G tasks
																						if unit_loadouts[l].hAttack > cloud_base then																		--attack alt is above cloud base
																							if unit_loadouts[l].adverseWeather == false then																--loadout is not adverse weather capable
																								weather_eligible = false																					--not eligible for this weather
																							end
																						end
																					end
																				end
																			end
																			if mission.weather["enable_fog"] == true then															--fog
																				if db_airbases[unit.base].elevation < mission.weather["fog"]["thickness"] then					--base elevation in fog
																					if mission.weather["fog"]["visibility"] < 5000 then												--less than 5000m visibility
																						if unit_loadouts[l].adverseWeather == false then											--loadout is not adverse weather capable
																							weather_eligible = false																--not eligible for this weather
																						end
																					end
																				end
																			end

																			--selectionne une escadrille CSAR la plus proche de l'EjectedPilot
																			local proxiCSAR = true
																			if task == "CSAR" and target.selectedUnitSAR ~= "" then
																				if unit.name ~= target.selectedUnitSAR then
																					proxiCSAR = false

																					if isDebugModeA then
																						debugLog(draftId.." AtoG passe A_13b ".." proxiCSAR "..tostring(proxiCSAR).." ".. unit.name.." selectedUnitSAR: "..target.selectedUnitSAR)
																					end
																				end
																			end



																			if (weather_eligible and proxiCSAR) or overRideReady then																				--continue of this loadout is eligible for weather

																				if isDebugModeA then
																					debugLog(draftId.." AtoG passe A_14 ".." After weather_eligible Condition "..target_name)
																				end

																				TrackPlayability(unit.player, "weather")															--track playabilty criterium has been met

																				--get airbase position
																				local airbasePoint = {																				--get the x-y coordinates of the airbase where the unit is located
																					x = db_airbases[unit.base].x,
																					y = db_airbases[unit.base].y,
																					h = db_airbases[unit.base].elevation,
																					BaseAirStart = db_airbases[unit.base].BaseAirStart
																				}

																				local multipack = 1
																				if target.firepower.packmax  then	--and unit_loadouts[l].MaxAttackOffset								--target has a requirement for multiple packages and loadout is multipack capable (defined maximum attack offset)
																					multipack = target.firepower.packmax															--create draft sorties for this target for the requested amount of packages
																				end

																				for r = 1, multipack do																				--repeat draft sortie generation for the requirement amount of packages (may create different routes each time)

																					if isDebugModeA then
																						debugLog(draftId.." AtoG passe A_15 multipack "..tostring(multipack).." FOR multipack Boucle "..target_name)
																					end

																					--determine route variants depending on Daytime
																					local variant
																					if Daytime == "day" then
																						variant = 1
																					elseif Daytime == "night" then
																						variant = 2
																					elseif Daytime == "night-day" then
																						variant = 3
																					elseif Daytime == "day-night" then
																						variant = 4
																					end

																					if isDebugModeA then
																						debugLog(draftId.." AtoG passe A_16 "..tostring(variant).." "..tostring(Daytime).." Befor variant Condition "..target_name)
																					end

																					while variant > 0 do
																						draftId = draftId + 1

																						if isDebugModeA then
																							debugLog(draftId.." AtoG passe A_18 ".." After variant Condition "..target_name)
																						end

																						local tempDebug = ""

																						i_timmer01 = i_timmer01 +1
																						if i_timmer01 >= 10  then io.write(".") i_timmer01 = 0 end
																						--determine route
																						status_counter_sorties = status_counter_sorties + 1													--status report

																						local route = {}

																						if task == "Intercept" then																			--intercept task only get a stub route
																							route = {
																								[1] = {
																									['y'] = airbasePoint.y,
																									['x'] = airbasePoint.x,
																									['alt'] = 0,
																									['id'] = 'Intercept',
																								},
																								threats = {
																									SEAD_offset = 0,
																									ground_total = 0.5,
																									air_total = 0.5
																								},
																								['lenght'] = target.radius * 2,																--interception task radius *2 because below it is compared with range *2
																							}
																						elseif task == "SAR" then																			--intercept task only get a stub route
																							route = {
																								[1] = {
																									['y'] = airbasePoint.y,
																									['x'] = airbasePoint.x,
																									['alt'] = 0,
																									['id'] = 'SAR',
																								},
																								threats = {
																									SEAD_offset = 0,
																									ground_total = 0.5,
																									air_total = 0.5
																								},
																								['lenght'] = target.radius * 2,																--interception task radius *2 because below it is compared with range *2
																							}
																						else																								--all other tasks than intercept
																							local toTarget = 9999999
																							if not airbasePoint.x then print("AtoG No Airbase position "..tostring(unit.base)) os.execute 'pause' end
																							if not target.x then
																								-- print("AtoG No target position "..tostring(target_name))
																							else
																								toTarget = GetDistance(airbasePoint, target)												--direct distance to target
																							end


																							if isDebugModeA then
																								debugLog(draftId.." AtoG A_25 "..tostring(toTarget).." || LoadoutUnitRange: "..tostring(unit_loadouts[l].range).." "..tostring(unit_loadouts[l].name)
																								.."\n".."______________toTarget "..tostring(toTarget).." <=? "..tostring(unit_loadouts[l].range)
																								.."\n".."______________minrange? "..tostring(unit_loadouts[l].minrange)
																								.."\n".."______________toTarget * 1.5 "..tostring(toTarget * 1.5).." >minrange? "..tostring(unit_loadouts[l].minrange))
																							end

																							tempDebug = "\n"..("AtoG A_26                    AtoG toTarget "..tostring(toTarget).." <=?? unit_loadouts[l].range: "..tostring(unit_loadouts[l].range) )
																							if toTarget <= unit_loadouts[l].range and (unit_loadouts[l].minrange == nil or toTarget * 1.5 > unit_loadouts[l].minrange) then	--basic feasibility check of range before performance intensive route calculations are done
																								tempDebug = tempDebug.."\n"..("                    AtoG variant" )
																								if variant == 1 or variant == 4 then
																									-- print("                    AtoG _1_4_route" )
																									tempDebug = tempDebug.."\n"..("AtoG  A_27a day")
																									route = GetRoute(airbasePoint, target, unit_loadouts[l], enemy, task, "day", r, multipack, unit, draftId)	or {}		--get the best route to this target at day-- modification M06 : helicopter playable(ajout variable helico pour generer une route )
																									-- print("                    AtoG      route_1_4_" )
																								elseif variant == 2 or variant == 3 then
																									-- print("                    AtoG _2_3_route" )
																									tempDebug = tempDebug.."\n"..("AtoG  A_27b night")
																									route = GetRoute(airbasePoint, target, unit_loadouts[l], enemy, task, "night", r, multipack, unit)	or {}	--get the best route to this target at night-- modification M06 : helicopter playable
																									-- print("                    AtoG      route_2_3_" )
																								end
																							end

																							DebugRoute = false
																						end

																						local altiPass = true
																						if 	unit_loadouts[l].hHover and target.z and target.z > unit_loadouts[l].hHover 	then
																							altiPass = false
																						end

																						if isDebugModeA then
																							debugLog(tempDebug..draftId.."\n".."AtoG passe A_28d "
																							.."\n".."______________route.lenght "..tostring(route.lenght).." <=? "..tostring(unit_loadouts[l].range * 2)
																							.."\n".."______________minrange? "..tostring(unit_loadouts[l].minrange)
																							.."\n".."______________route.lenght "..tostring(route.lenght).." >? "..tostring(unit_loadouts[l].minrange).." *2"
																							.."\n".."______________altiPass? "..tostring(altiPass)
																							.."\n".."______________altiPass? target.z "..tostring(target.z).." >? hHover "..tostring(unit_loadouts[l].hHover))
																						end

																						if route and route.lenght and route.lenght <= unit_loadouts[l].range * 2 and (unit_loadouts[l].minrange == nil or route.lenght > unit_loadouts[l].minrange * 2) and altiPass then		--if sortie route lenght is within range of aircraft-loadout

																							if isDebugModeA then
																								debugLog(draftId.." AtoG passe A_29 After Range Condition | firepower.max: "..tostring(target.firepower.max).." / loadoutFirepower "..tostring(unit_loadouts[l].firepower))
																							end

																							TrackPlayability(unit.player, "target_range")												--track playabilty criterium has been met

																							--determine number of aircraft needed for sortie
																							-- local aircraft_requested = target.firepower.max / unit_loadouts[l].firepower
																							-- local aircraft_requested = target.firepower.min / unit_loadouts[l].firepower					--how many aircraft are needed to satisfy the maximum firepower requirement of the target

																							-- print("min: "..tostring(target.firepower.min) .. " "..tostring(target.firepower.max))

																							local firepowerRequest = GetWeightedRandom(target.firepower.min, target.firepower.max, bias)
																							-- print(string.format("Valeur générée : %.2f", aircraft_requested))

																							local aircraft_requested = firepowerRequest / unit_loadouts[l].firepower

																							if task == "Transport" then
																								if multiPlaneSet and multiPlaneSet[side] and multiPlaneSet[side][unit.type]  and multiPlaneSet[side][unit.type][task]
																								and task_bool
																								and aircraft_requested < multiPlaneSet[side][unit.type][task].NbPlane
																								and task == "Transport"
																								then
																									aircraft_requested =  multiPlaneSet[side][unit.type][task].NbPlane
																									if aircraft_requested > 4 then aircraft_requested = 4 end
																								end
																							elseif task == "Strike" and aircraft_requested < 2 and aircraft_requested < 2  then
																								aircraft_requested = 2
																							end

																							local flights_requested
																							if  task == "AWACS" or task == "Refueling" or task == "AFAC" then									--multiple flights are required to continously cover a station for the duration of the mission
																								if not unit_loadouts[l].tStation then print("this variable <<tStation>> is missing  in this aircraft's "..task.." loadout "..unit.type) os.execute 'pause' end
																								flights_requested = math.ceil((tot_to - tot_from) / unit_loadouts[l].tStation) + 1			--how many flights are needed to keep continous coverage of station, plus 1 for on station before mission start
																								aircraft_requested = aircraft_requested * flights_requested									--total number of requested aircraft is number of aircraft needed to statisfy firepower requirement of station * number of flights needed for continous coverage
																							end
																							if task == "CAP"  then									--multiple flights are required to continously cover a station for the duration of the mission
																								if not unit_loadouts[l].tStation then print("this variable <<tStation>> is missing in this aircraft's "..task.." loadout "..unit.type) os.execute 'pause' end

																								local station = unit_loadouts[l].tStation * 0.75
																								flights_requested = math.ceil((tot_to - tot_from) / station)
																								aircraft_requested = aircraft_requested * flights_requested									--total number of requested aircraft is number of aircraft needed to statisfy firepower requirement of station * number of flights needed for continous coverage

																								if aircraft_requested < 2  then
																									aircraft_requested = 2
																								end

																							end

																							if task == "AWACS" or task == "Refueling" or task == "Transport" or task == "Nothing" or task == "Reconnaissance" or task == "AFAC" then
																								aircraft_requested = math.ceil(aircraft_requested)
																							-- elseif (unit.type == "S-3B" or unit.type == "F-117A" or unit.type == "B-1B" or unit.type == "B-52H" or unit.type == "Tu-22M3" or unit.type == "Tu-95MS" or unit.type == "Tu-142" or unit.type == "Tu-160" or unit.type == "MiG-25RBT")
																							-- 	and task ~= "Runway Attack"	then
																							-- 	aircraft_requested = math.ceil(aircraft_requested)	
																							elseif (Data_divers[unit.type] and Data_divers[unit.type].flyingAlone) and task ~= "Runway Attack"	then

																								aircraft_requested = math.ceil(aircraft_requested)
																							else
																								--aircraft_requested = math.ceil(aircraft_requested / 2) * 2								--round up to an even number
																								aircraft_requested = math.ceil(aircraft_requested)
																							end

																							local aircraft_assign
																							if aircraft_requested > aircraft_available then													--if more aircraft are requested than are available from this unit
																								aircraft_assign = math.floor(aircraft_available)														--assign all available aircraft
																							else																							--enough available aircraft to satisfy requested aircraft
																								aircraft_assign = math.floor(aircraft_requested)														--assign all requested aicraft
																							end

																							--garde en memoire remainingFirepower pour ajouter (ou non) un strike support
																							--
																							local remainingFirepower = target.firepower.max - ( unit_loadouts[l].firepower * aircraft_assign)
																							if remainingFirepower < 0 then remainingFirepower = 0 end

																							local debugMulti = ""
																							overRideMP_A = false


																							-- modification M11.o multiplayer
																							if multiPlaneSet then

																								debugMulti = debugMulti.."\n"..("AtoG passe A_AAb "..tostring(task).." "..unit.type.." aircraft_assign:"..tostring(aircraft_assign))

																								if multiPlaneSet[side] and multiPlaneSet[side][unit.type]  and multiPlaneSet[side][unit.type][task] and task_bool then
																									if Multi.Target and Multi.Target[side] then
																										debugMulti = debugMulti.."\n"..("AtoG passe A_AAe Multi.Target[side] "..tostring(Multi.Target[side]) .. " ==? target_name? " .. tostring(target_name))
																										if Multi.Target[side] == target_name  then
																											debugMulti = debugMulti.."\n"..("AtoG passe A_AAf Multi.Target[side] "..tostring(Multi.Target[side]) .. " ==? target_name? " .. tostring(target_name).." "..unit.type.." "..tostring(task))
																											overRideMP_A = true
																										end
																									else
																										debugMulti = debugMulti.."\n"..("AtoG passe A_AAg  " .. " ==? target_name? " .. tostring(target_name).." "..unit.type.." "..tostring(task))

																										Multi.Target = {}
																										Multi.Target[side] = target_name
																										overRideMP_A = true
																									end

																									--TODO a regarder si c'etait utile
																									if aircraft_assign > 4 and ( task == "CAP" ) then --or task == "Intercept"
																										aircraft_assign = 4
																									end

																									--M11.z
																									if overRideMP_A and aircraft_assign < multiPlaneSet[side][unit.type][task].NbPlane then
																										aircraft_assign = multiPlaneSet[side][unit.type][task].NbPlane
																										debugMulti = debugMulti.."\n"..("AtoG passe A_AAh "..unit.type.." aircraft_assign: "..tostring(aircraft_assign))
																									end
																									clientPlayer = true
																								end
																							end

																							if isDebugModeA then
																								debugLog(draftId.." "..debugMulti)
																							end


																							--self escort
																							if unit_loadouts[l].self_escort then															--if the loadout is capable of self-escort
																								route.threats.air_total = route.threats.air_total / 2										--reduce the fighter threat by half
																								if route.threats.air_total < 0.5 then
																									route.threats.air_total = 0.5
																								end
																							end

																							--build sortie entry
																							repeat																							--for tasks with station repeat to make entries for lesser amount of aircraft, repeat once for everything else
																								local idTemp = "id"..#Draft_sorties[side]+1

																								if isDebugModeA then
																									debugLog(draftId.." AtoG passe A_30a "..idTemp.." clientPlayer: "..tostring(clientPlayer) .. " overRideMP_A: "
																									.. tostring(overRideMP_A).." idTemp: "..tostring(idTemp).." aircraft_assign: "..tostring(aircraft_assign).." |Nb Draft "..tostring(#Draft_sorties[side]))
																								end

																								local draftSortiesEntry = {
																									name = unit.name,
																									playable = clientPlayer, 					--unit.player,
																									type = unit.type,
																									modification = unit.modification,
																									callsign = unit.callsign,
																									callsignId = unit.callsignId,
																									helicopter = unit.helicopter,
																									number = aircraft_assign,
																									flights = flights_requested,
																									country = unit.country,
																									livery = unit.livery,
																									sidenumber = unit.sidenumber,
																									liveryModex = unit.liveryModex,
																									base = unit.base,
																									airdromeId = db_airbases[unit.base].airdromeId,
																									parking_id = unit.parking_id,
																									skill = unit.skill,
																									task = task,
																									tasks = unit.tasks,
																									loadout = unit_loadouts[l],
																									target = Deepcopy(target),
																									target_name = target.titleName,
																									targetPriority = target.priority,
																									priorityIni = Deepcopy(target.priority),
																									route = route,
																									tot_from = tot_from,
																									tot_to = tot_to,
																									support = {
																										["Escort"] = {},
																										["SEAD"] = {},
																										["Escort Jammer"] = {},
																										["Flare Illumination"] = {},
																										["Laser Illumination"] = {},
																										["Strike"] = {},
																										},
																									multipack = multipack,
																									threatsGround = route.threats.ground_total,
																									threatsAir = route.threats.air_total,
																									id = "DraftId"..draftId.."_id"..#Draft_sorties[side]+1,
																									rejected = {},
																									mainOverRideMP = overRideMP_A,
																									remainingFirepower = remainingFirepower,
																									multiPlaneSet_B  = multiPlaneSet,

																								}


																								draftSortiesEntry.target.titleName =  target_name													-- ATO_G_Debug04 correction targetName

																								--score the sortie
																								draftSortiesEntry.scoreAdd = 0.000011
																								draftSortiesEntry.scoreCoef = 1

																								local route_threat = route.threats.ground_total + route.threats.air_total						--combine route ground and air threat
																								if task == "CAP" or task == "Intercept" or task == "SAR" then
																									draftSortiesEntry.score = target.priority	-- unit_loadouts[l].capability *				--route threat does not matter for CAP and intercept
																								else
																									draftSortiesEntry.score =  target.priority / route_threat	--unit_loadouts[l].capability *	--calculate the score to measure the importance of the sortie
																								end

																								-- if route.threats.SEAD_offset == 0 then
																								-- 	draftSortiesEntry.score = draftSortiesEntry.score + 4
																								-- end

																								if isDebugModeA then
																									debugLog(draftId.." AtoG passe A_30b: " .. idTemp.." score: "..tostring(draftSortiesEntry.score).." *T_priority "..tostring(target.priority).." /threat "..tostring(route_threat)
																									.." (ground_total "..route.threats.ground_total.." + air_total:"..route.threats.air_total.." )")
																								end

																								local reduce_score = 0																		--factor to reduce score for station missions with less aircraft than required to cover station
																								if task == "CAP" then																		--station tasks with flights of 2
																									-- reduce_score = flights_requested - aircraft_assign / math.ceil(target.firepower.max / unit_loadouts[l].firepower) --increase factor by one for each flight that is missing
																								elseif task == "AWACS" or task == "Refueling" or task == "AFAC"  then											--station tasks with flights of 1
																									reduce_score = flights_requested - aircraft_assign										--increase factor by one for each flight that is missing

																								end
																								draftSortiesEntry.score = draftSortiesEntry.score - reduce_score * 0.01					--reduce score slighthly for station missions with less aircraft than required to cover station
																								draftSortiesEntry.scoreAdd =  draftSortiesEntry.scoreAdd + reduce_score * 0.01

																								-- tasks = {
																								-- 	Strike = true,
																								-- 	SEAD = false,
																								-- 	["Anti-ship Strike"] = true,
																								-- 	["Runway Attack"] = true,
																								-- },--A 4 3
																								-- tasksCoef = {
																								-- 	Strike = 3,
																								-- 	SEAD = 1,
																								-- 	["Laser Illumination"] = 1,
																								-- 	Intercept = 1,
																								-- 	CAP = 0.2,
																								-- 	Escort = 0.5,
																								-- 	["Fighter Sweep"] = 0.2,
																								-- 	["Anti-ship Strike"] = 2,
																								-- 	["Runway Attack"] = 1,
																								-- },--A 4 3

																								--ATO_G_adjustment02
																								if unit.tasksCoef and unit.tasksCoef[task] then

																									local buildCoef = false
																									if unit.tasksCoefPourcent and not unit.tasksCoefPourcent[task] then
																										buildCoef = true
																									end

																									if not  unit.tasksCoefPourcent or buildCoef then


																										local minValue = 999999
																										local maxValue = -999999

																										for taskName, taskValue in pairs(unit.tasks) do
																											if taskValue and unit.tasksCoef[taskName] then
																												if minValue > unit.tasksCoef[taskName] then
																													minValue = unit.tasksCoef[taskName]
																												end
																												if maxValue < unit.tasksCoef[taskName] then
																													maxValue = unit.tasksCoef[taskName]
																												end
																											end
																										end

																										-- 3 -> 100
																										-- 0.1 -> 1
																										--
																										-- y = ax + b
																										--coef direc coefficient directeur = ( 1 − 100 ) / ( 0.3 − 3 )


																										-- print("AtoG task "..task)
																										-- _affiche(unit.tasks, "unit.tasks")
																										-- _affiche(unit.tasksCoef, "unit.tasksCoef")

																										local tasksCoefPourcent = 1
																										if minValue-maxValue ~= 0 then
																											-- print("AtoG minValue "..tostring(minValue).." maxValue "..tostring(maxValue))
																											local coefDir = (50-100) / (minValue-maxValue)

																											--k = 100 − 36.666666666667 × 3
																											local k = 100 - coefDir * maxValue
																											-- print("AtoG coefDir "..tostring(coefDir).." k "..tostring(k))

																											--y = 36.666666666667x − 10
																											tasksCoefPourcent = coefDir * unit.tasksCoef[task] + k

																										end

																										if not unit.tasksCoefPourcent then unit.tasksCoefPourcent = {} end
																										if not unit.tasksCoefPourcent[task] then unit.tasksCoefPourcent[task] = {} end
																										unit.tasksCoefPourcent[task] = tasksCoefPourcent

																										-- print("AtoG tasksCoefPourcent "..tostring(tasksCoefPourcent))
																									end

																									local randomCoef = math.random(1,100)

																									if unit.tasksCoefPourcent[task] <= randomCoef then
																										-- draftSortiesEntry.score idem
																									else
																										draftSortiesEntry.score = draftSortiesEntry.score * (unit.tasksCoefPourcent[task] / 100)
																										draftSortiesEntry.scoreCoef =  draftSortiesEntry.scoreCoef * (unit.tasksCoefPourcent[task] / 100)
																									end

																									-- draftSortiesEntry.score = draftSortiesEntry.score * unit.tasksCoef[task]	
																									-- draftSortiesEntry.scoreCoef =  draftSortiesEntry.scoreCoef * unit.tasksCoef[task]

																								end

																								if isDebugModeA then
																									debugLog(draftId.." AtoG passe A_30d: " ..idTemp.." score: ".. tostring(draftSortiesEntry.score).." "..unit.type.." "..tostring(task))
																								end

																								--augmente le score si l armement a une allonge, comme demandé par la cible
																								--target SA-2 45000
																								--loadoutStandoff 60000 JSAW
																								local debuGenTxtTemp = ""
																								if unit_loadouts[l].standoff and target.range and unit_loadouts[l].standoff > 0 and target.range >0 then
																									-- print("AtoG AA.score __"..draftSortiesEntry.score.."__ "..target.name)
																									-- print("AtoG 				AA1.range "..target.range.." standoff: "..unit_loadouts[l].standoff.." a/b "..tostring(target.range / unit_loadouts[l].standoff).." 1/: "..tostring(1/(target.range / unit_loadouts[l].standoff)))

																									debuGenTxtTemp = "\n".."AtoG AA.score __"..draftSortiesEntry.score.."__ "..target.name .."\n"
																									debuGenTxtTemp = debuGenTxtTemp .. "AtoG 				AA1 target.range "..target.range.." standoff: "..unit_loadouts[l].standoff.." a/b "..tostring(target.range / unit_loadouts[l].standoff).." 1/: "..tostring(1/(target.range / unit_loadouts[l].standoff)) .."\n"

																									local standOffCoef =  1/(target.range / unit_loadouts[l].standoff) * 10
																									if standOffCoef < 0.01 then
																										standOffCoef = 0.01
																									elseif standOffCoef > 100 then
																										standOffCoef = 100
																									end

																									draftSortiesEntry.score = draftSortiesEntry.score * standOffCoef
																									draftSortiesEntry.scoreCoef =  draftSortiesEntry.scoreCoef * standOffCoef
																									-- draftSortiesEntry.scoreAdd =  draftSortiesEntry.scoreAdd + 1000

																									-- print("AtoG BB.score__"..draftSortiesEntry.score.."__ "..unit_loadouts[l].name)
																									debuGenTxtTemp = debuGenTxtTemp .."AtoG BB.score__"..draftSortiesEntry.score.."__ "..unit_loadouts[l].name .."\n"
																								end

																								-- modification M11.q multiplayer

																								if multiPlaneSet[side] and  multiPlaneSet[side][unit.type] and  multiPlaneSet[side][unit.type][task] and task_bool and  multiPlaneSet[side][unit.type][task].NbPlane > 0 then
																									draftSortiesEntry.score = draftSortiesEntry.score + 1000
																									draftSortiesEntry.scoreAdd =  draftSortiesEntry.scoreAdd + 1000
																									if overRideMP_A then

																										-- draftSortiesEntry.score = draftSortiesEntry.score * 2 +1000
																										-- draftSortiesEntry.scoreCoef =  draftSortiesEntry.scoreCoef * 2
																										-- draftSortiesEntry.scoreAdd =  draftSortiesEntry.scoreAdd + 1000

																										draftSortiesEntry.score = draftSortiesEntry.score * 1.2 +1000
																										draftSortiesEntry.scoreCoef =  draftSortiesEntry.scoreCoef * 1.2
																										draftSortiesEntry.scoreAdd =  draftSortiesEntry.scoreAdd + 1000

																									end
																								-- elseif Multi.Target and Multi.Target[side] == target_name  then
																								-- 	draftSortiesEntry.score = draftSortiesEntry.score * 2
																								-- 	draftSortiesEntry.scoreCoef =  draftSortiesEntry.scoreCoef * 2
																								end

																								--augmente de 10% le score si l'avion peut etre joué
																								if unit.player then
																									draftSortiesEntry.score = draftSortiesEntry.score * 1.2
																									-- draftSortiesEntry.scoreAdd =  draftSortiesEntry.scoreAdd + 1000
																									draftSortiesEntry.scoreCoef =  draftSortiesEntry.scoreCoef * 1.2
																								end

																								if isDebugModeA then
																									debugLog(draftId.." "..debuGenTxtTemp.." AtoG passe A_30e: " ..idTemp.." score: ".. tostring(draftSortiesEntry.score).." "..unit.type.." "..tostring(task))
																								end

																								-- --insert sortie entry into Draft_sorties table sorted by score (highest first)
																								-- if #Draft_sorties[side] == 0 then															--if Draft_sorties table is empty
																								-- 	-- table.insert(Draft_sorties[side], draftSortiesEntry)
																								-- 	Draft_sorties[side][#Draft_sorties[side]+1] = draftSortiesEntry
																								-- else
																								-- 	for d = 1, #Draft_sorties[side] do														--iterate through Draft_sorties
																								-- 		if draftSortiesEntry.score > Draft_sorties[side][d].score then					--score is bigger than current table entry
																								-- 			-- table.insert(Draft_sorties[side], d, draftSortiesEntry)						--insert at current position in table
																								-- 			Draft_sorties[side][#Draft_sorties[side]+1] = draftSortiesEntry
																								-- 			break
																								-- 		elseif draftSortiesEntry.score == Draft_sorties[side][d].score then				--score is same as current table entry
																								-- 			local sum = 1
																								-- 			for s = d + 1, #Draft_sorties[side] do											--iterate through subsequent table entries
																								-- 				if draftSortiesEntry.score == Draft_sorties[side][s].score then			--if these entries also have the same score
																								-- 					sum = sum + 1															--sum them
																								-- 				else
																								-- 					break
																								-- 				end
																								-- 			end
																								-- 			table.insert(Draft_sorties[side], d + math.random(0, sum), draftSortiesEntry)	--insert random position position in table
																								-- 			-- Draft_sorties[side][d + math.random(0, sum)] = draftSortiesEntry
																								-- 			break
																								-- 		elseif d == #Draft_sorties[side] then												--if end of table is reached
																								-- 			-- draftSortiesEntry["id"] = "id"..#Draft_sorties[side]+1
																								-- 			Draft_sorties[side][#Draft_sorties[side]+1] = draftSortiesEntry
																								-- 		end
																								-- 	end
																								-- end



																								--/*/*/****/**/*/*/*/***/**/*/*/**/*/*/**/*/*/***/*/*/*/*/****/**/*/*/*/***/**/*/*/**/*/*/**/*/*/***/*/*
																								-- INSERT IN Draft_sorties
																								--/*/*/****/**/*/*/*/***/**/*/*/**/*/*/**/*/*/***/*/*/*/*/****/**/*/*/*/***/**/*/*/**/*/*/**/*/*/***/*/*
																								if not Draft_sorties[side] then
																									Draft_sorties[side] = {}
																								end
																								Draft_sorties[side][#Draft_sorties[side] + 1] = draftSortiesEntry

																								--/*/*/****/**/*/*/*/***/**/*/*/**/*/*/**/*/*/***/*/*/*/*/****/**/*/*/*/***/**/*/*/**/*/*/**/*/*/***/*/*
																								-- INSERT IN Draft_sorties
																								--/*/*/****/**/*/*/*/***/**/*/*/**/*/*/**/*/*/***/*/*/*/*/****/**/*/*/*/***/**/*/*/**/*/*/**/*/*/***/*/*



																								if task == "AWACS" or task == "Refueling" or task == "AFAC"  then--task == "CAP" or
																									aircraft_assign = aircraft_assign - 1													--make additional draft sortie for lesser amount of aircraft
																								elseif overRideMP_A then
																									aircraft_assign = aircraft_assign - 4
																								else
																									aircraft_assign = 0																		--do not make additional draft sorties
																								end

																								if isDebugModeA then
																									debugLog(draftId .." AtoG passe A_30_INIT : "..idTemp.." aircraft_assign "..aircraft_assign.." |Nb de draft: "..#Draft_sorties[side])
																								end

																							until aircraft_assign <= 0																		--stop making more draft sorties
																						end

																						variant = variant - 2																			--determines if while-loop does another route variant depending on Daytime
																					end
																				end
																			end
																		end
																	end
																end
															end
														end
													end
												end
											end
										end
									end
								end
							end
						end
					-- end
				end
			end
		end
	end
end

print("-")
print("ATO Generating Sortie (" .. status_counter_sorties .. ") - Complete")
debugLog("\n"..("ATO Generating Sortie (" .. status_counter_sorties .. ") - Complete"))

local shuffled = {}
for i, v in ipairs(oob_air["blue"]) do
	local pos = math.random(1, #shuffled+1)
	table.insert(shuffled, pos, v)
end
oob_air["blue"] = shuffled

shuffled = {}
for i, v in ipairs(oob_air["red"]) do
	local pos = math.random(1, #shuffled+1)
	table.insert(shuffled, pos, v)
end
oob_air["red"] = shuffled



-- Tri final par `targetPriority` (ascendant), puis par `score` (descendant)
for side, sorties in pairs(Draft_sorties) do
    table.sort(sorties, function(a, b)
        if a.targetPriority ~= b.targetPriority then
            return a.targetPriority > b.targetPriority -- Plus petite priorité d'abord
        end
        return a.score > b.score -- Plus grand score d'abord
    end)
end


if Debug.Generator.affiche then

	-- debuGenTxt = debuGenTxt.."\n"..("BLUE PART A")

	local _str = "Draft_sortiesA = " .. TableSerialization(Draft_sorties, 0)						--make a string
	local _file = io.open("Debug/Draft_sortiesA.lua", "w")  or error("Failed to open debug file")
	_file:write(_str)																		--save new data
	_file:close()

	for sideName, drafts in pairs(Draft_sorties) do
		local di = 1
		debugLog(string.upper(sideName).." PART A")

		for draft_n, draft in pairs(drafts) do
			if  di < Debug.Generator.nb or draft.name == Debug.Generator.SpySquad or draft.target_name == Debug.Generator.SpyTarget then		--if  di < Debug.Generator.nb and string.find(draft.task, "Strike") then
				debugLog(	"A N° " .. draft_n..
						" /id/ " ..tostring(draft.id)..
						" /Prioriry/ " ..tostring(draft.priorityIni)..
						" /Nb/ " ..draft.number..
						" /flights/ " ..tostring(draft.flights)..
						" /Type/ "..draft.type..
						" /threatsGround/ "..round(draft.threatsGround)..
						" /threatsAir/ "..round(draft.threatsAir)..
						" /Score/ " ..round(draft.score)..
						" /Task/ "..draft.task..
						" /Target/ "..draft.target_name..
						" /Sead_Of/ "..tostring(draft.route.threats.SEAD_offset)..
						" /mainOverRideMP/ " ..tostring(draft.mainOverRideMP)..
						" /remainingFirepower/ " ..draft.remainingFirepower..
						" /multipack/ " ..draft.multipack

						-- .." /loadout/ "..tostring(draft.loadout.loadout_name)
						)


				di = di +1
			end
		end
	end

end

--create additional draft sorties with support flights assigned
local wk = 1
local i_timmer02 = 0
local uniqueBonus = false

--inversion des 2 boucles draft_sortie en premier, oob_air ensuite, pour homogeniser les chances de sortie de tous les escadrons support
for sideName, draftT in pairs(Draft_sorties) do
	-- for draft_n, draft in ipairs(Draft_sorties[sideName]) do													--iterate through all draft sorties beginning with the highest scored
	for draft_n, draft in ipairs(draftT) do

		local isDebugModeB = Debug.Generator.affiche and string.find(Debug.Generator.chapter, "B")
							and ( Debug.Generator.SpySquad and Debug.Generator.SpySquad == draft.name
							or (Debug.Generator.SpyTarget and Debug.Generator.SpyTarget == draft.target_name ))


		if isDebugModeB then
			debugLog(draft.id.." AtoG II passe B_00 target_name draftType: "..draft.type.." "..tostring(draft.target_name) .." "..tostring(draft.score))
		end

		--determine enemy side
		local enemy																						--determine enemy side (opposite of unit side)
		if sideName == "blue" then
			enemy = "red"
		else
			enemy = "blue"
		end

		--rearange aléatoirement les unites pour que ne soit pas toujours les memes
		local shuffled = {}
		for i, v in ipairs(oob_air["blue"]) do
			local pos = math.random(1, #shuffled+1)
			table.insert(shuffled, pos, v)
		end
		oob_air["blue"] = shuffled

		shuffled = {}
		for i, v in ipairs(oob_air["red"]) do
			local pos = math.random(1, #shuffled+1)
			table.insert(shuffled, pos, v)
		end
		oob_air["red"] = shuffled

		--place en premier les unites des joueurs multi

		-- if multiPlaneSet.blue then
		-- 	for o = #oob_air["blue"], 1, -1 do
		-- 		if oob_air["blue"][o] and oob_air["blue"][o].type ==  multiPlaneSet.blue[oob_air["blue"][o].plane] 
		-- 		and oob_air["blue"][o].task ==  multiPlaneSet.blue[oob_air["blue"][o].task]  then	
		-- 			table.remove(oob_air["blue"], o)																		
		-- 		end
		-- 	end
		-- end


		if multiPlaneSet.blue then
			for o = 1, #oob_air["blue"] do
				local oob = oob_air["blue"][o]
				if multiPlaneSet.blue[oob.type] and oob and oob.tasks then
					for taskName, taskValue in pairs(oob.tasks) do
						if taskName == multiPlaneSet.blue.task then
							-- Décaler les éléments de la position 1 à o-1 vers la droite
							table_move(oob_air["blue"], 1, o-1, 2)
							-- Mettre l'élément trouvé en tête de la table
							oob_air["blue"][1] = oob
							-- Supprimer l'élément à sa position originale (qui a été décalée)
							table.remove(oob_air["blue"], o + 1)
							break -- Si un seul déplacement est requis, on peut quitter la boucle ici
						end
					end
				end
			end
		end

		if multiPlaneSet.red then
			for o = 1, #oob_air["red"] do
				local oob = oob_air["red"][o]
				if multiPlaneSet.red[oob.type] and oob and oob.tasks then
					for taskName, taskValue in pairs(oob.tasks) do
						if taskName == multiPlaneSet.red.task then
							-- Décaler les éléments de la position 1 à o-1 vers la droite
							table_move(oob_air["red"], 1, o-1, 2)
							-- Mettre l'élément trouvé en tête de la table
							oob_air["red"][1] = oob
							-- Supprimer l'élément à sa position originale (qui a été décalée)
							table.remove(oob_air["red"], o + 1)
							break -- Si un seul déplacement est requis, on peut quitter la boucle ici
						end
					end
				end
			end
		end


		--tag multiPlaneSet_B Présent pour l'avion MAIN

		local multiPlaneSet_B = draft.multiPlaneSet_B or {}

		if multiPlaneSet_B and multiPlaneSet_B[sideName] and multiPlaneSet_B[sideName][draft.type] and multiPlaneSet_B[sideName][draft.type][draft.task] then
			multiPlaneSet_B[sideName][draft.type][draft.task].checked = true
		end

		local remain_SEAD_offset = draft.route.threats.SEAD_offset
		local remain_air_total = draft.route.threats.air_total

		for side, units in pairs(oob_air) do
			local NbTotalSupport = {}

			if units and units ~= nil then
				for unitN, unit in pairs(units) do

					local overRideMP_B = false

					if draft.mainOverRideMP or (multiPlaneSet[side] and  multiPlaneSet[side][unit.type]) then
						overRideMP_B = true
					else
						overRideMP_B = false
					end

					-- if side == sideName and unit.inactive ~= true and db_airbases[unit.base] and db_airbases[unit.base].inactive ~= true and ( overRideMP_B or (AcftAvail[unit.name] and AcftAvail[unit.name].available > 0))  and db_airbases[unit.base].x  then	--if unit is active, its base is active and has available aircraft -- ATO_G_debug01 Fin de campagne					
					if side == sideName and unit.inactive ~= true and db_airbases[unit.base] and db_airbases[unit.base].inactive ~= true and (  (AcftAvail[unit.name] and AcftAvail[unit.name].available > 0))  and db_airbases[unit.base].x  then	--if unit is active, its base is active and has available aircraft -- ATO_G_debug01 Fin de campagne					

						if isDebugModeB then
							debugLog(draft.id.." AtoG II passe B_02_a draft.: "..draft.type.." OOBunit: "..unit.type.." overRideMP_B?: "..tostring(overRideMP_B))
						end


						for task, task_bool in pairs(unit.tasks) do											--iterate through all tasks of unit
							local playable_II = false

							if isDebugModeB then
								debugLog(draft.id.." AtoG II passe B_03 task.: "..tostring(task).." task_bool: "..tostring(task_bool))
							end

							if draft.mainOverRideMP or( multiPlaneSet[side] and multiPlaneSet[side][unit.type] and multiPlaneSet[side][unit.type][task] and task_bool) then

								overRideMP_B = true

								if not Multi.Target and draft.task ~= "SAR" and draft.task ~= "CAP" then
									Multi.Target = {}
									Multi.Target[side] = draft.target_name
									overRideMP_B = true

									if isDebugModeB then
										debugLog(draft.id.." AtoG II passe B_04 draft.: "..draft.type.." OOBunit: "..unit.type.." overRideMP_B?: "..tostring(overRideMP_B))
									end
								end

							else
								overRideMP_B = false
							end

							local temp_Draft_sorties = {}														--temporary table to hold additional draft sorties with escorts assigned

							--**cet overRideMP_B donne trop d'avion
							-- if (overRideMP_B or (task == "SEAD" or task == "Escort" or task == "Escort Jammer" or task == "Flare Illumination" or task == "Laser Illumination")) and task_bool then	--task is a support task and is true
							if ( draft.task ~= "CAP" and draft.task ~= "Intercept" ) and (task == "SEAD" or task == "Escort" or task == "Escort Jammer" or task == "Flare Illumination" or task == "Laser Illumination" or task == "Strike") and task_bool then	--task is a support task --and is true and draft.task ~= "SAR"

								if isDebugModeB then
									debugLog(draft.id.." AtoG II passe B_05  ")
								end

								--get possible loadouts
								local unit_loadouts = {}														--table to hold all loadouts for this aircraft type and task

								for loadout_name, ltable in pairs(db_loadouts[unit.type][task]) do			--iterate through all loadouts for the aircraft type and task
									ltable.name = loadout_name
									if ltable.standoff == nil then ltable.standoff = 0 end

									local countryEligible = false
									if ltable.country == nil  then
										countryEligible = true
									elseif type(ltable.country) == "string" then
										if string.lower(ltable.country) == string.lower(unit.country) or string.lower(ltable.country) == "all" then
											countryEligible = true
										end

									elseif type(ltable.country) == "table" then
										for n, countryLabel in pairs(ltable.country) do
											if string.lower(countryLabel) == string.lower(unit.country) or string.lower(countryLabel) == "all" then
												countryEligible = true
												break
											end
										end
									end

									if countryEligible then
										unit_loadouts[#unit_loadouts+1] = ltable
									end

								end

								-- trie par standoff
								table.sort(unit_loadouts, function(a,b) return a.standoff > b.standoff  end)

								for l = 1, #unit_loadouts do													--iterate through all available loadouts				

									--get possible Time on Target
									local tot_from = 0															--earliest Time on Target for this loadout
									local tot_to = 0															--latest Time on target for this loadout

									if unit_loadouts[l].day == nil then
										unit_loadouts[l].day = true
									end

									if unit_loadouts[l].day and unit_loadouts[l].night then						--loadout is day and night capable
										tot_from = 0															--from mission start
										tot_to = mission_ini.mission_duration											--to mission end
									elseif unit_loadouts[l].day then											--loadout is day capable
										if Daytime == "night-day" then
											tot_from = mission_ini.dawn - camp.time									--from dawn
											tot_to = mission_ini.mission_duration										--to mission end
										elseif Daytime == "day" then
											tot_from = 0														--from missiom start
											tot_to = mission_ini.mission_duration										--to mission end
										elseif Daytime == "day-night" then
											tot_from = 0														--from mission start
											tot_to = mission_ini.dusk - camp.time										--to dusk
										end
									elseif unit_loadouts[l].night then											--loadout is night capable
										if Daytime == "day-night" then
											tot_from = mission_ini.dusk - camp.time									--from dusk
											tot_to = mission_ini.mission_duration										--to mission end
										elseif Daytime == "night" then
											tot_from = 0														--from mission start
											tot_to = mission_ini.mission_duration										--to mission end
										elseif Daytime == "night-day" then
											tot_from = 0														--from mission start
											tot_to = mission_ini.dawn - camp.time										--to dawn
										end
									end

									if isDebugModeB then
										debugLog(draft.id.." AtoG II passe B_06 tot_from: "..tot_from.." tot_to: "..tot_to.." overRideMP_B: "..tostring(overRideMP_B))
									end

									--**cet overRideMP_B donne trop d'avion
									-- if overRideMP_B or (tot_from ~= 0 or tot_to ~= 0)   then										--loadout has an eligible time on target
									if  (tot_from ~= 0 or tot_to ~= 0)   then

										if not draft.support[task] then draft.support[task] ={} end
										if not draft.support[task]["NbTotalSupport"] then draft.support[task]["NbTotalSupport"] = 0 end
										-- if not draft.support[task]["escort_max"] then draft.support[task]["escort_max"] = campMod.Setting_Generation.limit_escort end
										if not draft.support[task]["escort_max"] then draft.support[task]["escort_max"] = 999 end

										local MP_Game = false
										if multiPlaneSet then
											if multiPlaneSet[side] and multiPlaneSet[side][unit.type] and multiPlaneSet[side][unit.type][task] then

												-- if  Multi.Target and Multi.Target[side] then
												-- 	debugLog(draft.id.." AtoG II passe B_9 Multi.Target[side]: "..tostring(Multi.Target[side]).." target_name: "..tostring(draft.target_name))
												-- end

												if Multi.Target and Multi.Target[side] and Multi.Target[side] == draft.target_name then

													if draft.task ~= "SAR" then
														MP_Game = true
													end


													-- --TODO faire en sorte qu'un seul score soit augmenté
													-- --augmente de 10% le score si l'avion peut etre joué
													-- -- if unit.player then
													-- draft.score = draft.score * 20
													-- -- Draft_sorties_entry.scoreAdd =  Draft_sorties_entry.scoreAdd + 1000
													-- draft.scoreCoef =  draft.scoreCoef * 20
													-- -- endroit

													if isDebugModeB then
														debugLog(draft.id.." AtoG II passe B_10c MP_Game = true target_name: "..tostring(draft.target_name))
													end

												end
											end
										end


										if isDebugModeB then
											debugLog(draft.id.." AtoG II passe B_07")
										end

										i_timmer02 = i_timmer02 +1
										if  (draft.loadout.support and draft.loadout.support[task])
											and ( (tonumber(draft.support[task]["NbTotalSupport"]) < tonumber(draft.support[task]["escort_max"]))  ) then

										-- if overRideMP_B or (draft.loadout.support and draft.loadout.support[task])
											-- and ( (tonumber(draft.support[task]["NbTotalSupport"]) < tonumber(draft.support[task]["escort_max"])) or MP_Game ) then

											if isDebugModeB then
												debugLog(draft.id.." AtoG II passe B_12 task "..task.." SEAD_offset  "..tostring(draft.route.threats.SEAD_offset))
											end


											local support_requirement = false
											if task == "SEAD" then
												if draft.route.threats.SEAD_offset > 0 then												--draft sortie has a SEAD offset requirement
													support_requirement = true
												end
											elseif task == "Escort" then
												if draft.route.threats.air_total > 0.5 then												--draft sortie has an air threat
													support_requirement = true
												end
											elseif task == "Escort Jammer" then
												if draft.route.threats.SEAD_offset > 0 or draft.route.threats.air_total > 0.5 then		--draft sortie has either a SEAD offest requirement or an air threat
													support_requirement = true
												end
											elseif task == "Flare Illumination" or task == "Laser Illumination"then
												support_requirement = true
											end

											if draft.task == "SAR" then
												support_requirement = false
											end


											if isDebugModeB then
												debugLog(draft.id.." AtoG II passe B_15 threats.SEAD_offset?: "..tostring(draft.route.threats.SEAD_offset).." support_requirement?: "..tostring(support_requirement).." "..unit.type.." MP_Game: "..tostring(MP_Game))
											end

											if support_requirement or MP_Game then																	--go ahead with this support task
												if Debug.Generator.affiche and string.find(Debug.Generator.chapter, "B")
												and (Debug.Generator.SpySquad and (Debug.Generator.SpySquad == unit.name or Debug.Generator.SpySquad == draft.name)  and  (Debug.Generator.SpyTask == draft.task or Debug.Generator.SpyTask == task)
												or (Debug.Generator.SpyTarget and Debug.Generator.SpyTarget == draft.target_name ))
												then
													debuGenTxt = debuGenTxt.."\n"..(tostring(draft.id).." AtoG II passe B_15b support_requirement passe: ")
												end


												if (unit_loadouts[l].day and draft.loadout.day) or (unit_loadouts[l].night and draft.loadout.night) then	--support can join package at either day or night
													TrackPlayability(unit.player, "tot")															--track playabilty criterium has been met
													--admet une vitesse (escort) 75% plus faible que la vitesse du Main
													if unit_loadouts[l].vCruise < draft.loadout.vCruise then

														if isDebugModeB then
															debugLog(draft.id.." AtoG II passe B_15c unit_loadouts[l].vCruise : "..tostring(unit_loadouts[l].vCruise).." < "..tostring(draft.loadout.vCruise).. " | %: "..tostring(unit_loadouts[l].vCruise / draft.loadout.vCruise))
														end


														if (unit_loadouts[l].vCruise / draft.loadout.vCruise) * 100 >= 75 then
															draft.loadout.vCruise = unit_loadouts[l].vCruise
														end
													end


													if isDebugModeB then
														debugLog(draft.id.." AtoG II passe B_15d support_requirement passe: ")
													end

													if unit_loadouts[l].vCruise >= draft.loadout.vCruise or overRideMP_B then										--support has a cruise speed equal or higher than main body
														TrackPlayability(unit.player, "target")													--track playabilty criterium has been met

														local debuGenTxt1480 = "\n"..(tostring(draft.id).." AtoG II passe B_15e support_requirement passe: ")

														--check weather
														local weather_eligible = true
														if mission.weather["clouds"]["density"] > 8 then											--overcast clouds
															local cloud_base = mission.weather["clouds"]["base"]
															local cloud_top = mission.weather["clouds"]["base"] + mission.weather["clouds"]["thickness"]
															if db_airbases[unit.base].elevation + 333 > cloud_base then							--cloud base is less than 1000 ft above airbase elevation
																if unit_loadouts[l].adverseWeather == false then									--loadout is not adverse weather capable
																	weather_eligible = false														--not eligible for this weather
																end
															else
																if draft.loadout.hCruise > cloud_base and draft.loadout.hCruise < cloud_top then	--cruise alt is in the clouds
																	if unit_loadouts[l].adverseWeather == false then								--loadout is not adverse weather capable
																		weather_eligible = false													--not eligible for this weather
																	end
																elseif draft.loadout.hAttack > cloud_base and draft.loadout.hAttack < cloud_top then	--attack alt is in the clouds
																	if unit_loadouts[l].adverseWeather == false then								--loadout is not adverse weather capable
																		weather_eligible = false													--not eligible for this weather
																	end
																end
															end
														end
														if mission.weather["enable_fog"] == true then												--fog
															if db_airbases[unit.base].elevation < mission.weather["fog"]["thickness"] then		--base elevation in fog
																if mission.weather["fog"]["visibility"] < 5000 then									--less than 5000m visibility
																	if unit_loadouts[l].adverseWeather == false then								--loadout is not adverse weather capable
																		weather_eligible = false													--not eligible for this weather
																	end
																end
															end
														end

														if Debug.Generator.affiche and string.find(Debug.Generator.chapter, "B")
														and (Debug.Generator.SpySquad and (Debug.Generator.SpySquad == unit.name or Debug.Generator.SpySquad == draft.name)  and  (Debug.Generator.SpyTask == draft.task or Debug.Generator.SpyTask == task)
														or (Debug.Generator.SpyTarget and Debug.Generator.SpyTarget == draft.target_name ))
														then
															debuGenTxt = debuGenTxt..debuGenTxt1480.."\n"..(tostring(draft.id).." AtoG II passe B_15e support_requirement passe: weather_eligible "..tostring(weather_eligible).." overRideMP_B "..tostring(overRideMP_B))
														end

														if weather_eligible or overRideMP_B then												--continue of this loadout is eligible for weather


															TrackPlayability(unit.player, "weather")												--track playabilty criterium has been met								
															--get airbase position
															local airbasePoint = {																	--get the x-y coordinates of the airbase where the unit is located
																x = db_airbases[unit.base].x,
																y = db_airbases[unit.base].y,
																h = db_airbases[unit.base].elevation,
															}

															local route = GetEscortRoute(airbasePoint, draft.route, task, unit_loadouts[l], unit, draft)									--get the route to escort this sortie

															if isDebugModeB then
																debugLog(draft.id.." AtoG II passe B_16 weather_eligible route.lenght: "..tostring(route.lenght).. " <= "..tostring(unit_loadouts[l].range * 2)
																.." (loadouts: )" ..tostring(unit_loadouts[l].range)..") loadoutName: "..tostring(unit_loadouts[l].name)
																.."unit_loadouts[l].minrange: "..tostring(unit_loadouts[l].minrange))
															end


															if route.lenght <= unit_loadouts[l].range * 2 and (unit_loadouts[l].minrange == nil or route.lenght > unit_loadouts[l].minrange * 2) then		--escort route lenght is within range capability of loadout
																TrackPlayability(unit.player, "target_range")									--track playabilty criterium has been met

																local debuGenTxt1545 = "\n"..(tostring(draft.id).." AtoG II passe B_17  ")

																--determine number of escorts
																local escort_num = 0
																local escort_max = 0

																if draft.support[task]["escort_max"] ~= 999 then
																	escort_max = draft.support[task]["escort_max"]
																else
																	escort_max = 0
																end

																if task == "SEAD" then
																	escort_num = draft.route.threats.SEAD_offset / unit_loadouts[l].firepower 		-- unit_loadouts[l].capability  capability determines amount of offset per aircraft
																	-- escort_num = remain_SEAD_offset / unit_loadouts[l].firepower
																	escort_num = math.ceil(escort_num / 2) * 2										--round up requested escorts to even number

																	--TODO revoir ça
																	-- if totalPlanePerTask[side][task] and totalPlanePerTask[side][task]/2 >= escort_num then
																	-- 	draft.score = draft.score + (1 * draft.loadout.firepower) * draft.target.priority
																	-- end

																	debuGenTxt1545 = debuGenTxt1545.."\n"..(tostring(draft.id).." AtoG II passe_SEAD B "..unit.type.." "..task.." "..escort_num.." NbTotalSupport: "..draft.support[task]["NbTotalSupport"].." draft.score: "..draft.score)
																	debuGenTxt1545 = debuGenTxt1545.."\n"..("-------------------- escort_num: "..(draft.route.threats.SEAD_offset / unit_loadouts[l].firepower).. "= SEAD_Offset: "..draft.route.threats.SEAD_offset.." /firepower "..unit_loadouts[l].firepower
																	)


																elseif task == "Escort" then
																	if draft.support[task]["escort_max"] ~= 999 then
																		escort_num = draft.support[task]["escort_max"] - draft.support[task]["NbTotalSupport"]	-- modification M11.x : Multiplayer	(x: EscorteTot-max)

																		debuGenTxt1545 = debuGenTxt1545.."\n"..(tostring(draft.id).." AtoG II passe_Escort B "..unit.type.." "..task.." "..escort_num.." NbTotalSupport: "..draft.support[task]["NbTotalSupport"])

																	else

																		local escort_offset_level =  unit_loadouts[l].firepower	--unit_loadouts[l].capability *--threat level that each fighter escort can offset
																		-- escort_num = (draft.route.threats.air_total - 0.5) / escort_offset_level		--number of escorts needed to offset total air threat (-0.5 because that is no air threat)
																		escort_num = (remain_air_total - 0.5) / escort_offset_level



																		if escort_num > draft.number * 2 then											--when more escorts 2 times escorts than escorted aircraft
																			escort_num = draft.number * 2												--limit escort number to 2 times escorted aircraft
																		end
																		-- if escort_num > campMod.Setting_Generation.limit_escort then
																		-- 	escort_num = campMod.Setting_Generation.limit_escort
																		-- end

																		escort_num = math.ceil(escort_num / 2) * 2										--round up requested escorts to even number

																		if escort_num > escort_max then
																			escort_max = escort_num
																			draft.support[task]["escort_max"] = escort_max
																		end

																		debuGenTxt1545 = debuGenTxt1545.."\n"..(tostring(draft.id).." AtoG II passe_Escort I "..unit.type.." "..task.." "..escort_num)

																	end

																elseif task == "Escort Jammer" then
																	escort_num = 1																	--escort jamming by single aircraft
																elseif task == "Flare Illumination" then
																	escort_num = 1																	--flare illumination by single aircraft
																elseif task == "Laser Illumination" then
																	escort_num = 1																	--laser illumination by single aircraft
																elseif task == "Strike" and not overRideMP_B then
																	-- escort_num = 4
																	escort_num = draft.remainingFirepower / unit_loadouts[l].firepower
																elseif task == "Strike"  then
																	escort_num = 4
																end

																--ici 4 Mi24 redemandé
																-- mais c'est 4 de trop, 4 sont déjà pris en main strike
																if escort_num > AcftAvail[unit.name].available then					--if more escorts are requested than available
																	escort_num = AcftAvail[unit.name].available						--reduce requested escorts to number of available escorts
																	escort_num = math.floor(escort_num / 2) * 2										--round down to even number

																	debuGenTxt1545 = debuGenTxt1545.."\n"..(tostring(draft.id).." AtoG II passe_Escort J "..unit.type.." "..task.." escort_num: "..escort_num.." available: "..AcftAvail[unit.name].available)

																end

																debuGenTxt1545 = debuGenTxt1545.."\n"..(tostring(draft.id).." AtoG II passe_Escort P "..unit.type.." "..task.." "..escort_num)


																--*********************************************************************************
																-- modification M11.o multiplayer**************************************************
																local txtDebug = ""
																if multiPlaneSet_B  then
																	txtDebug = txtDebug .. " passeA ".."/n"

																	-- if  multiPlaneSet_B[side] and multiPlaneSet_B[side][unit.type]  and multiPlaneSet_B[side][unit.type][task] then	
																	if MP_Game then

																		--si l'avion de support est déjà utilise en MAIN, on enleve la qté dejà utilisé
																		if multiPlaneSet_B and multiPlaneSet_B[side] and multiPlaneSet_B[side][draft.type] and multiPlaneSet_B[side][draft.type][draft.task] and task_bool then

																			-- print("AtoG II passe_Escort P2 side "..side.." draft.type: "..tostring(draft.type).." task "..tostring(task).." draft.task "..tostring(draft.task).."")

																			multiPlaneSet_B[side][draft.type][draft.task].NbPlane = multiPlaneSet_B[side][draft.type][draft.task].InitNbPlaneByTask - draft.number
																			txtDebug = txtDebug .. "    passeB NbPlane: "..multiPlaneSet_B[side][draft.type][draft.task].NbPlane.." draft.task: "..tostring(draft.task).."/n"

																		end


																		playable_II = true

																		if escort_num < multiPlaneSet_B[side][unit.type][task].NbPlane then
																			escort_num =  multiPlaneSet_B[side][unit.type][task].NbPlane
																			txtDebug = txtDebug .. "    passeC "..escort_num.."/n"
																		elseif escort_num > multiPlaneSet_B[side][unit.type][task].NbPlane then
																			escort_num =  multiPlaneSet_B[side][unit.type][task].NbPlane
																			txtDebug = txtDebug .. "    passeD "..escort_num.."/n"
																		end

																		txtDebug = txtDebug .. "    passeE "..draft.score.."/n"

																		draft.score = draft.score * 1.2 + 1000
																		draft.scoreAdd =  draft.scoreAdd + 1000
																		draft.scoreCoef =  draft.scoreCoef * 1.2

																		txtDebug = txtDebug .. "    passeF "..draft.score.."/n"

																		txtDebug = txtDebug .. "    passeG NbPlane "..multiPlaneSet_B[side][unit.type][task].NbPlane.."/n"
																		txtDebug = txtDebug .." InitNbPlaneByTask: "..tostring(multiPlaneSet_B[side][unit.type][task].InitNbPlaneByTask)

																		-- Marquer l'unité comme vérifiée
																		multiPlaneSet_B[side][unit.type][task].checked = true

																		-- Vérification si tous les éléments sont cochés
																		local fullMP_Plane = true
																		for typeM, tasksM in pairs(multiPlaneSet_B[side]) do
																			if type(tasksM) == "table" then
																				for taskM, value in pairs(tasksM) do
																					if type(value) == "table" and not value.checked then
																						fullMP_Plane = false
																						break  -- Arrêter la vérification dès qu'un élément n'est pas coché
																					end
																				end
																				if not fullMP_Plane then
																					break  -- Sortir complètement si un type n'est pas entièrement vérifié
																				end
																			end
																		end

																		-- Doubler le score si tous les éléments sont cochés
																		if fullMP_Plane and not uniqueBonus then
																			draft.score = draft.score * 2000
																			draft.scoreCoef =  draft.scoreCoef * 2000

																			uniqueBonus = true

																			-- print(tostring(draft.id).." "..draft.score)																			
																		end

																	end


																	if isDebugModeB then
																		debugLog(debuGenTxt1545..draft.id.." AtoG II passe B_20a2. escort_num "..tostring(escort_num).." txtDebug: "..txtDebug  )
																	end

																end

																if Multi.NbGroup == 0 then
																	playable_II = unit.player
																end

																local wi = 1

																if isDebugModeB then
																	debugLog(draft.id.." AtoG II passe B_21c Id "..tostring(draft.id).." "..unit.type.." "..unit.name.." escort_num "..tostring(escort_num).." "..draft.target_name.." NbTotalSupport: "..draft.support[task]["NbTotalSupport"]  )
																end

																TrackPlayability(unit.player, "target_firepower")							--track playabilty criterium has been met

																local entryEscortNum

																entryEscortNum = escort_num

																if not draft.support[task] then
																	draft.support[task] = {}
																end


																--add escort table to sortie															
																draft.support[task]["NbTotalSupport"] = draft.support[task]["NbTotalSupport"] + escort_num
																draft.support[task]["escort_max"] = escort_max

																if isDebugModeB then
																	debugLog(draft.id.." AtoG II passe B_21d Id "..tostring(draft.id).." "..unit.type.." "..unit.name.."".." escort_num "..tostring(escort_num).." "..draft.target_name.." NbTotalSupport: "..draft.support[task]["NbTotalSupport"].." entryEscortNum: "..tostring(entryEscortNum)  )
																end

																if entryEscortNum >= 1 then

																	if Debug.Generator.affiche and string.find(Debug.Generator.chapter, "B")
																	and (Debug.Generator.SpySquad and Debug.Generator.SpySquad == unit.name  and  (Debug.Generator.SpyTask == draft.task or Debug.Generator.SpyTask == task)
																	or (Debug.Generator.SpyTarget and Debug.Generator.SpyTarget == draft.target_name ))
																	then
																		debuGenTxt = debuGenTxt.."\n"..(tostring(draft.id).." AtoG II passe B_21c Add In draft.support ")
																	end

																	if not draft.support[task][unit.type] then
																		draft.support[task][unit.type] = {}
																	end

																	draft.support[task][unit.type] = {
																		id = draft.id.."-"..wi.."-"..wk,
																		name = unit.name,
																		playable = playable_II,								--unit.player,
																		-- playable = unit.player,
																		type = unit.type,
																		modification = unit.modification,
																		callsign = unit.callsign,
																		callsignId = unit.callsignId,
																		helicopter = unit.helicopter,											-- modification M06 : helicopter playable
																		number = entryEscortNum,
																		country = unit.country,
																		livery = unit.livery,
																		sidenumber = unit.sidenumber,
																		liveryModex = unit.liveryModex,
																		base = unit.base,
																		airdromeId = db_airbases[unit.base].airdromeId,
																		parking_id = unit.parking_id,
																		skill = unit.skill,
																		task = task,
																		tasks = unit.tasks,
																		loadout = unit_loadouts[l],
																		route = route,
																		target = Deepcopy(draft.target),
																		target_name = draft.target.titleName,
																		tot_from = draft.tot_from,
																		tot_to = draft.tot_to,
																		rejected = {},
																		overRideMP_B = overRideMP_B,
																		priorityIni = draft.priorityIni,
																		support_requirement = support_requirement,
																	}

																end

																--recalculate threat level for sortie adjusted by number of escort
																-- route.threats.ground_total_OLD = Deepcopy(route.threats.ground_total)
																-- route.threats.air_total_OLD = Deepcopy(route.threats.air_total)

																local route_threat_OLD = draft.route.threats.ground_total + draft.route.threats.air_total
																-- print()
																-- if draft.name == "VMA 311" then print("Atog A1 draft.id "..draft.id) end

																local route_threat_recalc = 0.5														--recalculated route threat with escort in place (0.5 == no threat)
																if task == "SEAD" then
																	local escort_offset = escort_num *  unit_loadouts[l].firepower					--* unit_loadouts[l].capability--number of available SEAD to offset threats
																	for k, tGround in pairs(draft.route.threats.ground) do									--iterate through route ground threats
																		if tGround.offset > 0 then														--if threat can be offset by SEAD
																			if escort_offset >= tGround.offset then										--some SEAD aircraft remain to offset the threat
																				route_threat_recalc = escort_offset - tGround.offset							--use these SEAD aircraft to offset and ignore the therat
																			else																	--no SEAD aircraft remain unassignedd
																				route_threat_recalc = route_threat_recalc + tGround.level					--sum route ground threat levels
																			end
																		else																		--threat cannot be offset by SEAD
																			route_threat_recalc = route_threat_recalc + tGround.level						--sum route ground threat levels
																		end
																		-- if draft.name == "VMA 311" then print("Atog A2 recalcul SEAD "..route_threat_recalc) end
																	end

																	if not draft.route.threats.ground_total_Init then
																		draft.route.threats.ground_total_Init = draft.route.threats.ground_total
																	end

																	if route_threat_recalc < 0.5 then
																		route_threat_recalc = 0.5
																	end

																	draft.route.threats.ground_total = route_threat_recalc			--recalculated total route grund threat

																elseif task == "Escort" then

																	local escort_offset_level =  unit_loadouts[l].firepower		--unit_loadouts[l].capability *--threat level that each fighter escort can offset
																	route_threat_recalc = draft.route.threats.air_total - escort_offset_level * escort_num			--recalculated total route air threat

																	if route_threat_recalc < 0.5 then
																		route_threat_recalc = 0.5
																	end

																	draft.route.threats.air_total = route_threat_recalc

																	-- if draft.name == "VMA 311" then print("Atog A3 recalcul Escort "..route_threat_recalc) end

																elseif task == "Escort Jammer" then
	--ADD RECALCULATED THREAT LEVEL WITH ESCORT JAMMERS
																end


																local route_threat_New = draft.route.threats.ground_total + draft.route.threats.air_total
																-- if draft.name == "VMA 311" then print("Atog A2 route_threat_OLD "..route_threat_OLD.." route_threat_New "..route_threat_New) end

																if route_threat_New ~= route_threat_OLD then
																	local oldScore = draft.score
																	draft.score = draft.priorityIni / route_threat_New

																	-- if draft.name == "VMA 311" then print("Atog "..draft.type.." target_name "..draft.target_name) end
																	-- if draft.name == "VMA 311" then print("AtoG                  Total AA id "..draft.id.." priorityIni: "..draft.priorityIni.." Oldscore: "..oldScore.." NewScore: "..draft.score.." route_threat_OLD "..route_threat_OLD) end


																	draft.score =  draft.score * draft.scoreCoef
																	draft.score =  draft.score + draft.scoreAdd

																	-- if draft.name == "VMA 311" then print("AtoG                  Total BB id "..draft.id.." priorityIni: "..draft.priorityIni.." Oldscore: "..oldScore.." NewScore: "..draft.score.." route_threat "..route_threat_New) end


																end

																-- if  multiPlaneSet[side] and  multiPlaneSet[side][unit.type] and  multiPlaneSet[side][unit.type][task] and task_bool and  multiPlaneSet[side][unit.type][task].NbPlane > 0 then
																-- 	draft.score = draft.score + 1000
																-- 	debuGenTxt = debuGenTxt.."\n"..(tostring(draft.id).." AtoG B passe multiPlaneSet B: score: " .. tostring(draft.score).." "..unit.type.." "..tostring(task))

																-- 	if draft.mainOverRideMP then
																-- 		draft.score = draft.score * 2 +1000
																-- 		debuGenTxt = debuGenTxt.."\n"..(tostring(draft.id).." AtoG B passe multiPlaneSet C: score: " .. tostring(draft.score).." "..unit.type.." "..tostring(task))
																-- 	end
																-- elseif  Multi.Target and Multi.Target[side] == draft.target_name  then
																-- 	-- draft.score = draft.score * 2   -- attention tout autre avion non multi augmente drastiquement ici
																-- 	draft.score = draft.score + 1 
																-- 	debuGenTxt = debuGenTxt.."\n"..(tostring(draft.id).." AtoG B passe multiPlaneSet D:  "..tostring(draft.id).." score: " .. tostring(draft.score).." "..unit.type.." "..tostring(task))
																-- end

																-- --augmente de 10% le score si l'avion peut etre joué
																-- if draft.playable then

																-- 	draft.score = draft.score * 2

																-- end

																--adjust sortie Time on Target
																if tot_from > draft.tot_from then									--if earliest escort Time on Target is later than main body TOT
																	draft.tot_from = tot_from							--make earliest escort TOT the draft sortie earliest TOT 
																end
																if tot_to < draft.tot_to then										--if latest escort Time on Target is sooner than main body TOT
																	draft.tot_to = tot_to								--make latest escort TOT the draft sortie latest TOT
																end

																--status report
																status_counter_escorts = status_counter_escorts + 1
																--debuGenTxt = debuGenTxt.."\n"..("ATO Assigning Escorts (" .. status_counter_escorts .. ")")	--DEBUG

																wi = wi + 1


																if isDebugModeB then
																	debugLog(draft.id.." AtoG II passe B_22 escort_num "..tostring(escort_num).." "..unit.type.." target_name: "..tostring(draft.target_name)  )
																end


															end
														end
													end
												end
											end
										else
											-- print("ATO_G  Refused02 ||:if draft.loadout.support and draft.loadout.support[task] and "..debug.getinfo(1).currentline)
											-- print("    draft.type"..tostring(draft.type).."[task]?: "..tostring(task).." NbTotalSupport: "..tonumber(draft.support[task]["NbTotalSupport"]).." < "..tonumber(draft.support[task]["escort_max"]).." or "..tostring(MP_Game))
										end
										if i_timmer02 >= 1000  then io.write(".") i_timmer02 = 0 end
										wk = wk +1
									end
								end
							end
						end
					end
				end
			end
		end
	end
end

-- debuGenTxt = debuGenTxt.."\n\n"..("ATO Assigning Escorts (" .. status_counter_escorts .. ")")

-- if isDebugModeB then
-- 	debugLog(draft.id.." AtoG II passe B_22 escort_num "..tostring(escort_num).." "..unit.type.." target_name: "..tostring(draft.target_name)  )
-- end


-- Tri final par `targetPriority` (ascendant), puis par `score` (descendant)
for side, sorties in pairs(Draft_sorties) do
    table.sort(sorties, function(a, b)
        if a.targetPriority ~= b.targetPriority then
            return a.targetPriority > b.targetPriority -- Plus grande priorité d'abord
        end
        return a.score > b.score -- Plus grand score d'abord
    end)
end

if Debug.Generator.affiche then

	debugLog("ATO Assigning Escorts (" .. status_counter_escorts.. ")")

	for sideName, drafts in pairs(Draft_sorties) do
		-- debuGenTxt = debuGenTxt.."\n\n\n"..( string.upper(sideName).." PART B")
		debugLog(string.upper(sideName).." PART B")

		local di = 1
		for draft_n, draft in pairs(drafts) do
			if  di < Debug.Generator.nb or draft.name == Debug.Generator.SpySquad  or draft.target_name == Debug.Generator.SpyTarget then

				debugLog(	"B N° " .. draft_n..
						-- " /support/ " ..tostring(draft.support)..
						" /Id " ..tostring(draft.id)..
						" /Prioriry/ " ..tostring(draft.priorityIni)..
						" /Name/ " ..tostring(draft.name)..
						" /Nb/ " ..draft.number..
						" /flights/ " ..tostring(draft.flights)..
						" /Type/ "..draft.type..
						" /thrtGrnd/ "..round(draft.threatsGround)..
						" /thrtA/ "..round(draft.threatsAir)..
						" /Score/ " ..round(draft.score)..
						" /NbTotSupt/ " ..tostring(draft.NbTotalSupport)..

						" /Task/ "..draft.task..
						" /Target/ "..draft.target_name..
						" /Sead_Of/ "..tostring(draft.route.threats.SEAD_offset)..
						" /mainOverRideMP/ " ..tostring(draft.mainOverRideMP)..
						" /loadout/ "..tostring(draft.loadout.loadout_name)
						)

				di = di +1
				for _planeTask, PlaneTask in pairs(draft.support) do
					for taskName, task in pairs(PlaneTask) do

						if type(task) == "table" and task.target_name and task.loadout then

							debugLog(	"    ---> Nsupport " .._planeTask.." ".. taskName..
									" /Id/ " ..tostring(task.id)..
									" /Nb/ " ..task.number..
									" /escort_max/ " ..tostring(PlaneTask.escort_max)..
									" /SupportName/ "..task.name..
									" /Type/ "..task.type..
									" /Task/ "..task.task..
									" /NbTotSupt/ " ..tostring(task.NbTotalSupport)..
									" /Target/ "..task.target_name..
									" /overRideMP_B/ "..tostring(task.overRideMP_B)..
									" /loadout/ "..tostring(task.loadout.loadout_name)
									)
						end
					end
				end
				-- debuGenTxt = debuGenTxt.."\n\n"
			end
		end
	end


	-- debuGenTxt = debuGenTxt.."\n"
end

--table to store the final ATO
ATO = {
	blue = {},
	red = {}
}



--assign draft sorties to ATO and build packages/flights
local function createATO_table(draftPriority)
	for side, drafts in pairs(draftPriority) do
		if drafts and drafts ~= nil then
			for draftN, draft in pairs(drafts) do																						--iterate through all draft sorties beginning with the highest scored			

				local isDebugModeC = Debug.Generator.affiche and string.find(Debug.Generator.chapter, "C")
						and ( Debug.Generator.SpySquad and Debug.Generator.SpySquad == draft.name
						or (Debug.Generator.SpyTarget and Debug.Generator.SpyTarget == draft.target_name ))

				if isDebugModeC then
					debugLog(draft.id.." AtoG passe C_00 "..draft.type.." "..draft.task.." "..draft.score)
				end

				--diminue le minscore en fonction du nombre de tentative de generation de mission
				--evite un blocage de generation
				if draft.loadout.minscore and MissionInstance >= 2 then
					-- print("AtoG BEFOR minscore "..draft.loadout.minscore)
					draft.loadout.minscore = draft.loadout.minscore / ((MissionInstance )/10 +1)
					-- print("AtoG After minscore "..draft.loadout.minscore)
				end

				if draft.loadout.minscore == nil or draft.score >= draft.loadout.minscore then					--draft sortie has no minimum score requirement or minimum score requirement is satisified		
				-- if 1 == 1 then
					-- if draft.multipack > 0 then												--target does not have a requirment for a specific number of packages, or still needs more packages		
					if multipackByTargetName[draft.target_name] > 0 then

						if draft.target.firepower.max > 0 and draft.target.firepower.max >= draft.target.firepower.min then	--the target of this draft sortie must have a need for firepower above the minimum firepower threshold	
							local available = AcftAvail[draft.name].unassigned											--shortcut for available aircraft for this draft sortie					

							if available * draft.loadout.firepower >= draft.target.firepower.min and draft.number * draft.loadout.firepower >= draft.target.firepower.min then	--enough aircraft are available to satisfy minimum firepower requirement for target						

								if draft.target.firepower.packmin == nil or available * draft.loadout.firepower >= (draft.target.firepower.packmin - 1) * draft.target.firepower.max + draft.target.firepower.min then	--if the target has a minimum package number requirement, sufficient aircraft are available from this unit to satisfy it					

									local limitMP = true   --TODO a revoir, semble inutile

									if isDebugModeC and multiPlaneSet and multiPlaneSet[side] and multiPlaneSet[side][draft.type] and multiPlaneSet[side][draft.type][draft.task] then
										debugLog(draft.id.." AtoG passe C_00_b  ".." "..draft.type
											.." available: "..tostring(available)
											.." < NbPlane? ".. tostring(multiPlaneSet[side][draft.type][draft.task].NbPlane)
											.." mainOverRideMP?: "..tostring(draft.mainOverRideMP)
											.." overRideMP_B?: "..tostring(draft.overRideMP_B))
									end

									if (draft.flights == nil or draft.number <= available or draft.mainOverRideMP) and limitMP then											--for targets with station time (multiple flights), continue only if sufficient aircraft are availabe. Additional lower scored sorties with less airctaft required will come later 

										--adjust the number of requested aircraft to the number of available aircraft
										if draft.number > available and not draft.mainOverRideMP then

											draft.number = available

											if isDebugModeC then
												debugLog(draft.id.." AtoG passe C_00_c  number "..tostring(draft.number))
											end

										end

										--check if there are enough supports available if supports are required		
										local support_available = true
										-- local supportMandatory = true					

										local need = {}																														--collect the total number of aircraft needed from each unit to complete the package
										need[draft.name] = draft.number																								--number of main body aircraft 
										local avail = {}																													--collect the maximal number of available aircraft from this unit (biggest number of all tasks)
										avail[draft.name] = AcftAvail[draft.name].unassigned

										-- if multiPlaneSet_B  then
										-- 	if  multiPlaneSet_B[side] and multiPlaneSet_B[side][unit.type]  and multiPlaneSet_B[side][unit.type][task] then	

										-- 		if multiPlaneSet_B and multiPlaneSet_B[side] and multiPlaneSet_B[side][draft.type] and multiPlaneSet_B[side][draft.type][task] then

										-- 			multiPlaneSet_B[side][draft.type][task].NbPlane = multiPlaneSet_B[side][draft.type][task].InitNbPlaneByTask - draft.number
										-- 		end

										-- 	end

										-- end

										-- ["newTaskRequest"] = 
										-- {
										-- 	["red"] = 
										-- 	{
										-- 		["C-130"] = 
										-- 		{
										-- 			["Transport"] = 
										-- 			{
										-- 				["Escort"] = true,
										-- 			},

										-- 		},
										-- 	},
										-- },

										-- --ajoute une task obligatoire en fonction du learning des missions précédentes
										-- if camp.newTaskRequest then
										-- 	for rSide, rSides in pairs(camp.newTaskRequest) do
										-- 		if rSide == side then
										-- 			for rTypeName, rTypes in pairs(rSides) do
										-- 				if rTypeName == draft.type then
										-- 					for rTaskEnCours, rNewTasks in pairs(rTypes) do
										-- 						if rTaskEnCours == draft.task then
										-- 							for rNewTask, value in pairs(rNewTasks) do
										-- 								if value then
										-- 									for support_name, supportPart in pairs(draft.support) do										--iterate through all package support
										-- 										if type(supportPart) == "table" then	
										-- 											for _plane, support in pairs(supportPart) do
										-- 												if type(support) == "table" and not support.overRideMP_B then
										-- 													if  support.number > AcftAvail[support.name].unassigned then 
										-- 														support_available = false
										-- 														-- print("AtoG passe support_available FALSE "..draft.target_name.." "..support.name.." "..support.number)


										-- 														local tabRejected = {}
										-- 														tabRejected["sujet"]  = draft.id.." type: "..support.type.." newTaskRequest  AVION SUPPORT INSUFFISANTsupport.number < unassigned "
										-- 														tabRejected["cause"] = { [1] = AcftAvail[support.name].unassigned, [2] = "newTaskRequest", }
										-- 														tabRejected["ligne"]  = debug.getinfo(1).currentline														
										-- 														table.insert(draft["rejected"], tabRejected)

										-- 													end
										-- 												end
										-- 											end
										-- 										end
										-- 									end	
										-- 									-- print("AtoG passe newTaskRequest "..draft.target_name.." "..rTypeName .." rTaskEnCours: "..rTaskEnCours.." rNewTask: ".. rNewTask)

										-- 								end
										-- 							end
										-- 						end
										-- 					end
										-- 				end
										-- 			end
										-- 		end
										-- 	end
										-- end

										-- ["newTaskPerTarget"] = 
										-- {
										-- 	["EWR-Eyeball"] = 
										-- 	{
										-- 		["tasks"] = 
										-- 		{
										-- 			["SEAD"] = 1,
										-- 			["Escort"] = 2,
										-- 		},
										-- 		["difficult"] = 2,
										-- 		["lastNumMission"] = 2,
										-- 	},
										-- 	["North Cyprus-Turkish Force 4"] = 
										-- 	{
										-- 		["tasks"] = 
										-- 		{
										-- 			["SEAD"] = 1,
										-- 		},
										-- 		["difficult"] = 1,
										-- 		["lastNumMission"] = 3,
										-- 	},
										-- },



										--en fonction du learning des missions passé, interdit une mission si les task support ne sont pas present

										local tempInfo = " AtoG NbTotPlanePerTask CALCUL"
										local draft_availability = Deepcopy(AcftAvail)
										if camp.newTaskPerTarget then
											for tableTargetName, targetTask in pairs(camp.newTaskPerTarget) do
												if tableTargetName == draft.target_name and targetTask.tasks then

													for taskLearning, value in pairs(targetTask.tasks) do

														local NbTotPlanePerTask = 0

														for supportTask, supportPart in pairs(draft.support) do

															if supportTask == taskLearning then
																--avant d'interdire, on regarde si un squad possede la capacité du task
																local taskRequireInSide
																for squadN, squad in pairs(oob_air[side]) do
																	if not squad.inactive then
																		for task, taskValue in pairs(squad.tasks) do
																			if taskValue and task == taskLearning then
																				taskRequireInSide = true
																				break
																			end

																		end
																	end
																	if taskRequireInSide then break end
																end

																if taskRequireInSide and type(supportPart) == "table" then
																	for _plane, support in pairs(supportPart) do

																		if type(support) == "table" and draft_availability[support.name] then

																			if support.overRideMP_B then
																				NbTotPlanePerTask = 9999
																			else

																				--enleve le nombre de plane du main si le meme type de plane est compté pour le support
																				tempInfo = tempInfo .."\n"..tostring(draft.name).." ==? "..tostring(support.name)
																				if draft.name == support.name then
																					draft_availability[support.name].unassigned = draft_availability[support.name].unassigned - draft.number
																					tempInfo = tempInfo .."\n AtoG NbTotPlanePerTask AA "..supportTask.." ".._plane.." "..support.name.." Need "..draft.number.." Dispo: "..draft_availability[support.name].unassigned
																				end

																				draft_availability[support.name].unassigned = draft_availability[support.name].unassigned - support.number

																				tempInfo = tempInfo .."\n AtoG NbTotPlanePerTask BB "..supportTask.." ".._plane.." "..support.name.." Need "..support.number.." Dispo: "..draft_availability[support.name].unassigned

																				if draft_availability[support.name].unassigned >= 0 then
																					NbTotPlanePerTask = NbTotPlanePerTask + support.number

																					tempInfo = tempInfo .."\nAtoG NbTotPlanePerTask CC "..supportTask.." NbTotPlanePerTask: "..NbTotPlanePerTask
																				end
																			end
																		end
																	end
																end
																if taskRequireInSide and NbTotPlanePerTask < 2 and not draft.overRideMP_B then
																	support_available = false

																	tempInfo = tempInfo .."\nAtoG NbTotPlanePerTask REJETE CC "

																	local tabRejected = {}
																	tabRejected["sujet"]  = draft.id.." "..supportTask.." newTaskPerTarget  AVION TOTAL SUPPORT INSUFFISANT NbTotPlanePerTask <= 0 "
																	tabRejected["cause"] = { [1] = NbTotPlanePerTask, [2] = "newTaskPerTarget", }
																	tabRejected["ligne"]  = debug.getinfo(1).currentline
																	table.insert(draft["rejected"], tabRejected)
																end

																-- if Debug.Generator.affiche and string.find(Debug.Generator.chapter, "C")
																-- and ( Debug.Generator.SpySquad and Debug.Generator.SpySquad == draft.name
																-- or (Debug.Generator.SpyTarget and Debug.Generator.SpyTarget == draft.target_name ))
																-- then
																-- 	debuGenTxt = debuGenTxt.."\n"..tempInfo
																-- end

															end

															-- if supportTask == taskLearning then
															-- 	if type(supportPart) == "table" then	
															-- 		for _plane, support in pairs(supportPart) do

															-- 			if type(support) == "table" and not support.overRideMP_B then

															-- 				draft_availability[support.name].unassigned = draft_availability[support.name].unassigned - support.number

															-- 				if  draft_availability[support.name].unassigned >= 0 then 
															-- 					support_available = false

															-- 					local tabRejected = {}
															-- 					tabRejected["sujet"]  = draft.id.." "..supportTask.." type: "..support.type.." newTaskPerTarget  AVION SUPPORT INSUFFISANTsupport.number < unassigned "
															-- 					tabRejected["cause"] = { [1] = draft_availability[support.name].unassigned, [2] = "newTaskPerTarget", }
															-- 					tabRejected["ligne"]  = debug.getinfo(1).currentline														
															-- 					table.insert(draft["rejected"], tabRejected)

															-- 				end
															-- 			end
															-- 		end
															-- 	end
															-- end	
														end
													end
												end
											end
										end

										if isDebugModeC then
											debugLog(draft.id.." "..tempInfo)
										end

										--TODO bizarre, il s agit du nb d avion du main, pas du support
										-- if not draft.mainOverRideMP then
											for unitname,_ in pairs(need) do
												if need[unitname] > avail[unitname] then																						--more aircraft are needed from this unit across all package tasks than are available
													support_available = false																									--not enough support available
													local tabRejected = {}
													tabRejected["sujet"]  = draft.id.." type: "..draft.type.." AVION SUPPORT?Main? INSUFFISANT()support_available if need[unitname] > avail[unitname]"
													tabRejected["cause"] = { tostring(need[unitname]), tostring(avail[unitname]) }
													tabRejected["ligne"]  = debug.getinfo(1).currentline
													table.insert(draft["rejected"], tabRejected)
												end
											end
										-- end

										-- ATO_G_adjustment01 escort mandatory or not
										-- regarde uniquement pour les bombardiers necessitant une escorte

										-- if campMod.strikeOnlyWithEscorte and not draft.loadout.self_escort then
										-- 	if (db_loadouts[draft.type]["Anti-ship Strike"] or db_loadouts[draft.type]["Strike"])  then	
										-- 		local break_loop = false
										-- 		for n_squad, squad in pairs(oob_air[side]) do

										-- 			if Debug.Generator.affiche and string.find(Debug.Generator.chapter, "C") 
										-- 			and ( Debug.Generator.SpySquad and Debug.Generator.SpySquad == draft.name 
										-- 			or (Debug.Generator.SpyTarget and Debug.Generator.SpyTarget == draft.target_name ))
										-- 			then
										-- 				debuGenTxt = debuGenTxt.."\n"..(tostring(draft.id).." AtoG III passe SWE _01 "..draft.type.." "..squad.type ) 
										-- 			end

										-- 			if draft.mainOverRideMP or ((squad.tasks["Anti-ship Strike"]  or squad.tasks["Strike"] ) and squad.type == draft.type) then
										-- 				local needSupport = {}																														--collect the total number of aircraft needed from each unit to complete the package																							--number of main body aircraft 
										-- 				local availSupport = {}																													--collect the maximal number of available aircraft from this unit (biggest number of all tasks)

										-- 				if not needSupport[draft.name] then needSupport[draft.name] = 0 end
										-- 				if not availSupport[draft.name] then availSupport[draft.name] = 0 end
										-- 				needSupport[draft.name] =  Deepcopy(draft.number)	

										-- 				--TODO comment ça marche? ça a l'air inutile....
										-- 				availSupport[draft.name] =  AcftAvail[draft.name].unassigned

										-- 				for _p,_support in pairs(draft.support) do																							--iterate through support in draft sortie	
										-- 					if 	type(_support) == "table" then	
										-- 						for _a,support in pairs(_support) do											
										-- 							if 	type(support) == "table" then

										-- 								if not needSupport[support.name] then needSupport[support.name] = 0 end																															
										-- 								if not availSupport[support.name] then availSupport[support.name] = 0 end																

										-- 								needSupport[support.name] =  needSupport[support.name] + support.number																	--add number of support aircraft from same unit
										-- 								availSupport[support.name] =  AcftAvail[support.name].unassigned														

										-- 							end
										-- 						end
										-- 					end
										-- 				end		

										-- 				--TODO encore utile ça?												
										-- 				for Sname,_ in pairs(needSupport) do 
										-- 					-- print("AtoG NeedName"..Sname.." |Need| "..needSupport[Sname].." |dispo| "..availSupport[Sname])
										-- 					if needSupport[Sname] - (needSupport[Sname] * 0.25)  > availSupport[Sname] then	
										-- 					----more aircraft are needed from this unit across all package tasks than are available
										-- 						-- print("AtoG tabRejected: Necessaire: "..needSupport[Sname].." >  Dispo "..availSupport[Sname])
										-- 						support_available = false																									--not enough support available
										-- 							local tabRejected = {}
										-- 							tabRejected["sujet"]  = draft.id.." BOMBARDIER NECESSITANT ESCORTE()support_available if needSupport[Sname] - (needSupport[Sname] * 0.15) > availSupport[Sname]"
										-- 							tabRejected["cause"] = { [1] =  needSupport[Sname] - (needSupport[Sname] * 0.25), [2] = availSupport[Sname], }
										-- 							tabRejected["ligne"]  = debug.getinfo(1).currentline														
										-- 							table.insert(draft["rejected"], tabRejected)
										-- 					end
										-- 				end
										-- 			end
										-- 		end
										-- 	end	
										-- end


										-- s il n y a qu un avion d escorte, on bache la mission
										--obliger de regarder la demande total du package, par rapport aux existants

										local dispoTmp = Deepcopy(AcftAvail)

										--enleve deja l effectif du main (il peut y avoir 4 F18 strike et 2f18 sead ou escorte)
										dispoTmp[draft.name].unassigned = dispoTmp[draft.name].unassigned - draft.number

										for supportTask, supports in pairs(draft.support) do																							--iterate through support in draft sortie
											if support_available and type(supports) == "table" then
												for supportName, support in pairs(supports) do																							--iterate through support in draft sortie
													if 	type(support) == "table"  then --and support.name ~= nil	

														if support.number == nil or dispoTmp[support.name].unassigned == nil then
															print("AtoG bugA1 supportTask|"..supportTask.."|supportName:|"..tostring(supportName).."|"..tostring(support.name).." no unassigned "..tostring(support.number))
															if isDebugModeC then
																debugLog(draft.id.." AtoG bugA1 supportTask|"..supportTask.."|supportName:|"..tostring(supportName).."|"..tostring(support.name).." no unassigned "..tostring(support.number))
															end

															-- local test_str = "draft = " .. TableSerialization(draft, 0)						--make a string
															-- local testFile = io.open("Debug/draft_support__AtoG.lua", "w")								--open targetlist file
															-- testFile:write(test_str)															--save new data
															-- testFile:close()

														end


														--si c'est un task d'une demande MP, on chunte la restrition plus loin
														--TODO pourquoi le coef est plus important sur d'autre élément que lorsqu'on demande notre target?
														local MPOverride_C  = false
														if multiPlaneSet[side] and multiPlaneSet[side][draft.type] then
															MPOverride_C = true
														end

														if isDebugModeC then
															debugLog(draft.id.." AtoG passe C_00_h  we don't accept a single aircraft as escort supportTask "..supportTask.." draft.task "..tostring(draft.task))
														end

														if support.support_requirement and mission_ini.strikeOnlyWithEscorte and (support.number >= 2 and dispoTmp[support.name].unassigned < 2 and draft.task ~= supportTask) and not MPOverride_C then

															support_available = false																									--not enough support available

															local tabRejected = {}
															tabRejected["sujet"]  = support.id.." type: "..support.type.." we don't accept a single aircraft as escort "..supportName
															tabRejected["cause"] = { "support.number: ",support.number, "unassigned:" , tostring(dispoTmp[support.name].unassigned), " available: ", tostring(dispoTmp[support.name].aircraft_available), "supportName: ", tostring(supportName), " task: ", tostring(draft.task)  }
															tabRejected["ligne"]  = debug.getinfo(1).currentline
															table.insert(draft["rejected"], tabRejected)
														else
															dispoTmp[support.name].unassigned = dispoTmp[support.name].unassigned - support.number
														end

													end
												end
											end
										end

										if support_available and not draft.mainOverRideMP and mission_ini.strikeOnlyWithEscorte then

											local tracing = false
											local txtTracing = ""

											if isDebugModeC then
												debugLog(draft.id.." AtoG passe C_01_a  strikeOnlyWithEscorte number "..tostring(draft.number))
											end

											local tmpTxt = ""
											for _p,_support in pairs(draft.support) do																							--iterate through support in draft sortie
												tmpTxt = tmpTxt .."_A_ "

												if support_available and type(_support) == "table" then
													tmpTxt = tmpTxt .." _B_ "

													for supportName, support in pairs(_support) do																							--iterate through support in draft sortie
														tmpTxt = tmpTxt .." _C_supportName: "..tostring(supportName)

														if 	type(support) == "table" then
															tmpTxt = tmpTxt .." _D_support.number: "..tostring(support.number).." >? "..AcftAvail[support.name].unassigned

															if support.number > AcftAvail[support.name].unassigned then															--not enough aircraft available from this unit for this task
																tmpTxt = tmpTxt .." _E_ "
																if tracing then txtTracing = txtTracing .. "Passe 1E EJECT".."\n" end

																support_available = false																									--not enough support available

																local tabRejected = {}
																tabRejected["sujet"]  = support.id.." type: "..support.type.." (strikeOnlyWithEscorte) support_available if support.number > AcftAvail[support.name].unassigned "..supportName
																tabRejected["cause"] = { [1] =  support.number, [2] = AcftAvail[support.name].unassigned, }
																tabRejected["ligne"]  = debug.getinfo(1).currentline
																table.insert(draft["rejected"], tabRejected)

															end
														end
													end
												end
											end

											tmpTxt = tmpTxt .. "\n".."Passe 20 "..tostring(draft.type).." "..tostring(draft.target_name).."\n"

											--NON, ce qui suit est faux, il ne faut pas se limiter à ce que demande le loadout, mais ce limiter en fonction des menaces (thread)
											--si escorte obligatoire(pévu dans le loadout main) et qu'il n'y en a pas de prévu, on shunt
											-- if support_available and draft.loadout.support then																									--main body loadout support requirements

											-- 	for loadoutNeedTask, loadoutNeedTaskValue in pairs(draft.loadout.support) do																		--iterate through support requirements of loadout
											-- 		tmpTxt = tmpTxt .. "Passe 2B |||"..tostring(draft.loadout.name).."|||"..tostring(loadoutNeedTask).."||| Value: |||"..tostring(loadoutNeedTaskValue).."|||\n"

											-- 		if draft.loadout.support[loadoutNeedTask]   then
											-- 			tmpTxt = tmpTxt .. "Passe 2C ".."\n"

											-- 			local foundOnePlane = false
											-- 			for planeSupport, support in pairs(draft.support[loadoutNeedTask]) do
											-- 				tmpTxt = tmpTxt .. "Passe 2D "..tostring(planeSupport).."\n"

											-- 				if type(support) == "table" then
											-- 					tmpTxt = tmpTxt .. "Passe 2E ".."\n"

											-- 					if support.name  then
											-- 						tmpTxt = tmpTxt .. "Passe 2H "..tostring(support.name).."\n"

											-- 						foundOnePlane = true
											-- 					end
											-- 				end
											-- 			end

											-- 			if not foundOnePlane then
											-- 				tmpTxt = tmpTxt .. "Passe 2J EJECT".."\n"

											-- 				support_available = false																							--necessary support is not available

											-- 				local tabRejected = {}
											-- 				tabRejected["sujet"]  = draft.id.." type: ".." aucun SUPPORT "..tostring(loadoutNeedTask)
											-- 				tabRejected["cause"] = { [1] =  draft.support["support"], [2] = "", }
											-- 				tabRejected["ligne"]  = debug.getinfo(1).currentline
											-- 				table.insert(draft["rejected"], tabRejected)

											-- 				-- print("tmpTxt "..tmpTxt)
											-- 			end
											-- 		end
											-- 	end
											-- end


											for _p,_support in pairs(draft.support) do																							--iterate through support in draft sortie
												tmpTxt = tmpTxt .."_B1_"
												if support_available and type(_support) == "table" then
													tmpTxt = tmpTxt .."_B2_"
													for _,support in pairs(_support) do																							--iterate through support in draft sortie
														tmpTxt = tmpTxt .."_B3_"
															if 	type(support) == "table" then
															tmpTxt = tmpTxt .."_B4_"

															if AcftAvail[support.name].unassigned <=0 then
																tmpTxt = tmpTxt .."_B5_"

																if tracing then txtTracing = txtTracing .. "Passe 3E EJECT".."\n" end

																support_available = false

																local tabRejected = {}
																tabRejected["sujet"]  = draft.id.." type: "..support.type.." (strikeOnlyWithEscorte) AVION SUPPORT INSUFFISANT()support_available if AcftAvail[support.name].unassigned <=0"
																tabRejected["cause"] = { [1] = AcftAvail[support.name].unassigned, [2] = "", }
																tabRejected["ligne"]  = debug.getinfo(1).currentline
																table.insert(draft["rejected"], tabRejected)
															end
														end
													end
												end
											end

											if isDebugModeC then
												debugLog(draft.id.." AtoG passe C_01_a strikeOnlyWithEscorte"..txtTracing.."\n"..tmpTxt)
												debugLog(draft.id.." AtoG passe C_01_b strikeOnlyWithEscorte "..draft.type.." "..draft.task.." support_available: "..tostring(support_available) )
											end
										end

										--si c'est un task d'une demande MP, on chunte la restrition plus loin
										local MPOverride_C  = false
										if multiPlaneSet[side] and multiPlaneSet[side][draft.type] and multiPlaneSet[side][draft.type][draft.task]
											-- and support.number < AcftAvail[support.name].unassigned
										then
											MPOverride_C = true

											if isDebugModeC then
												debugLog(draft.id.." AtoG passe C_02a "..draft.type.." "..draft.task )
											end
										end


										if isDebugModeC then
											debugLog(draft.id.." AtoG passe C_02b serviceable: "
														..tostring(AcftAvail[draft.name].serviceable)
														.." |available: "..tostring(AcftAvail[draft.name].available)
														.." >? "..tostring(AcftAvail[draft.name].available / denom_NeDonnePasTOUT))
										end

										-- modification M11.u : Multiplayer	(u: reserve avion Escorte)
										-- interdit aux possible avion d'escorte de tout donner dans CAP ou Intercept

										if not MPOverride_C and (draft.task == "CAP" or draft.task == "Intercept" )   then

											for n_squad, squad in pairs(oob_air[side]) do
												if squad.type == draft.type and squad.name == draft.name and ((squad.tasks["Escort"] and squad.tasks["Escort"] == true)
												or  (squad.tasks["SEAD"] and squad.tasks["SEAD"] == true) or  (squad.tasks["Strike"] and squad.tasks["Strike"] == true)  )
												then

													local test_Aircraftnumber = Deepcopy(draft.number)
													local needeMindAircraft = false

													-- if AcftAvail[draft.name].unassigned - test_Aircraftnumber < 2 then
													-- 	test_Aircraftnumber = test_Aircraftnumber -2
													-- else
													-- 	test = true
													-- end
													if (AcftAvail[draft.name].unassigned - test_Aircraftnumber) >= (AcftAvail[draft.name].ready / 2) then
														-- test_Aircraftnumber = test_Aircraftnumber -2
														needeMindAircraft = true
														debuGenTxt = debuGenTxt.."\n".." AtoG passe C_03_0a unassigned: "..AcftAvail[draft.name].unassigned.." - "..test_Aircraftnumber.." ready: "..AcftAvail[draft.name].ready .." /2"
														debuGenTxt = debuGenTxt.."\n".." AtoG passe C_03_0b result: "..(AcftAvail[draft.name].unassigned - test_Aircraftnumber).." <= "..(AcftAvail[draft.name].ready / 2)

													elseif AcftAvail[draft.name].unassigned  > 0 then
														test_Aircraftnumber = math.floor(AcftAvail[draft.name].ready / 2)
														needeMindAircraft = true

													elseif AcftAvail[draft.name].unassigned  <= 0 then
														needeMindAircraft = false
													end

													draft.number = test_Aircraftnumber

													if not needeMindAircraft then
														support_available = false

														if Debug.Generator.affiche and string.find(Debug.Generator.chapter, "C")
														and ( Debug.Generator.SpySquad and Debug.Generator.SpySquad == draft.name
														or (Debug.Generator.SpyTarget and Debug.Generator.SpyTarget == draft.target_name ))
														then
															debuGenTxt = debuGenTxt.."\n"..(tostring(draft.id).." AtoG passe C_03  "..squad.type.." "..draft.task)
														end


														local tabRejected = {}
														tabRejected["sujet"]  = draft.id.." NE DONNE PAS TOUT en CAP ou Intercept ()support_available if AcftAvail[draft.name].unassigned - draft.number <= AcftAvail[draft.name].serviceable/3"
														tabRejected["cause"] = { " unassigned - draft.number: ", tostring(AcftAvail[draft.name].unassigned - draft.number), "serviceable/ denom_NeDonnePasTOUT: ", tostring(AcftAvail[draft.name].serviceable/ denom_NeDonnePasTOUT) }
														tabRejected["ligne"]  = debug.getinfo(1).currentline
														table.insert(draft["rejected"], tabRejected)

													end
												end
											end
										end

										-- ne donne pas tout aux strike si du sead est possible en task escadrille
										--bug avec de petite campagne comme le Tchad
										--TODO prevoir seulement si SEAD prévu, ou pas.
										-- if testCode then
										-- 	if not MPOverride_C and (draft.task == "Strike" or draft.task == "Anti-ship Strike" )   then	--and (AcftAvail[draft.name].serviceable > (AcftAvail[draft.name].available / 1.01 ))
										-- 		local break_loop = false
										-- 		for n_squad, squad in pairs(oob_air[side]) do
										-- 			if squad.type == draft.type and squad.name == draft.name and ( squad.tasks["Escort"] or squad.tasks["SEAD"] or squad.tasks["Laser Illumination"]   ) then --squad.tasks["Fighter Sweep"] or or squad.tasks["Fighter Sweep"]
										-- 				--AcftAvail[support.name].unassigned
										-- 				if AcftAvail[draft.name].unassigned - draft.number <= AcftAvail[draft.name].serviceable / 2 then
										-- 					support_available = false

										-- 					if Debug.Generator.affiche and string.find(Debug.Generator.chapter, "C") 
										-- 					and ( Debug.Generator.SpySquad and Debug.Generator.SpySquad == draft.name 
										-- 					or (Debug.Generator.SpyTarget and Debug.Generator.SpyTarget == draft.target_name ))
										-- 					then
										-- 						debuGenTxt = debuGenTxt.."\n"..(tostring(draft.id).." AtoG passe C_03  "..draft.type.." "..draft.task) 
										-- 					end
										-- 						local tabRejected = {}
										-- 						tabRejected["sujet"]  = draft.id.." NE DONNE PAS TOUT en Strike ()support_available if AcftAvail[draft.name].unassigned - draft.number <= AcftAvail[draft.name].serviceable/6"
										-- 						tabRejected["cause"] = { [1] = AcftAvail[draft.name].unassigned - draft.number, [2]  = AcftAvail[draft.name].serviceable/3, }
										-- 						tabRejected["ligne"]  = debug.getinfo(1).currentline														
										-- 						table.insert(draft["rejected"], tabRejected)	

										-- 					break_loop = true																		
										-- 					break
										-- 				end
										-- 			end
										-- 			if break_loop == true then
										-- 				break																							
										-- 			end
										-- 		end
										-- 	end
										-- end

										if isDebugModeC then
											debugLog(draft.id.." AtoG passe C_04  support_available "..tostring(support_available).." MPOverride_C: "..tostring(MPOverride_C))
										end

										--add new package to ATO
										if support_available  then																		--continue if no support is required or enough support is available to create package

											local pack_n = #ATO[side]

											ATO[side][pack_n + 1] = {
												["main"] = {},																			--package main body
												["Escort"] = {},																		--Fighter escort
												["SEAD"] = {},																			--SEAD escort
												["Escort Jammer"] = {},																	--jammer escort
												["Flare Illumination"] = {},															--illumination flare
												["Laser Illumination"] = {},															--laser illumination
												["Strike"] = {},
												["Anti-ship Strike"] = {},

											}
											pack_n = pack_n + 1




											--********************************************************************************************
											--********************************************************************************************
											--********************************AddFlight**********************************************
											--********************************************************************************************
											--********************************************************************************************

											--add flights of 1, 2 or 4 aircraft to package
											local function AddFlight(assign, role, entry)

												local assigned
												while assign > 0 do																		--loop as long as there are aircraft to assign

													local debugA = ""
													local debugE = ""

													if entry.flights then																--for multiple flights with station time (CAP, AWACS, Tanker etc.)
														local flightsize = math.ceil(draft.target.firepower.max / draft.loadout.firepower)	--how many aircraft should be in each flight
														debugA = "assign: "..assign.." >=? flightsize: "..flightsize
														if assign >= flightsize then													--if there are more aircraft left to assign than the size of one flight
															assigned = flightsize														--assign one full flight
															debugA = debugA .." ||if assign >= flightsize: assigned: "..assigned
														else																			--if there are less aircraft left to assign than size of one flight
															assigned = assign
															debugA = debugA .." ||else assigned: "..assigned												--assign whatever is left
														end

														if entry.task == "CAP" then
															if assigned < 2 then
																assigned = 2
															end
														end

														entry.flights = entry.flights - 1												--one less flight to assign

														debugA = debugA .." ||result entry.flights: "..entry.flights

													elseif  entry.task == "Escort Jammer" or entry.task == "Flare Illumination" or entry.task == "Laser Illumination" then		--for tasks with single aircraft
														assigned = 1																	--assign one aircraft per flight	
													elseif entry.task == "Transport" then
														if multiPlaneSet and multiPlaneSet[side] and multiPlaneSet[side][draft.type]  and multiPlaneSet[side][draft.type][entry.task] then
															assigned = assign
														else
															assigned = 1
														end

													elseif entry.task == "Intercept" then
														if assign >= 4 then																--if more than 2 aircraft are to be assigned
															assigned = 4																--assign flight of 2 aircaft
														-- if assign >= 2 then																--if more than 2 aircraft are to be assigned
														-- 	assigned = 2
														else
															assigned = 2																--else assign flight of 1 aicraft
														end
													-- elseif (entry.type == "S-3B" or entry.type == "F-117A" or entry.type == "B-1B" or entry.type == "B-52H" or entry.type == "Tu-22M3" or entry.type == "Tu-95MS" or entry.type == "Tu-142" or entry.type == "Tu-160" or entry.type == "MiG-25RBT")
													-- and entry.task ~= "Runway Attack" then	--for bombers	
													elseif (Data_divers[entry.type] and Data_divers[entry.type].flyingAlone) and entry.task ~= "Runway Attack" then	--for bombers
														assigned = 1																	--assigne one aircraft per flight
													elseif entry.task == "Reconnaissance" then											--for recon
														if assign == 1 then																--if there is one aircraft left to assign
															assigned = 1																--assigne one aircraft per flight
														elseif assign >= 4 then															--if more than 4 aircraft are to be assigned
															assigned = 4																--assign flight of 4 aircaft
														elseif assign == 3 then															--if more than 3 aircraft are to be assigned
															assigned = 3																--assign flight of 3 aircaft
														else
															assigned = 2																--else assign flight of 2 aicraft
														end
													elseif (entry.task == "SAR" or entry.task == "CSAR") and not MPOverride_C then											--for recon
														assigned = 1
													else																			--for everything else
														debugE = "else BEFORE assigned: if assigned and assign == 1? "..assign

														if assigned and assign == 1 then												--if there is one aircraft left to assign and there was already a previous flight assigned, stop assigning (do not add leftover single-ships)
															break
														elseif assign >= 4 then															--if more than 4 aircraft are to be assigned
															assigned = 4																--assign flight of 4 aircaft
															debugE = debugE .." || elseif assign >= 4 then"
															else
															assigned = assign															--else assign flight size of what is left
														end
														debugE = debugE .. " || elseAFTER assigned: "..assigned
													end

													-- if assign >= 4 then															--if more than 4 aircraft are to be assigned
													-- 	assigned = 4																--assign flight of 4 aircaft
													-- else
													-- 	assigned = assign															--else assign flight size of what is left
													-- end

													if isDebugModeC then
														debugLog(draft.id.." AtoG passe C_04a   _A_" ..debugA.." \r\n _E_ "..debugE.." \r\n assigned "..assigned)
													end

													local flight = {																	--build ATO flight entry
														name = entry.name,
														playable = entry.playable,
														type = entry.type,
														modification = entry.modification,
														callsign = entry.callsign,
														callsignId = entry.callsignId,
														helicopter = entry.helicopter,
														number = assigned,																--number of aircraft in flight
														country = entry.country,
														livery = entry.livery,
														sidenumber = entry.sidenumber,
														liveryModex = entry.liveryModex,
														base = entry.base,
														airdromeId = entry.airdromeId,
														parking_id = entry.parking_id,
														skill = entry.skill,
														task = entry.task,
														loadout = entry.loadout,
														route = {},																		--route is a table and connot be copied as a whole
														target = Deepcopy(entry.target),
														target_name = entry.target_name,
														firepower = assigned * entry.loadout.firepower,
														tot_from = entry.tot_from,
														tot_to = entry.tot_to,
														id = entry.id,
														score= draft.score,
														threatsGround = draft.threatsGround,
														threatsAir = draft.threatsAir,
													}
													for r = 1, #entry.route do															--make copy of route table
														flight.route[r] = {}
														for k,v in pairs(entry.route[r]) do
															flight.route[r][k] = v
														end
													end


													if isDebugModeC then
														debugLog(draft.id.." AtoG passe C_05a number "..assigned.." "..entry.task)
													end


													if multiPlaneSet and multiPlaneSet[side] and multiPlaneSet[side][draft.type]  and multiPlaneSet[side][draft.type][draft.task]  then

														multiPlaneSet[side][draft.type][draft.task].NbPlane = multiPlaneSet[side][draft.type][draft.task].NbPlane - assigned

														if isDebugModeC then
															debugLog(draft.id.." AtoG passe C_05b (NbPlane - assigned) "..multiPlaneSet[side][draft.type][draft.task].NbPlane)
														end
													end
			--######################################################################################################################################
			--######################################################################################################################################

			--######################################################################################################################################
			--#############"" insert/create ATO table ##############################################################################################

													table.insert(ATO[side][pack_n][role], flight)										--add flight to package role (main, SEAD or escort)											


													-- for prioriyN, testTargets in pairs(targetNamePrio[side]) do
													-- 	for i, testTarget in pairs(testTargets) do
													-- 		if testTarget.name == entry.target_name then
													-- 			testTarget.check = true
													-- 			print("AtoG BB   ?               __checked__: "..tostring(testTarget.name))
													-- 			break
													-- 		end
													-- 	end
													-- end

													-- table.insert(newDraftByPriority[sidePrio], draft)


			--#############"" insert/create ATO table ##############################################################################################
			--######################################################################################################################################

			--######################################################################################################################################
			--######################################################################################################################################
													-- --store time assigned aircraft are unavailable for future missions
													-- local operating_hours														--time the unit is operating each day
													-- if entry.loadout.day and entry.loadout.night then							--day/night loadout
													-- 	operating_hours = 86400													--full day in seconds
													-- elseif entry.loadout.day then												--day loadout
													-- 	operating_hours = mission_ini.dusk - mission_ini.dawn									--Daytime in seconds
													-- elseif entry.loadout.night then												--night loadout
													-- 	operating_hours = mission_ini.dawn + (86400 - mission_ini.dusk)						--nighttime in seconds
													-- end
													-- local time_to_next_mission = operating_hours / entry.loadout.sortie_rate	--time duration until aircraft can do the next mission based on its sortie rate
													-- if entry.loadout.tStation and #ATO[side][pack_n][role] == 1 then			--for a flight that has a station time and for the first flight in package
													-- 	time_to_next_mission = time_to_next_mission - entry.loadout.tStation	--remove station time from time to next mission, because flight could airstart current mission at close to end of its station time
													-- end

													--boucle transféré a la fin de ATO_Timing
													-- if daysfrom > AcftAvail[unit.name].unavailable[u] then
													-- local unavailable = current_time + time_to_next_mission 					--campaign time until this aircraft unavailable for new mission
													-- local unavailable = daysfrom + (time_to_next_mission / (24 * 60 * 60))		-- seconds in a day

													-- for a = 1, assigned do														--iterate through all assigned aircraft
													-- 	if #AcftAvail[entry.name].unavailable == 0 then
													-- 		table.insert(AcftAvail[entry.name].unavailable, unavailable)						--insert unavailable time into unavailable table of this unit
													-- 	else
													-- 		for u = 1, #AcftAvail[entry.name].unavailable do
													-- 			if unavailable > AcftAvail[entry.name].unavailable[u] then
													-- 				table.insert(AcftAvail[entry.name].unavailable, u, unavailable)				--insert unavailable time into unavailable table of this unit sorted from highest to lowest
													-- 				break
													-- 			elseif u == #AcftAvail[entry.name].unavailable then
													-- 				table.insert(AcftAvail[entry.name].unavailable, u + 1, unavailable)			--insert unavailable time into unavailable table of this unit sorted from highest to lowest
													-- 			end
													-- 		end
													-- 	end
													-- end

													AcftAvail[entry.name].assigned = AcftAvail[entry.name].assigned + assigned
													AcftAvail[entry.name].unassigned = AcftAvail[entry.name].unassigned - assigned		--remove assigned aircraft from total number of available aircraft for this unit
													assign = assign - assigned															--continue loop until are aircraft are assigned

													if isDebugModeC then
														debugLog(draft.id.." AtoG passe C_05b   assign "..assign.." type: "..entry.type.." unassigned: "..AcftAvail[entry.name].unassigned)
													end

												end
											end

											if isDebugModeC then
												debugLog(draft.id.." AtoG passe C_06b  |AddFlight MAIN| number "..tostring(draft.number))
											end

											--********************************************************************************************
											AddFlight(draft.number, "main", draft)												--add main body flights to package
											--********************************************************************************************

											for support_name, supportPart in pairs(draft.support) do										--iterate through all package support
												if type(supportPart) == "table" then
													for _plane, support in pairs(supportPart) do
														local number  = 0
														if type(support) == "table" and support.name  then

															if support.number >= AcftAvail[support.name].unassigned then
																number = AcftAvail[support.name].unassigned
															end
															if support.number < AcftAvail[support.name].unassigned then
																number = support.number
															end

															if support.overRideMP_B then number = support.number end

															if isDebugModeC then
																debugLog(draft.id.." AtoG passe C_07  |AddFlight SUPPORT| numberFINAL "..tostring(number).." support_name: "..support_name.." unassigned: "..tostring(AcftAvail[support.name].unassigned))
															end

															--********************************************************************************************
															AddFlight(number, support_name, support)										--add support flights to package
															--********************************************************************************************

														else
															-- if type(support) ~= "table" then
															-- 	txt0 = "support != table "
															-- 		.." OveRide?: "..tostring(draft.mainOverRideMP)
															-- 		.." type: "..tostring(draft.type)
															-- 		.." key: "..tostring(_plane)
															-- 		.." supportPart(_plane): "..tostring(supportPart[_plane]) 
															-- 		.." support: "..tostring(support) 
															-- 		.." supportPart: "..tostring(supportPart) 
															-- 		.." || "

															-- 		if Debug.Generator.affiche and string.find(Debug.Generator.chapter, "C") 
															-- 		and ( Debug.Generator.SpySquad and Debug.Generator.SpySquad == draft.name 
															-- 		or (Debug.Generator.SpyTarget and Debug.Generator.SpyTarget == draft.target_name ))
															-- 		then
															-- 			debuGenTxt = debuGenTxt.."\n"..(tostring(draft.id).." AtoG passe C_08")
															-- 			debuGenTxt = debuGenTxt.."\n"..(txt0)
															-- 			-- _affiche(supportPart, "supportPart")
															-- 		end	



															-- txt0 = draft.id.." IN AddFlight: type(support) ~= table or support_name "
															-- 	.." OveRide?: "..tostring(draft.mainOverRideMP)
															-- 	.." "..tostring(draft.type) 
															-- 	.." support_name: "..tostring(support_name)
															-- 	-- .."\n".. TableSerialization(draft.loadout, 0)  



															-- local tabRejected = {}
															-- tabRejected["sujet"]  = txt0
															-- tabRejected["cause"] = { [1] = support_available, [2]  = "", }
															-- tabRejected["ligne"]  = debug.getinfo(1).currentline
															-- table.insert(draft["rejected"], tabRejected)

														end
													end
												else
													local tabRejected = {}
													tabRejected["sujet"]  = draft.id.." IN AddFlight type(supportPart) == table"
													tabRejected["cause"] = { "support_available: ", tostring(support_available) }
													tabRejected["ligne"]  = debug.getinfo(1).currentline
													table.insert(draft["rejected"], tabRejected)
												end
											end

											--remove the firepower applied by package to target from maximum firepower of all other draft sorties to the same target
											local firepower_applied = 0																	--collect the amount of firepower combined by all main body flights of this package
											for f = 1, #ATO[side][pack_n].main do														--iterate through all main body flights
												firepower_applied = firepower_applied + ATO[side][pack_n].main[f].firepower				--sum firepower
											end
											-- for allSide, allDrafts in pairs(Draft_sorties) do
											-- -- for m = 1, #draft do
											-- 	for allN, allDraft in pairs(allDrafts) do																		--iterate through all draft sorties again
											-- 		-- print("AtoG AA draft.target_name: "..draft.target_name.." allDraft "..allDraft.target_name)
											-- 		if draft.target_name == allDraft.target_name then									--if draft sortie with same target as present package is found
											-- 			print("AtoG   --> BB "..tostring(allDraft.multipack).." "..tostring(draft.target_name))

											-- 			if allDraft.multipack then															--target has a fixed requirement for number of packages 
											-- 				allDraft.multipack = allDraft.multipack - 1										--reduce number of packages per one
											-- 				if allDraft.target.firepower.packmin then											--target has a fixed requirement for minimal number of packages 
											-- 					allDraft.target.firepower.packmin = allDraft.target.firepower.packmin - 1		--reduce number of minimal packages per one
											-- 				end
											-- 			else																				--target is stricly firepower controlled
											-- 				allDraft.target.firepower.max = allDraft.target.firepower.max - firepower_applied	--remove the firepower applied by current package from maximum firepower for this sortie
											-- 				allDraft.number = math.ceil(allDraft.number - (firepower_applied / allDraft.loadout.firepower))	--reduce the number of aircraf to be assigned to this sortie as a result of the firepower reduction
											-- 			end
											-- 		end
											-- 	end
											-- end

											if multipackByTargetName[draft.target_name] then
												multipackByTargetName[draft.target_name] = multipackByTargetName[draft.target_name] -1
											end

											--status report
											status_counter_ATO = status_counter_ATO + 1
											--print("ATO Generation (" .. status_counter_ATO .. ")")	--DEBUG
										else
											local tabRejected = {}
											tabRejected["sujet"]  = draft.id.." SUPPORT IMPOSSIBLE()if support_available"
											tabRejected["cause"] = { "support_available: ", tostring(support_available) }
											tabRejected["ligne"]  = debug.getinfo(1).currentline
											table.insert(draft["rejected"], tabRejected)
										end
									else
										local tabRejected = {}
										tabRejected["sujet"]  = draft.id.." AVIONS INSUFFISANT()if draft.number <= available and limitMP then {draft.number, limitMP}"
										tabRejected["cause"] = {"draft.number: ", tostring(draft.number), "limitMP: ", tostring(limitMP)}
										tabRejected["ligne"]  = debug.getinfo(1).currentline
										table.insert(draft["rejected"], tabRejected)
									end
								else
									--if draft.target.firepower.packmin == nil or available * draft.loadout.firepower >= (draft.target.firepower.packmin - 1) * draft.target.firepower.max + draft.target.firepower.min
									local tabRejected = {}
									tabRejected["sujet"]  = draft.id.." FIREPOWER du PACKAGE INSUFFISANT()if  available * draft.loadout.firepower >= (draft.target.firepower.packmin - 1) * draft.target.firepower.max"
									tabRejected["cause"] = { [1] = tostring(available * draft.loadout.firepower), [2]  = tostring((draft.target.firepower.packmin - 1) * draft.target.firepower.max), }
									tabRejected["ligne"]  = debug.getinfo(1).currentline
									table.insert(draft["rejected"], tabRejected)
								end
							else
								local tabRejected = {}
								tabRejected["sujet"]  = draft.id.." "..tostring(draft.type).." AVION DISPONIBLE INSUFFISANT "..tostring(draft.name).." available: "..tostring(available).." draft.loadout.firepower: "..tostring(draft.loadout.firepower.." firepowerMin: "..tostring(draft.target.firepower.min))
								tabRejected["cause"] = { [1] = tostring(available * draft.loadout.firepower), [2]  = tostring(draft.target.firepower.min), }
								tabRejected["ligne"]  = debug.getinfo(1).currentline
								table.insert(draft["rejected"], tabRejected)
							end
						else
							local tabRejected = {}
							tabRejected["sujet"]  = draft.id.." FIREPOWER INSUFFISANT (a augmenter dans loadout)if draft.target.firepower.max > 0 and draft.target.firepower.max >= draft.target.firepower.min"
							tabRejected["cause"] = { [1] = tostring(draft.target.firepower.max), [2]  = tostring(draft.target.firepower.max), }
							tabRejected["ligne"]  = debug.getinfo(1).currentline
							table.insert(draft["rejected"], tabRejected)
						end
					else
						local tabRejected = {}
						tabRejected["sujet"]  = draft.id.." MultiPACKAGE A 0 (?)if draft.multipack == nil or draft.multipack > 0 || target_name: "..tostring(draft.target_name).." || multipack: " ..tostring(draft.multipack)
						tabRejected["cause"] = { [1] = tostring(draft.multipack), [2]  = tostring(draft.multipack), }
						tabRejected["ligne"]  = debug.getinfo(1).currentline
						table.insert(draft["rejected"], tabRejected)
					end
				else
					local tabRejected = {}
					tabRejected["sujet"]  = draft.id.." MENACE TROP IMPORTANTE (descendre minscore ou diminuer Menace AA AS) draft.loadout.minscore <= draft.score"
					tabRejected["cause"] = { [1] = tostring(draft.loadout.minscore), [2]  = tostring(draft.score), }
					tabRejected["ligne"]  = debug.getinfo(1).currentline
					table.insert(draft["rejected"], tabRejected)
				end
			end
		end
	end
end



-- _affiche(Draft_sorties.blue[1], "Draft_sorties.blue[1]")
-- _affiche(Draft_sorties.red[1], "Draft_sorties.red[1]")

local function showAtoSort(newDraftByPriority, tablePrio)

	local showSquad
	local showTarget

	if Debug.Generator.SpySquad then
		showSquad = Debug.Generator.SpySquad
	end
	if Debug.Generator.SpyTarget  then
		showTarget = Debug.Generator.SpyTarget
	end


	-- local showSquad = "111.Filo"

	for side, sorties in pairs(newDraftByPriority) do
		local di = 1
		debugLog(side.." PART C ")

		for draft_n, draft in pairs(sorties) do
			local nameOK = false
			if draft.target_name == showTarget then
				nameOK = true
			end
			for _planeTask, PlaneTask in pairs(draft.support) do
				for taskName, task in pairs(PlaneTask) do
					if type(task) == "table" then
						if task.name == showSquad  then
							nameOK = true
						end
					end
				end
			end

			if di < Debug.Generator.nb or draft.name == showSquad or nameOK  then
				debugLog("")
				debugLog("/n"..	side.." tablePrio: "..tablePrio.." C N° " .. draft_n..
						-- " /support/ " ..tostring(draft.support)..
						" /Id" ..tostring(draft.id)..
						" /Prioriry/ " ..tostring(draft.priorityIni)..
						" /name/ " ..draft.name..
						" /Nb/ " ..draft.number..
						" /Type/ "..draft.type..
						" /Tot_to/ "..draft.tot_to ..
						" /threatsGround/ "..round(draft.threatsGround)..
						" /threatsAir/ "..round(draft.threatsAir)..
						" /Score/ " ..round(draft.score)..
						" /Task/ "..draft.task..
						" /Target/ "..tostring(draft.target_name)..
						" /LoadName/ "..tostring(draft.loadout.name)
						)
				di = di +1
				for _planeTask, PlaneTask in pairs(draft.support) do
					for taskName, task in pairs(PlaneTask) do
						if type(task) == "table" and task.target_name and task.loadout then
							debugLog(	"    ---> Nsupport " .._planeTask.." ".. taskName..
									" /Id" ..tostring(task.id)..
									" /name/ " ..task.name..
									" /Nb/ " ..task.number..
									" /escort_max/ " ..tostring(PlaneTask.escort_max)..
									" /SupportName/ "..task.name..
									" /Type/ "..task.type..
									" /Task/ "..task.task..
									" /NbTotSupt/ " ..tostring(task.NbTotalSupport)..
									" /Target/ "..task.target_name..
									" /LoadName/ "..tostring(task.loadout.name)
									)
						end
					end
				end
				if draft.rejected then
					for id, _rejected in pairs(draft.rejected) do

						--ecrit les causes:
						local causeTxt = ""
						for causeN, cause_ in ipairs(_rejected.cause) do
							causeTxt = causeTxt .. " |#"..causeN.."->| "..tostring(cause_)
						end
						debugLog(	" - - ----> rejected/ ".._rejected.sujet..
							" / cause " ..causeTxt..
							" / ligne " ..tostring(_rejected.ligne)
							)
					end
				end

			end
		end
	end
end

if #Draft_sorties.blue == 0 then
	print("AtoG ERROR no route could be generated in blue camp? ")
elseif #Draft_sorties.red == 0 then
	print("AtoG ERROR no route could be generated in red camp? ")
end

--creation de la table multipack (systeme cassé a cause du decoupage draft_sortie en plusieurs morceau/priorité)
multipackByTargetName = {}
for side, drafts in pairs(Draft_sorties) do
	for draftN, draft in ipairs(drafts)do
		if not multipackByTargetName[draft.target_name] then  multipackByTargetName[draft.target_name] = 0 end

		if multipackByTargetName[draft.target_name] < draft.multipack then
			multipackByTargetName[draft.target_name] = draft.multipack
		end
	end
end


-- local priorityRef = {
-- 	blue =0,
-- 	red = 0,
-- }
-- local newDraftByPriority = {
-- 	blue = {},
-- 	red = {},
-- }

-- --creation du targetlist par ordre de priorité
-- local targetListPrio = {
-- 	blue = {},
-- 	red = {},
-- }
-- local targetListPrioCheck = {
-- 	blue = {},
-- 	red = {},
-- }
-- local targetNamePrio = {
-- 	blue = {},
-- 	red = {},
-- }
for targetSide, targets in pairs(targetlist) do
	for targetN, target in pairs(targets) do
		if not target.inactive and target.ATO  then  --and (target.task == "Strike" or  target.task == "Anti-ship Strike" or target.task == "Runway Attack")

			--util pour eviter de cibler les memes target
			if not targetNamePrio[targetSide][target.priority] then targetNamePrio[targetSide][target.priority] = {} end
			local tempValue = {
				name = target.titleName,
				check = false,
				priority = target.priority,
			}
			table.insert(targetNamePrio[targetSide][target.priority], tempValue)

			--necessaire pour trier par ordre de priorité
			if not targetListPrioCheck[targetSide][target.priority] then
				table.insert(targetListPrio[targetSide], target.priority)
				targetListPrioCheck[targetSide][target.priority] = true
			end

			if priorityRef[targetSide] < target.priority  then
				priorityRef[targetSide] = target.priority
			end
		end
	end
end

table.sort(targetListPrio["blue"], function(a,b) return a > b  end)
table.sort(targetListPrio["red"], function(a,b) return a > b  end)


for sidePrio, tableauPrio in pairs(targetListPrio) do
	for tableN, tablePrio in pairs(tableauPrio) do
		for draftN, draft in pairs(Draft_sorties[sidePrio]) do
			if draft.priorityIni == tablePrio then
				table.insert(newDraftByPriority[sidePrio], draft)
			end

		end

		table.sort(newDraftByPriority[sidePrio], function(a,b) return a.score > b.score  end)

		createATO_table(newDraftByPriority)

		if Debug.Generator.affiche and newDraftByPriority ~= nil then
			debugLog("\n"..debuGenTxt.." \n Side: "..sidePrio.."  tablePrio "..tostring(tablePrio).."\n")
			showAtoSort(newDraftByPriority, tablePrio)
		end

		newDraftByPriority = {
			blue = {},
			red = {},
		}
	end
end


--calcul le nb d'avion en tout
-- local nbAfterPlaneActifTotal = {
-- 	blue = {
-- 		ready = 0,
-- 		reserve = 0
-- 	},
-- 	red = {
-- 		ready = 0,
-- 		reserve = 0
-- 	},
-- }
-- for side, packages in pairs(ATO) do								
-- 	for packN, pack in pairs(packages) do
-- 		for task, flights in pairs(pack) do
-- 			for task, flights in pairs(pack) do




--remet la valeur de priority correct, si elle avait été changée par un choix multijoueur
-- for kGroupN, multiGroup in pairs(Multi.Group) do
for targetSide, targets in pairs(targetlist) do
	for targetN, target in pairs(targets) do
		if  target.priorityINIT  then
			target.priority = Deepcopy(target.priorityINIT)
			target.priorityINIT = nil
		end
	end
end


local show = true

if Debug.debug then

	for side, packages in pairs(ATO) do
		for packN, pack in pairs(packages) do
			for role, flights in pairs(pack) do
				for flightN, flight in pairs(flights) do

					checkNbPlane[side]["thisMission"].used = checkNbPlane[side]["thisMission"].used + flight.number

				end
			end
		end
	end

	_affiche(checkNbPlane, "checkNbPlane: ")


	local resultPourcent =  checkNbPlane.blue.thisMission.used / checkNbPlane.blue.beforMission.ready * 100

	local resultPourcent2 =  checkNbPlane.blue.thisMission.used / (checkNbPlane.blue.beforMission.ready - checkNbPlane.blue.beforMission.alreadyInFlight) * 100
	print("AtoG caution 2, not enough BLUE aircraft used compared to available aircraft. Maybe a bug? "..resultPourcent2.." %")

	if resultPourcent < 75 then
		print("AtoG caution, not enough BLUE aircraft used compared to available aircraft. Maybe a bug? "..resultPourcent.." %")
		show = true
	end

	resultPourcent =  checkNbPlane.red.thisMission.used / checkNbPlane.red.beforMission.ready * 100
	local resultPourcent2 =  checkNbPlane.red.thisMission.used / (checkNbPlane.red.beforMission.ready - checkNbPlane.red.beforMission.alreadyInFlight) * 100
	print("AtoG caution 2, not enough RED aircraft used compared to available aircraft. Maybe a bug? "..resultPourcent2.." %")

	if resultPourcent < 75 then
		print("AtoG caution, not enough RED aircraft used compared to available aircraft. Maybe a bug? "..resultPourcent.." %")
		show = true
	end





	-- if camp.Aircraft_availability then
	-- 	for squadName, squad in pairs(camp.Aircraft_availability) do
	-- 		if squad then
	-- 			if squad.unavailable then
	-- 				local squadSide = FoundSquadSide(squadName)
	-- 				if squadSide then

	-- 					checkNbPlane[squadSide]["beforMission"].alreadyInFlight = checkNbPlane[squadSide]["beforMission"].alreadyInFlight + #squad.unavailable
	-- 				else
	-- 					print("AtoG strange, squad.unavailable on this squad ")
	-- 					_affiche(squad, "squad")
	-- 					if Debug.debug then
	-- 					end

	-- 				end
	-- 			end
	-- 		end
	-- 	end
	-- end



	for side, units in pairs(oob_air) do
		for unitN, unit in pairs(units) do
			if not unit.inactive or unit.inactive == nil then
				if AcftAvail[unit.name] then
					local campSquad = Deepcopy(AcftAvail[unit.name])
					local pourcent = campSquad.assigned / campSquad.ready * 100

					if pourcent <= 25 then
						print("AtoG caution, low available unassigned aircraft. Maybe a bug? "..unit.type.." : "..pourcent.." %: "..unit.name)
						_affiche(campSquad, "squad ")
						print()
					end
				else

				end
			end
		end
	end

	if show then os.execute 'pause'
	end

end



if Debug.debug and Debug.Generator.affiche and string.find(Debug.Generator.chapter, "C") then

	local camp_str = "ATO = " .. TableSerialization(ATO, 0)
	local campFile = io.open("Debug/ATO_AtoGenerator.lua", "w")
	if campFile then
		campFile:write(camp_str)
		campFile:close()
	end

	local camp_str = "camp = " .. TableSerialization(camp, 0)
	local campFile = io.open("Debug/CAMP_Ato_Generator.lua", "w")
	if campFile then
		campFile:write(camp_str)
		campFile:close()
	end
end

--place la clef occurence à tous les loadouts
Loadouts_archive = Loadouts_archive or {}
for plane, planeTab  in pairs(Loadouts_archive) do
	for taskName, loadout  in pairs(planeTab) do
		for loadoutName, value  in pairs(loadout) do
			if type(value) == "table" then
				if not value["occurence"] then value["occurence"] = 0 end
			end
		end
	end
end


-- modification M49.c big central db_loadout (c: loadout statistics)
local found = false
for side, pack in pairs(ATO) do
	for p = 1, #pack do
		for role,flight in pairs(pack[p]) do
			for f = 1, #flight do
				local found = false
				for plane, planeTab  in pairs(Loadouts_archive) do
					if plane == flight[f].type then
						for taskName, loadout  in pairs(planeTab) do
							for loadoutName, value  in pairs(loadout) do
								if loadoutName  == flight[f].loadout.name then
									if not value["occurence"] or value["occurence"] == nil or value["occurence"] == " " then value["occurence"] = 0 end
									value["occurence"] = value["occurence"] + 1
									found = true
									break
								end
								if found then break end
							end
							if found then break end
						end
						if found then break end
					end
					if found then break end
				end
			end
		end
	end
end


local s = ""
--place la clef occurence à tous les loadouts
for plane, planeTab  in pairs(Loadouts_archive) do
	for taskName, loadout  in pairs(planeTab) do
		for loadoutName, value  in pairs(loadout) do
			if type(value) == "table" then
				s = s.."\n"
				s = s..plane
				for i=1, 15 - string.len(plane) do
					s = s.." "
				end

				s = s..taskName
				for i=1, 20 - string.len(taskName) do
					s = s.." "
				end

				if value.occurence == 0 then
					value.occurence = " "
				end
				s = s..value.occurence
				for i=1, 5 - string.len(value.occurence) do
					s = s.." "
				end

				local minsCore = ""
				if value.minscore then minsCore = value.minscore end

				s = s..minsCore
				for i=1, 5 - string.len(minsCore) do
					s = s.." "
				end

				s = s..loadoutName
			end
		end
	end
end

if Debug.Generator and Debug.debug then
	local _file = io.open("Debug/AtoGenerator_Debug.txt", "w") or error("Failed to open debug file")
	_file:write(debuGenTxt)
	_file:close()

	local _str = "debugLogs = " .. TableSerializationAG_triggers(debugLogs, 0)
	_file = io.open("Debug/AtoGenerator_Debug_B.lua", "w") or error("Échec d'ouverture du fichier AtoGenerator_Debug_B")
	_file:write(_str)
	_file:close()

end

if Debug.debug then
	local camp_str = "ATO_ATO_PA = " .. TableSerialization(ATO, 0)
	local campFile = io.open("Debug/ATO_AtoG.lua", "w") or error("Échec d'ouverture du fichier ATO_AtoG")
	campFile:write(camp_str)
	campFile:close()
end

--*****************ne pas effacer commenter**********************	
local loadoutSTR = StringToTxt(s)
local dloadoutFile = io.open("Active/loadout_stats.lua", "w") or error("Failed to open debug file")
dloadoutFile:write(loadoutSTR)
dloadoutFile:close()
--***************ne pas effacer commenter	**************************



