mission = 
{
    ["trig"] = 
    {
        ["actions"] = 
        {
            [1] = "a_do_script(\"dcsCommon = {}\\\
dcsCommon.version = \\\"2.5.6\\\"\\\
--[[-- VERSION HISTORY\\\
 2.2.6 - compassPositionOfARelativeToB\\\
       - clockPositionOfARelativeToB\\\
 2.2.7 - isTroopCarrier \\\
       - distFlat\\\
 2.2.8 - fixed event2text \\\
 2.2.9 - getUnitAGL\\\
       - getUnitAlt\\\
       - getUnitSpeed \\\
       - getUnitHeading\\\
       - getUnitHeadingDegrees\\\
       - mag\\\
       - clockPositionOfARelativeToB with own heading \\\
 2.3.0 - unitIsInfantry\\\
 2.3.1 - bool2YesNo\\\
       - bool2Text\\\
 2.3.2 - getGroupAvgSpeed\\\
       - getGroupMaxSpeed\\\
 2.3.3 - getSizeOfTable\\\
 2.3.4 - isSceneryObject\\\
         coalition2county\\\
 2.3.5 - smallRandom\\\
         pickRandom uses smallRandom\\\
         airfield handling, parking \\\
         flight waypoint handling\\\
         landing waypoint creation\\\
         take-off waypoint creation\\\
 2.3.6 - createOverheadAirdromeRoutPintData(aerodrome)\\\
 2.3.7 - coalition2county - warning when creating UN \\\
 2.3.8 - improved headingOfBInDegrees, new getClockDirection\\\
 2.3.9 - getClosingVelocity\\\
       - dot product \\\
       - magSquare\\\
       - vMag\\\
 2.4.0 - libCheck\\\
 2.4.1 - grid/square/rect formation \\\
       - arrangeGroupInNColumns formation \\\
       - 2Columns formation deep and wide formation\\\
 2.4.2 - getAirbasesInRangeOfPoint\\\
 2.4.3 - lerp \\\
 2.4.4 - getClosestAirbaseTo\\\
       - fixed bug in containsString when strings equal\\\
 2.4.5 - added cargo and mass options to createStaticObjectData\\\
 2.4.6 - fixed randompercent \\\
 2.4.7 - smokeColor2Num(smokeColor)\\\
 2.4.8 - linkStaticDataToUnit()\\\
 2.4.9 - trim functions \\\
       - createGroundUnitData uses trim function to remove leading/trailing blanks\\\
         so now we can use blanks after comma to separate types \\\
       - dcsCommon.trimArray(\\\
       - createStaticObjectData uses trim for type \\\
       - getEnemyCoalitionFor understands strings, still returns number\\\
       - coalition2county also undertsands 'red' and 'blue'\\\
 2.5.0 - \\\"Line\\\" formation with one unit places unit at center     \\\
 2.5.1 - vNorm(a)  \\\
 2.5.1 - added SA-18 Igla manpad to unitIsInfantry()\\\
 2.5.2 - added copyArray method\\\
       - corrected heading in createStaticObjectData\\\
 2.5.3 - corrected rotateGroupData bug for cz \\\
       - removed forced error in failed pickRandom\\\
 2.5.4 - rotateUnitData()\\\
       - randomBetween()\\\
 2.5.5 - stringStartsWithDigit()\\\
       - stringStartsWithLetter()\\\
       - stringIsPositiveNumber()\\\
 2.5.6 - corrected stringEndsWith() bug with str\\\
       \\\
--]]--\\\
\\\
    -- dcsCommon is a library of common lua functions \\\
    -- for easy access and simple mission programming\\\
    -- (c) 2021, 2022 by Chritian Franz and cf/x AG\\\
\\\
    dcsCommon.verbose = false -- set to true to see debug messages. Lots of them\\\
    dcsCommon.uuidStr = \\\"uuid-\\\"\\\
\\\
    -- globals\\\
    dcsCommon.cbID = 0 -- callback id for simple callback scheduling\\\
    dcsCommon.troopCarriers = {\\\"Mi-8MT\\\", \\\"UH-1H\\\", \\\"Mi-24P\\\"} -- Ka-50 and Gazelle can't carry troops\\\
\\\
    -- verify that a module is loaded. obviously not required\\\
    -- for dcsCommon, but all higher-order modules\\\
    function dcsCommon.libCheck(testingFor, requiredLibs)\\\
        local canRun = true \\\
        for idx, libName in pairs(requiredLibs) do \\\
            if not _G[libName] then \\\
                trigger.action.outText(\\\"*** \\\" .. testingFor .. \\\" requires \\\" .. libName, 30)\\\
                canRun = false \\\
            end\\\
        end\\\
        return canRun\\\
    end\\\
\\\
    -- returns only positive values, lo must be >0 and <= hi \\\
    function dcsCommon.randomBetween(loBound, hiBound)\\\
        if not loBound then loBound = 1 end \\\
        if not hiBound then hiBound = 1 end \\\
        if loBound == hiBound then return loBound end \\\
\\\
        local delayMin = loBound\\\
        local delayMax = hiBound \\\
        local delay = delayMax \\\
    \\\
        if delayMin ~= delayMax then \\\
            -- pick random in range , say 3-7 --> 5 s!\\\
            local delayDiff = (delayMax - delayMin) + 1 -- 7-3 + 1\\\
            delay = dcsCommon.smallRandom(delayDiff) - 1 --> 0-4\\\
            delay = delay + delayMin \\\
            if delay > delayMax then delay = delayMax end \\\
            if delay < 1 then delay = 1 end \\\
        \\\
            if dcsCommon.verbose then \\\
                trigger.action.outText(\\\"+++dcsC: delay range \\\" .. delayMin .. \\\"-\\\" .. delayMax .. \\\": selected \\\" .. delay, 30)\\\
            end\\\
        end\\\
        \\\
        return delay\\\
    end\\\
    \\\
\\\
    -- taken inspiration from mist, as dcs lua has issues with\\\
    -- random numbers smaller than 50. Given a range of x numbers 1..x, it is \\\
    -- repeated a number of times until it fills an array of at least \\\
    -- 50 items (usually some more), and only then one itemis picked from \\\
    -- that array with a random number that is from a greater range (0..50+)\\\
    function dcsCommon.smallRandom(theNum) -- adapted from mist, only support ints\\\
        if theNum >= 50 then return math.random(theNum) end\\\
        \\\
        -- for small randoms (<50) \\\
        local lowNum, highNum\\\
        highNum = theNum\\\
        lowNum = 1\\\
        local total = 1\\\
        if math.abs(highNum - lowNum + 1) < 50 then -- if total values is less than 50\\\
            total = math.modf(50/math.abs(highNum - lowNum + 1)) -- number of times to repeat whole range to get above 50. e.g. 11 would be 5 times 1 .. 11, giving us 55 items total \\\
        end\\\
        local choices = {}\\\
        for i = 1, total do -- iterate required number of times\\\
            for x = lowNum, highNum do -- iterate between the range\\\
                choices[#choices +1] = x -- add each entry to a table\\\
            end\\\
        end\\\
        local rtnVal; -- = math.random(#choices) -- will now do a math.random of at least 50 choices\\\
        for i = 1, 15 do\\\
            rtnVal = math.random(#choices) -- iterate 15 times for randomization\\\
        end\\\
        return choices[rtnVal] -- return indexed\\\
    end\\\
    \\\
\\\
    function dcsCommon.getSizeOfTable(theTable)\\\
        local count = 0\\\
        for _ in pairs(theTable) do count = count + 1 end\\\
        return count\\\
    end\\\
\\\
    function dcsCommon.findAndRemoveFromTable(theTable, theElement) -- assumes array \\\
        if not theElement then return false end \\\
        if not theTable then return false end \\\
        for i=1, #theTable do \\\
            if theTable[i] == theElement then \\\
                -- this element found. remove from table \\\
                table.remove(theTable, i)\\\
                return true \\\
            end\\\
        end\\\
    end\\\
\\\
    function dcsCommon.pickRandom(theTable)\\\
        if not theTable then \\\
            trigger.action.outText(\\\"*** warning: nil table in pick random\\\", 30)\\\
        end\\\
        \\\
        if #theTable < 1 then \\\
            trigger.action.outText(\\\"*** warning: zero choice in pick random\\\", 30)\\\
            --local k = i.ll \\\
            return nil\\\
        end\\\
        if #theTable == 1 then return theTable[1] end\\\
        r = dcsCommon.smallRandom(#theTable) --r = math.random(#theTable)\\\
        return theTable[r]\\\
    end\\\
\\\
    -- enumerateTable - make an array out of a table for indexed access\\\
    function dcsCommon.enumerateTable(theTable)\\\
        if not theTable then theTable = {} end\\\
        local array = {}\\\
        for key, value in pairs(theTable) do \\\
            table.insert(array, value)\\\
        end\\\
        return array\\\
    end\\\
\\\
-- \\\
-- A I R F I E L D S  A N D  F A R P S  \\\
--\\\
\\\
    -- airfield management \\\
    function dcsCommon.getAirbaseCat(aBase)\\\
        if not aBase then return nil end \\\
        \\\
        local airDesc = aBase:getDesc()\\\
        if not airDesc then return nil end \\\
        \\\
        local airCat = airDesc.category\\\
        return airCat \\\
    end\\\
\\\
    -- get free parking slot. optional parkingType can be used to \\\
    -- filter for a scpecific type, e.g. 104 = open field\\\
    function dcsCommon.getFirstFreeParkingSlot(aerodrome, parkingType) \\\
        if not aerodrome then return nil end \\\
        local freeSlots = aerodrome:getParking(true)\\\
        \\\
        for idx, theSlot in pairs(freeSlots) do \\\
            if not parkingType then \\\
                -- simply return the first we come across\\\
                return theSlot\\\
            end        \\\
            \\\
            if theSlot.Term_Type == parkingType then \\\
                return theSlot \\\
            end\\\
        end\\\
        \\\
        return nil \\\
    end\\\
\\\
    -- getAirbasesInRangeOfPoint: get airbases that are in range of point \\\
    function dcsCommon.getAirbasesInRangeOfPoint(center, range, filterCat, filterCoalition)\\\
        if not center then return {} end \\\
        if not range then range = 500 end -- 500m default \\\
        local basesInRange = {}\\\
        \\\
        local allAB = dcsCommon.getAirbasesWhoseNameContains(\\\"*\\\", filterCat, filterCoalition)\\\
        for idx, aBase in pairs(allAB) do             \\\
            local delta = dcsCommon.dist(center, aBase:getPoint())\\\
            if delta <= range then \\\
                table.insert(basesInRange, aBase)\\\
            end\\\
        end\\\
        return basesInRange\\\
    end\\\
\\\
    -- getAirbasesInRangeOfAirbase returns all airbases that \\\
    -- are in range of the given airbase \\\
    function dcsCommon.getAirbasesInRangeOfAirbase(airbase, includeCenter, range, filterCat, filterCoalition)\\\
        if not airbase then return {} end\\\
        if not range then range = 150000 end \\\
        local center = airbase:getPoint() \\\
        local centerName = airbase:getName() \\\
        \\\
        local ABinRange = {}\\\
        local allAB = dcsCommon.getAirbasesWhoseNameContains(\\\"*\\\", filterCat, filterCoalition)\\\
        \\\
        for idx, aBase in pairs(allAB) do \\\
            if aBase:getName() ~= centerName then \\\
                local delta = dcsCommon.dist(center, aBase:getPoint())\\\
                if delta <= range then \\\
                    table.insert(ABinRange, aBase)\\\
                end\\\
            end        \\\
        end\\\
        \\\
        if includeCenter then \\\
            table.insert(ABinRange, airbase)\\\
        end\\\
        \\\
        return ABinRange\\\
    end\\\
\\\
    function dcsCommon.getAirbasesInRangeOfAirbaseList(theCenterList, includeList, range, filterCat, filterCoalition)\\\
        local collectorDict = {}\\\
        for idx, aCenter in pairs(theCenterList) do \\\
            -- get all surrounding airbases. returns list of airfields \\\
            local surroundingAB = dcsCommon.getAirbasesInRangeOfAirbase(airbase, includeList, range, filterCat, filterCoalition)\\\
            \\\
            for idx2, theAirField in pairs (surroundingAB) do \\\
                collectorDict[airField] = theAirField \\\
            end\\\
        end\\\
        \\\
        -- make result an array\\\
        local theABList = dcsCommon.enumerateTable(collectorDict)\\\
        return theABList\\\
    end\\\
\\\
    -- getAirbasesWhoseNameContains - get all airbases containing \\\
    -- a name. filterCat is optional and can be aerodrome (0), farp (1), ship (2)\\\
    -- filterCoalition is optional and can be 0 (neutral), 1 (red), 2 (blue) \\\
    -- if no name given or aName = \\\"*\\\", then all bases are returned prior to filtering \\\
    function dcsCommon.getAirbasesWhoseNameContains(aName, filterCat, filterCoalition)\\\
        --trigger.action.outText(\\\"getAB(name): enter with \\\" .. aName, 30)\\\
        if not aName then aName = \\\"*\\\" end \\\
        local allYourBase = world.getAirbases() -- get em all \\\
        local areBelongToUs = {}\\\
        -- now iterate all bases\\\
        for idx, aBase in pairs(allYourBase) do\\\
            local airBaseName = aBase:getName() -- get display name\\\
            if aName == \\\"*\\\" or dcsCommon.containsString(airBaseName, aName) then \\\
                -- containsString is case insesitive unless told otherwise\\\
                --if aName ~= \\\"*\\\" then \\\
                --    trigger.action.outText(\\\"getAB(name): matched \\\" .. airBaseName, 30)\\\
                --end \\\
                local doAdd = true \\\
                if filterCat then \\\
                    -- make sure the airbase is of that category \\\
                    local airCat = dcsCommon.getAirbaseCat(aBase)\\\
                    doAdd = doAdd and airCat == filterCat \\\
                end\\\
                \\\
                if filterCoalition then \\\
                    doAdd = doAdd and filterCoalition == aBase:getCoalition()\\\
                end\\\
                \\\
                if doAdd then \\\
                    -- all good, add to table\\\
                    table.insert(areBelongToUs, aBase)\\\
                end            \\\
            end\\\
        end\\\
        return areBelongToUs\\\
    end\\\
\\\
    function dcsCommon.getFirstAirbaseWhoseNameContains(aName, filterCat, filterCoalition)\\\
        local allBases = dcsCommon.getAirbasesWhoseNameContains(aName, filterCat, filterCoalition)\\\
        for idx, aBase in pairs (allBases) do \\\
            -- simply return first \\\
            return aBase\\\
        end\\\
        return nil \\\
    end    \\\
\\\
    function dcsCommon.getClosestAirbaseTo(thePoint, filterCat, filterCoalition)\\\
        local delta = math.huge\\\
        local allYourBase = dcsCommon.getAirbasesWhoseNameContains(\\\"*\\\", filterCat, filterCoalition) -- get em all and filter\\\
        local closestBase = nil \\\
        for idx, aBase in pairs(allYourBase) do\\\
            -- iterate them all \\\
            local abPoint = aBase:getPoint()\\\
            newDelta = dcsCommon.dist(thePoint, {x=abPoint.x, y = 0, z=abPoint.z})\\\
            if newDelta < delta then \\\
                delta = newDelta\\\
                closestBase = aBase\\\
            end\\\
        end\\\
        return closestBase, delta \\\
    end\\\
\\\
-- \\\
-- U N I T S   M A N A G E M E N T \\\
--\\\
\\\
    -- number of living units in group\\\
    function dcsCommon.livingUnitsInGroup(group)\\\
        local living = 0\\\
        local allUnits = group:getUnits()\\\
        for key, aUnit in pairs(allUnits) do \\\
            if aUnit:isExist() and aUnit:getLife() >= 1 then \\\
                living = living + 1\\\
            end\\\
        end\\\
        return living\\\
    end\\\
\\\
    -- closest living unit in group to a point\\\
    function dcsCommon.getClosestLivingUnitToPoint(group, p)\\\
        if not p then return nil end\\\
        if not group then return nil end\\\
        local closestUnit = nil\\\
        local closestDist = math.huge\\\
        local allUnits = group:getUnits()\\\
        for key, aUnit in pairs(allUnits) do \\\
            if aUnit:isExist() and aUnit:getLife() >= 1 then \\\
                local thisDist = dcsCommon.dist(p, aUnit:getPoint())\\\
                if thisDist < closestDist then \\\
                    closestDist = thisDist\\\
                    closestUnit = aUnit \\\
                end\\\
            end\\\
        end\\\
        return closestUnit, closestDist\\\
    end\\\
    \\\
    -- closest living group to a point - cat can be nil or one of Group.Category = { AIRPLANE = 0, HELICOPTER = 1, GROUND = 2, SHIP = 3, TRAIN = 4}\\\
    function dcsCommon.getClosestLivingGroupToPoint(p, coal, cat) \\\
        if not cat then cat = 2 end -- ground is default \\\
        local closestGroup = nil;\\\
        local closestGroupDist = math.huge\\\
        local allGroups =  coalition.getGroups(coal, cat) -- get all groups from this coalition, perhaps filtered by cat \\\
        for key, grp in pairs(allGroups) do\\\
            local closestUnit, dist = dcsCommon.getClosestLivingUnitToPoint(grp, p)\\\
            if closestUnit then \\\
                if dist < closestGroupDist then \\\
                    closestGroup = grp\\\
                    closestGroupDist = dist\\\
                end\\\
            end            \\\
        end\\\
        return closestGroup, closestGroupDist\\\
    end\\\
\\\
    function dcsCommon.getLivingGroupsAndDistInRangeToPoint(p, range, coal, cat) \\\
        if not cat then cat = 2 end -- ground is default \\\
        local groupsInRange = {};\\\
        local allGroups = coalition.getGroups(coal, cat) -- get all groups from this coalition, perhaps filtered by cat \\\
        for key, grp in pairs(allGroups) do\\\
            local closestUnit, dist = dcsCommon.getClosestLivingUnitToPoint(grp, p)\\\
            if closestUnit then \\\
                if dist < range then \\\
                    table.insert(groupsInRange, {group = grp, dist = dist}) -- array\\\
                end\\\
            end            \\\
        end\\\
        -- sort the groups by distance\\\
        table.sort(groupsInRange, function (left, right) return left.dist < right.dist end )\\\
        return groupsInRange\\\
    end\\\
\\\
    -- distFlat ignores y, input must be xyz points, NOT xy points  \\\
    function dcsCommon.distFlat(p1, p2) \\\
        local point1 = {x = p1.x, y = 0, z=p1.z}\\\
        local point2 = {x = p2.x, y = 0, z=p2.z}\\\
        return dcsCommon.dist(point1, point2)\\\
    end\\\
    \\\
    -- distance between points\\\
    function dcsCommon.dist(point1, point2)     -- returns distance between two points\\\
      -- supports xyz and xy notations\\\
      if not point1 then \\\
        trigger.action.outText(\\\"+++ warning: nil point1 in common:dist\\\", 30)\\\
        point1 = {x=0, y=0, z=0}\\\
      end\\\
\\\
      if not point2 then \\\
        trigger.action.outText(\\\"+++ warning: nil point2 in common:dist\\\", 30)\\\
        point2 = {x=0, y=0, z=0}\\\
        stop.here.now = 1\\\
      end\\\
      \\\
      local p1 = {x = point1.x, y = point1.y}\\\
      if not point1.z then \\\
        p1.z = p1.y\\\
        p1.y = 0\\\
      else \\\
        p1.z = point1.z\\\
      end\\\
      \\\
      local p2 = {x = point2.x, y = point2.y}\\\
      if not point2.z then \\\
        p2.z = p2.y\\\
        p2.y = 0\\\
      else \\\
        p2.z = point2.z\\\
      end\\\
      \\\
      local x = p1.x - p2.x\\\
      local y = p1.y - p2.y \\\
      local z = p1.z - p2.z\\\
      \\\
      return (x*x + y*y + z*z)^0.5\\\
    end\\\
\\\
    function dcsCommon.delta(name1, name2) -- returns distance (in meters) of two named objects\\\
      local n1Pos = Unit.getByName(name1):getPosition().p\\\
      local n2Pos = Unit.getByName(name2):getPosition().p\\\
      return dcsCommon.dist(n1Pos, n2Pos)\\\
    end\\\
\\\
    -- lerp between a and b, x being 0..1 (percentage), clipped to [0..1]\\\
    function dcsCommon.lerp(a, b, x) \\\
        if not a then return 0 end\\\
        if not b then return 0 end\\\
        if not x then return a end\\\
        if x < 0 then x = 0 end \\\
        if x > 1 then x = 1 end \\\
        return a + (b - a ) * x\\\
    end\\\
\\\
    function dcsCommon.bearingFromAtoB(A, B) -- coords in x, z \\\
        dx = B.x - A.x\\\
        dz = B.z - A.z\\\
        bearing = math.atan2(dz, dx) -- in radiants\\\
        return bearing\\\
    end\\\
\\\
    function dcsCommon.bearingInDegreesFromAtoB(A, B)\\\
        local bearing = dcsCommon.bearingFromAtoB(A, B) -- in rads \\\
        bearing = math.floor(bearing / math.pi * 180)\\\
        if bearing < 0 then bearing = bearing + 360 end\\\
        if bearing > 360 then bearing = bearing - 360 end\\\
        return bearing\\\
    end\\\
    \\\
    function dcsCommon.compassPositionOfARelativeToB(A, B)\\\
        -- warning: is REVERSE in order for bearing, returns a string like 'Sorth', 'Southwest'\\\
        if not A then return \\\"***error:A***\\\" end\\\
        if not B then return \\\"***error:B***\\\" end\\\
        local bearing = dcsCommon.bearingInDegreesFromAtoB(B, A) -- returns 0..360\\\
        if bearing < 23 then return \\\"North\\\" end \\\
        if bearing < 68 then return \\\"NE\\\" end\\\
        if bearing < 112 then return \\\"East\\\" end \\\
        if bearing < 158 then return \\\"SE\\\" end \\\
        if bearing < 202 then return \\\"South\\\" end \\\
        if bearing < 248 then return \\\"SW\\\" end \\\
        if bearing < 292 then return \\\"West\\\" end\\\
        if bearing < 338 then return \\\"NW\\\" end \\\
        return \\\"North\\\"\\\
    end\\\
    \\\
    function dcsCommon.clockPositionOfARelativeToB(A, B, headingOfBInDegrees)\\\
        -- o'clock notation \\\
        if not A then return \\\"***error:A***\\\" end\\\
        if not B then return \\\"***error:B***\\\" end\\\
        if not headingOfBInDegrees then headingOfBInDegrees = 0 end \\\
        \\\
        local bearing = dcsCommon.bearingInDegreesFromAtoB(B, A) -- returns 0..360\\\
--        trigger.action.outText(\\\"+++comm: oclock - bearing = \\\" .. bearing .. \\\" and inHeading = \\\" .. headingOfBInDegrees, 30) \\\
        bearing = bearing - headingOfBInDegrees\\\
        return dcsCommon.getClockDirection(bearing)\\\
        \\\
    end \\\
    \\\
    -- given a heading, return clock with 0 being 12, 180 being 6 etc.\\\
    function dcsCommon.getClockDirection(direction) -- inspired by cws, improvements my own\\\
        if not direction then return 0 end\\\
        direction = math.fmod (direction, 360)\\\
        while direction < 0 do \\\
            direction = direction + 360\\\
        end\\\
        \\\
        if direction < 15 then -- special case 12 o'clock past 12 o'clock\\\
            return 12\\\
        end\\\
    \\\
        direction = direction + 15 -- add offset so we get all other times correct\\\
        return math.floor(direction/30)\\\
    \\\
    end\\\
\\\
    \\\
    function dcsCommon.randomDegrees()\\\
        local degrees = math.random(360) * 3.14152 / 180\\\
        return degrees\\\
    end\\\
\\\
    function dcsCommon.randomPercent()\\\
        local percent = math.random(100)/100\\\
        return percent\\\
    end\\\
\\\
    function dcsCommon.randomPointOnPerimeter(sourceRadius, x, z) \\\
        return dcsCommon.randomPointInCircle(sourceRadius, sourceRadius-1, x, z)\\\
    end\\\
\\\
    function dcsCommon.randomPointInCircle(sourceRadius, innerRadius, x, z)\\\
        if not x then x = 0 end\\\
        --local y = 0\\\
        if not innerRadius then innerRadius = 0 end        \\\
        if innerRadius < 0 then innerRadius = 0 end\\\
        \\\
        local percent = dcsCommon.randomPercent() -- 1 / math.random(100)\\\
        -- now lets get a random degree\\\
        local degrees = dcsCommon.randomDegrees() -- math.random(360) * 3.14152 / 180 -- ok, it's actually radiants. \\\
        local r = (sourceRadius-innerRadius) * percent \\\
        local x = x + (innerRadius + r) * math.cos(degrees)\\\
        local z = z + (innerRadius + r) * math.sin(degrees)\\\
    \\\
        local thePoint = {}\\\
        thePoint.x = x\\\
        thePoint.y = 0\\\
        thePoint.z = z \\\
        \\\
        return thePoint, degrees\\\
    end\\\
\\\
    -- get group location: get the group's location by \\\
    -- accessing the fist existing, alive member of the group that it finds\\\
    function dcsCommon.getGroupLocation(group)\\\
        -- nifty trick from mist: make this work with group and group name\\\
        if type(group) == 'string' then -- group name\\\
            group = Group.getByName(group)\\\
        end\\\
        \\\
        -- get all units\\\
        local allUnits = group:getUnits()\\\
\\\
        -- iterate through all members of group until one is alive and exists\\\
        for index, theUnit in pairs(allUnits) do \\\
            if (theUnit:isExist() and theUnit:getLife() > 0) then \\\
                return theUnit:getPosition().p \\\
            end;\\\
        end\\\
\\\
        -- if we get here, there was no live unit \\\
        --trigger.action.outText(\\\"+++cmn: A group has no live units. returning nil\\\", 10)\\\
        return nil \\\
        \\\
    end\\\
\\\
    -- get the group's first Unit that exists and is \\\
    -- alive \\\
    function dcsCommon.getGroupUnit(group)\\\
        if not group then return nil  end\\\
        \\\
        -- nifty trick from mist: make this work with group and group name\\\
        if type(group) == 'string' then -- group name\\\
            group = Group.getByName(group)\\\
        end\\\
        \\\
        if not group:isExist() then return nil end \\\
        \\\
        -- get all units\\\
        local allUnits = group:getUnits()\\\
\\\
        -- iterate through all members of group until one is alive and exists\\\
        for index, theUnit in pairs(allUnits) do \\\
            if (theUnit:isExist() and theUnit:getLife() > 0) then \\\
                return theUnit\\\
            end;\\\
        end\\\
\\\
        -- if we get here, there was no live unit \\\
        --trigger.action.outText(\\\"+++cmn A group has no live units. returning nil\\\", 10)\\\
        return nil \\\
        \\\
    end\\\
\\\
    -- and here the alias\\\
    function dcsCommon.getFirstLivingUnit(group)\\\
        return dcsCommon.getGroupUnit(group)\\\
    end\\\
    \\\
    -- isGroupAlive returns true if there is at least one unit in the group that isn't dead\\\
    function dcsCommon.isGroupAlive(group)\\\
        return (dcsCommon.getGroupUnit(group) ~= nil) \\\
    end\\\
\\\
    function dcsCommon.getLiveGroupUnits(group)\\\
        -- nifty trick from mist: make this work with group and group name\\\
        if type(group) == 'string' then -- group name\\\
            group = Group.getByName(group)\\\
        end\\\
        \\\
        local liveUnits = {}\\\
        -- get all units\\\
        local allUnits = group:getUnits()\\\
\\\
        -- iterate through all members of group until one is alive and exists\\\
        for index, theUnit in pairs(allUnits) do \\\
            if (theUnit:isExist() and theUnit:getLife() > 0) then \\\
                table.insert(liveUnits, theUnit) \\\
            end;\\\
        end\\\
\\\
        -- if we get here, there was no live unit \\\
        return liveUnits\\\
    end\\\
\\\
    function dcsCommon.getGroupTypeString(group) -- convert into comma separated types \\\
        if not group then \\\
            trigger.action.outText(\\\"+++cmn getGroupTypeString: nil group\\\", 30)\\\
            return \\\"\\\" \\\
        end\\\
        if not dcsCommon.isGroupAlive(group) then \\\
            trigger.action.outText(\\\"+++cmn getGroupTypeString: dead group\\\", 30)\\\
            return \\\"\\\" \\\
        end \\\
        local theTypes = \\\"\\\"\\\
        local liveUnits = dcsCommon.getLiveGroupUnits(group)\\\
        for i=1, #liveUnits do \\\
            if i > 1 then theTypes = theTypes .. \\\",\\\" end\\\
            theTypes = theTypes .. liveUnits[i]:getTypeName()\\\
        end\\\
        return theTypes\\\
    end\\\
\\\
    function dcsCommon.getGroupTypes(group) \\\
        if not group then \\\
            trigger.action.outText(\\\"+++cmn getGroupTypes: nil group\\\", 30)\\\
            return {}\\\
        end\\\
        if not dcsCommon.isGroupAlive(group) then \\\
            trigger.action.outText(\\\"+++cmn getGroupTypes: dead group\\\", 30)\\\
            return {}\\\
        end \\\
        local liveUnits = dcsCommon.getLiveGroupUnits(group)\\\
        local unitTypes = {}\\\
        for i=1, #liveUnits do \\\
            table.insert(unitTypes, liveUnits[i]:getTypeName())\\\
        end\\\
        return unitTypes\\\
    end\\\
\\\
    function dcsCommon.getEnemyCoalitionFor(aCoalition)\\\
        if aCoalition == 1 then return 2 end\\\
        if aCoalition == 2 then return 1 end\\\
        if type(aCoalition) == \\\"string\\\" then \\\
            aCoalition = aCoalition:lower()\\\
            if aCoalition == \\\"red\\\" then return 2 end\\\
            if aCoalition == \\\"blue\\\" then return 1 end\\\
        end\\\
        return nil\\\
    end\\\
\\\
    function dcsCommon.getACountryForCoalition(aCoalition)\\\
        -- scan the table of countries and get the first country that is part of aCoalition\\\
        -- this is useful if you want to create troops for a coalition but don't know the\\\
        -- coalition's countries \\\
        -- we start with id=0 (Russia), go to id=85 (Slovenia), but skip id = 14\\\
        local i = 0\\\
        while i < 86 do \\\
            if i ~= 14 then \\\
                if (coalition.getCountryCoalition(i) == aCoalition) then return i end\\\
            end\\\
            i = i + 1\\\
        end\\\
        \\\
        return nil\\\
    end\\\
--\\\
--\\\
-- C A L L B A C K   H A N D L E R \\\
--\\\
--\\\
\\\
    -- installing callbacks\\\
    -- based on mist, with optional additional hooks for pre- and post-\\\
    -- processing of the event\\\
    -- when filtering occurs in pre, an alternative 'rejected' handler can be called \\\
    function dcsCommon.addEventHandler(f, pre, post, rejected) -- returns ID \\\
        local handler = {} -- build a wrapper and connect the onEvent\\\
        --dcsCommon.cbID = dcsCommon.cbID + 1 -- increment unique count\\\
        handler.id = dcsCommon.uuid(\\\"eventHandler\\\")\\\
        handler.f = f -- the callback itself\\\
        if (rejected) then handler.rejected = rejected end\\\
        -- now set up pre- and post-processors. defaults are set in place\\\
        -- so pre and post are optional. If pre returns false, the callback will\\\
        -- not be invoked\\\
        if (pre) then handler.pre = pre else handler.pre = dcsCommon.preCall end\\\
        if (post) then handler.post = post else handler.post = dcsCommon.postCall end\\\
        function handler:onEvent(event)\\\
            if not self.pre(event) then \\\
                if dcsCommon.verbose then\\\
--                    trigger.action.outText(\\\"event \\\" .. event.id .. \\\" discarded by pre-processor\\\", 10)\\\
                end\\\
                if (self.rejected) then self.rejected(event) end \\\
                return\\\
            end\\\
            self.f(event) -- call the handler\\\
            self.post(event) -- do post-processing\\\
        end\\\
        world.addEventHandler(handler)\\\
        return handler.id\\\
    end\\\
\\\
    function dcsCommon.preCall(e)\\\
        -- we can filter here\\\
        -- if we return false, the call is abortet\\\
        if dcsCommon.verbose then\\\
            trigger.action.outText(\\\"event \\\" .. e.id .. \\\" received: PRE-PROCESSING\\\", 10)\\\
        end\\\
        return true;\\\
    end;\\\
\\\
    function dcsCommon.postCall(e)\\\
        -- we do pos proccing here \\\
        if dcsCommon.verbose then\\\
            trigger.action.outText(\\\"event \\\" .. e.id .. \\\" received: post proc\\\", 10)\\\
        end\\\
    end\\\
    \\\
    -- highly specific eventhandler for one event only\\\
    -- based on above, with direct filtering built in; skips pre\\\
    -- but does post\\\
    function dcsCommon.addEventHandlerForEventTypes(f, evTypes, post, rejected) -- returns ID \\\
        local handler = {} -- build a wrapper and connect the onEvent\\\
        dcsCommon.cbID = dcsCommon.cbID + 1 -- increment unique count\\\
        handler.id = dcsCommon.cbID\\\
        handler.what = evTypes\\\
        if (rejected) then handler.rejected = rejected end \\\
        \\\
        handler.f = f -- set the callback itself\\\
        -- now set up post-processor. pre is hard-coded to match evType\\\
        -- post is optional. If event.id is not in evTypes, the callback will\\\
        -- not be invoked\\\
        if (post) then handler.post = post else handler.post = dcsCommon.postCall end\\\
        function handler:onEvent(event)\\\
            hasMatch = false;\\\
            for key, evType in pairs(self.what) do\\\
                if evType == event.id then\\\
                    hasMatch = true;\\\
                    break;\\\
                end;\\\
            end;\\\
            if not hasMatch then \\\
                if dcsCommon.verbose then\\\
                    trigger.action.outText(\\\"event \\\" .. e.id .. \\\" discarded - not in whitelist evTypes\\\", 10)\\\
                end\\\
                if (self.rejected) then self.rejected(event) end \\\
                return;\\\
            end;\\\
            \\\
            self.f(event) -- call the actual handler as passed to us\\\
            self.post(event) -- do post-processing \\\
        end\\\
        world.addEventHandler(handler) -- add to event handlers\\\
        return handler.id\\\
    end\\\
    \\\
    \\\
    \\\
    -- remove event handler / callback, identical to Mist \\\
    -- note we don't call world.removeEventHandler, but rather directly \\\
    -- access world.eventHandlers directly and remove kvp directly.\\\
    function dcsCommon.removeEventHandler(id)\\\
        for key, handler in pairs(world.eventHandlers) do\\\
            if handler.id and handler.id == id then\\\
                world.eventHandlers[key] = nil\\\
                return true\\\
            end\\\
        end\\\
        return false\\\
    end\\\
\\\
--\\\
--\\\
-- C L O N I N G \\\
--\\\
--\\\
    -- topClone is a shallow clone of orig, only top level is iterated,\\\
    -- all values are ref-copied\\\
    function dcsCommon.topClone(orig)\\\
        local orig_type = type(orig)\\\
        local copy\\\
        if orig_type == 'table' then\\\
            copy = {}\\\
            for orig_key, orig_value in pairs(orig) do\\\
                copy[orig_key] = orig_value\\\
            end\\\
        else -- number, string, boolean, etc\\\
            copy = orig\\\
        end\\\
        return copy\\\
    end\\\
\\\
    -- clone is a recursive clone which will also clone\\\
    -- deeper levels, as used in units \\\
    function dcsCommon.clone(orig)\\\
        local orig_type = type(orig)\\\
        local copy\\\
        if orig_type == 'table' then\\\
            copy = {}\\\
            for orig_key, orig_value in next, orig, nil do\\\
                copy[dcsCommon.clone(orig_key)] = dcsCommon.clone(orig_value)\\\
            end\\\
            setmetatable(copy, dcsCommon.clone(getmetatable(orig)))\\\
        else -- number, string, boolean, etc\\\
            copy = orig\\\
        end\\\
        return copy\\\
    end\\\
\\\
    function dcsCommon.copyArray(inArray)\\\
        -- warning: this is a ref copy!\\\
        local theCopy = {}\\\
        for idx, element in pairs(inArray) do \\\
            table.insert(theCopy, element)\\\
        end\\\
        return theCopy \\\
    end\\\
--\\\
-- \\\
-- S P A W N I N G \\\
-- \\\
-- \\\
\\\
    function dcsCommon.createEmptyGroundGroupData (name)\\\
        local theGroup = {} -- empty group\\\
        theGroup.visible = false\\\
        theGroup.taskSelected = true\\\
        -- theGroup.route = {}\\\
        -- theGroup.groupId = id\\\
        theGroup.tasks = {}\\\
        -- theGroup.hidden = false -- hidden on f10?\\\
\\\
        theGroup.units = { } -- insert units here! -- use addUnitToGroupData\\\
\\\
        theGroup.x = 0\\\
        theGroup.y = 0\\\
        theGroup.name = name\\\
        -- theGroup.start_time = 0\\\
        theGroup.task = \\\"Ground Nothing\\\"\\\
        \\\
        return theGroup\\\
    end;\\\
\\\
    function dcsCommon.createEmptyAircraftGroupData (name)\\\
        local theGroup = dcsCommon.createEmptyGroundGroupData(name)--{} -- empty group\\\
\\\
        theGroup.task = \\\"Nothing\\\" -- can be others, like Transport, CAS, etc\\\
        -- returns with empty route\\\
        theGroup.route = dcsCommon.createEmptyAircraftRouteData() -- we can add points here \\\
        return theGroup\\\
    end;\\\
\\\
    function dcsCommon.createAircraftRoutePointData(x, z, altitudeInFeet, knots, altType, action)\\\
        local rp = {}\\\
        rp.x = x\\\
        rp.y = z\\\
        rp.action = \\\"Turning Point\\\"\\\
        rp.type = \\\"Turning Point\\\"\\\
        if action then rp.action = action; rp.type = action end -- warning: may not be correct, need to verify later\\\
        rp.alt = altitudeInFeet * 0.3048\\\
        rp.speed = knots * 0.514444 -- we use \\\
        rp.alt_type = \\\"BARO\\\"\\\
        if (altType) then rp.alt_type = altType end \\\
        return rp\\\
    end\\\
\\\
    function dcsCommon.addRoutePointDataToRouteData(inRoute, x, z, altitudeInFeet, knots, altType, action)\\\
        local p = dcsCommon.createAircraftRoutePointData(x, z, altitudeInFeet, knots, altType, action)\\\
        local thePoints = inRoute.points \\\
        table.insert(thePoints, p)\\\
    end\\\
    \\\
    function dcsCommon.addRoutePointDataToGroupData(group, x, z, altitudeInFeet, knots, altType, action)\\\
        if not group.route then group.route = dcsCommon.createEmptyAircraftRouteData() end\\\
        local theRoute = group.route \\\
        dcsCommon.addRoutePointDataToRouteData(theRoute, x, z, altitudeInFeet, knots, altType, action)\\\
    end\\\
\\\
    function dcsCommon.addRoutePointForGroupData(theGroup, theRP)\\\
        if not theGroup then return end \\\
        if not theGroup.route then theGroup.route = dcsCommon.createEmptyAircraftRouteData() end\\\
        \\\
        local theRoute = theGroup.route \\\
        local thePoints = theRoute.points \\\
        table.insert(thePoints, theRP)\\\
    end\\\
    \\\
    function dcsCommon.createEmptyAircraftRouteData()\\\
        local route = {}\\\
        route.points = {}\\\
        return route\\\
    end\\\
\\\
    function dcsCommon.createTakeOffFromParkingRoutePointData(aerodrome)\\\
        if not aerodrome then return nil end \\\
            \\\
        local rp = {}    \\\
        local freeParkingSlot = dcsCommon.getFirstFreeParkingSlot(aerodrome, 104) -- get big slot first \\\
        if not freeParkingSlot then \\\
            freeParkingSlot = dcsCommon.getFirstFreeParkingSlot(aerodrome) -- try any size\\\
        end\\\
            \\\
        if not freeParkingSlot then \\\
            trigger.action.outText(\\\"civA: no free parking at \\\" .. aerodrome:getName(), 30)\\\
            return nil \\\
        end\\\
            \\\
        local p = freeParkingSlot.vTerminalPos\\\
            \\\
        rp.airdromeId = aerodrome:getID() \\\
        rp.x = p.x\\\
        rp.y = p.z\\\
        rp.alt = p.y \\\
        rp.action = \\\"From Parking Area\\\"\\\
        rp.type = \\\"TakeOffParking\\\"\\\
            \\\
        rp.speed = 100; -- in m/s? If so, that's 360 km/h \\\
        rp.alt_type = \\\"BARO\\\"\\\
        return rp\\\
    end\\\
\\\
    function dcsCommon.createOverheadAirdromeRoutPintData(aerodrome)\\\
        if not aerodrome then return nil end \\\
        local rp = {}            \\\
        local p = aerodrome:getPoint()\\\
        rp.x = p.x\\\
        rp.y = p.z\\\
        rp.alt = p.y + 2000 -- 6000 ft overhead\\\
        rp.action = \\\"Turning Point\\\"\\\
        rp.type = \\\"Turning Point\\\"\\\
            \\\
        rp.speed = 133; -- in m/s? If so, that's 360 km/h \\\
        rp.alt_type = \\\"BARO\\\"\\\
        return rp\\\
    end\\\
    \\\
\\\
    function dcsCommon.createLandAtAerodromeRoutePointData(aerodrome)\\\
        if not aerodrome then return nil end \\\
            \\\
        local rp = {}            \\\
        local p = aerodrome:getPoint()\\\
        rp.airdromeId = aerodrome:getID() \\\
        rp.x = p.x\\\
        rp.y = p.z\\\
        rp.alt = p.y \\\
        rp.action = \\\"Landing\\\"\\\
        rp.type = \\\"Land\\\"\\\
            \\\
        rp.speed = 100; -- in m/s? If so, that's 360 km/h \\\
        rp.alt_type = \\\"BARO\\\"\\\
        return rp\\\
    end\\\
\\\
    \\\
    function dcsCommon.createRPFormationData(findex) -- must be added as \\\"task\\\" to an RP. use 4 for Echelon right\\\
        local task = {}\\\
        task.id = \\\"ComboTask\\\"\\\
        local params = {}\\\
        task.params = params\\\
        local tasks = {}\\\
        params.tasks = tasks\\\
        local t1 = {}\\\
        tasks[1] = t1\\\
        t1.number = 1\\\
        t1.auto = false \\\
        t1.id = \\\"WrappedAction\\\"\\\
        t1.enabled = true\\\
        local t1p = {}\\\
        t1.params = t1p\\\
        local action = {}\\\
        t1p.action = action \\\
        action.id = \\\"Option\\\"\\\
        local ap = {}\\\
        action.params = ap\\\
        ap.variantIndex = 3\\\
        ap.name = 5 -- AI.Option.Air.ID 5 = Formation \\\
        ap.formationIndex = findex -- 4 is echelon_right\\\
        ap.value = 262147\\\
        \\\
        return task \\\
    end\\\
\\\
    function dcsCommon.addTaskDataToRP(theTask, theGroup, rpIndex)\\\
        local theRoute = theGroup.route\\\
        local thePoints = theRoute.points\\\
        local rp = thePoints[rpIndex]\\\
        rp.task = theTask\\\
    end\\\
    \\\
    -- create a minimal payload table that is compatible with creating \\\
    -- a unit. you may need to alter this before adding the unit to\\\
    -- the mission. all params optional \\\
    function dcsCommon.createPayload(fuel, flare, chaff, gun) \\\
        local payload = {}\\\
        payload.pylons = {}\\\
        if not fuel then fuel = 1000 end -- in kg. check against fuelMassMax in type desc\\\
        if not flare then flare = 0 end\\\
        if not chaff then chaff = 0 end\\\
        if not gun then gun = 0 end\\\
        return payload \\\
        \\\
    end\\\
\\\
    function dcsCommon.createCallsign(cs) \\\
        local callsign = {}\\\
        callsign[1] = 1\\\
        callsign[2] = 1\\\
        callsign[3] = 1\\\
        if not cs then cs = \\\"Enfield11\\\" end\\\
        callsign.name = cs\\\
        return callsign\\\
    end\\\
    \\\
\\\
    -- create the data table required to spawn a unit.\\\
    -- unit types are defined in https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB\\\
    function dcsCommon.createGroundUnitData(name, unitType, transportable)\\\
        local theUnit = {}\\\
        unitType = dcsCommon.trim(unitType)\\\
        theUnit.type = unitType -- e.g. \\\"LAV-25\\\",\\\
        if not transportable then transportable = false end -- elaborate, not requried code\\\
        theUnit.transportable = {[\\\"randomTransportable\\\"] = transportable} \\\
        -- theUnit.unitId = id \\\
        theUnit.skill = \\\"Average\\\" -- always average \\\
        theUnit.x = 0 -- make it zero, zero!\\\
        theUnit.y = 0\\\
        theUnit.name = name\\\
        theUnit.playerCanDrive = false\\\
        theUnit.heading = 0\\\
        return theUnit\\\
    end \\\
\\\
    function dcsCommon.createAircraftUnitData(name, unitType, transportable, altitude, speed, heading)\\\
        local theAirUnit = dcsCommon.createGroundUnitData(name, unitType, transportable)\\\
        theAirUnit.alt = 100 -- make it 100m\\\
        if altitude then theAirUnit.alt = altitude end \\\
        theAirUnit.alt_type = \\\"RADIO\\\" -- AGL\\\
        theAirUnit.speed = 77 -- m/s --> 150 knots\\\
        if speed then theAirUnit.speed = speed end \\\
        if heading then theAirUnit.heading = heading end \\\
        theAirUnit.payload = dcsCommon.createPayload()\\\
        theAirUnit.callsign = dcsCommon.createCallsign()\\\
        return theAirUnit\\\
    end\\\
    \\\
\\\
    function dcsCommon.addUnitToGroupData(theUnit, theGroup, dx, dy, heading)\\\
        -- add a unit to a group, and place it at dx, dy of group's position,\\\
        -- taking into account unit's own current location\\\
        if not dx then dx = 0 end\\\
        if not dy then dy = 0 end\\\
        if not heading then heading = 0 end\\\
        theUnit.x = theUnit.x + dx + theGroup.x\\\
        theUnit.y = theUnit.y + dy + theGroup.y \\\
        theUnit.heading = heading\\\
        table.insert(theGroup.units, theUnit)\\\
    end;\\\
\\\
    function dcsCommon.createSingleUnitGroup(name, theUnitType, x, z, heading) \\\
        -- create the container \\\
        local theNewGroup = dcsCommon.createEmptyGroundGroupData(name)\\\
        local aUnit = {}\\\
        aUnit = dcsCommon.createGroundUnitData(name .. \\\"-1\\\", theUnitType, false)\\\
--        trigger.action.outText(\\\"dcsCommon - unit name retval \\\" .. aUnit.name, 30)\\\
        dcsCommon.addUnitToGroupData(aUnit, theNewGroup, x, z, heading)\\\
        return theNewGroup\\\
    end\\\
    \\\
\\\
    function dcsCommon.arrangeGroupDataIntoFormation(theNewGroup, radius, minDist, formation, innerRadius)\\\
        -- formations:\\\
        --    (default) \\\"line\\\" (left to right along x) -- that is Y direction\\\
        --    \\\"line_v\\\" a line top to bottom -- that is X direction\\\
        --    \\\"chevron\\\" - left to right middle too top\\\
        --    \\\"scattered\\\", \\\"random\\\" -- random, innerRadius used to clear area in center\\\
        --       \\\"circle\\\", \\\"circle_forward\\\" -- circle, forward facing\\\
        --    \\\"circle_in\\\" -- circle, inwarf facing\\\
        --    \\\"circle_out\\\" -- circle, outward facing\\\
        --    \\\"grid\\\", \\\"square\\\", \\\"rect\\\" -- optimal rectangle\\\
        --    \\\"2cols\\\", \\\"2deep\\\" -- 2 columns, n deep \\\
        --    \\\"2wide\\\" -- 2 columns wide, 2 deep \\\
\\\
        local num = #theNewGroup.units \\\
        \\\
        -- now do the formation stuff\\\
        -- make sure that they keep minimum  distance \\\
--        trigger.action.outText(\\\"dcsCommon - processing formation \\\" .. formation .. \\\" with radius = \\\" .. radius, 30)\\\
        if formation == \\\"LINE_V\\\" then \\\
            -- top to bottom in zone (heding 0). -- will run through x-coordinate \\\
            -- use entire radius top to bottom \\\
            local currX = -radius\\\
            local increment = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\\\
            for i=1, num do\\\
            \\\
                local u = theNewGroup.units[i]\\\
--                trigger.action.outText(\\\"formation unit \\\" .. u.name .. \\\" currX = \\\" .. currX, 30)\\\
                u.x = currX\\\
                currX = currX + increment\\\
            end\\\
        \\\
        elseif formation == \\\"LINE\\\" then \\\
            -- left to right in zone. runs through Y\\\
            -- left and right are y because at heading 0, forward is x (not y as expected)\\\
            -- if only one, place in middle of circle and be done \\\
            if num == 1 then \\\
                -- nothing. just stay in the middle \\\
            else \\\
                local currY = -radius\\\
                local increment = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\\\
                for i=1, num do\\\
                    local u = theNewGroup.units[i]\\\
--                    trigger.action.outText(\\\"formation unit \\\" .. u.name .. \\\" currX = \\\" .. currY, 30)\\\
                    u.y = currY\\\
                    currY = currY + increment\\\
                end    \\\
            end \\\
            \\\
        elseif formation == \\\"CHEVRON\\\" then \\\
            -- left to right in zone. runs through Y\\\
            -- left and right are y because at heading 0, forward is x (not y as expected)\\\
            local currY = -radius\\\
            local currX = 0\\\
            local incrementY = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\\\
            local incrementX = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\\\
            for i=1, num do\\\
                local u = theNewGroup.units[i]\\\
--                trigger.action.outText(\\\"formation unit \\\" .. u.name .. \\\" currX = \\\" .. currX .. \\\" currY = \\\" .. currY, 30)\\\
                u.x = currX\\\
                u.y = currY\\\
                -- calc coords for NEXT iteration\\\
                currY = currY + incrementY -- march left to right\\\
                if i < num / 2 then -- march up\\\
                    currX = currX + incrementX \\\
                elseif i == num / 2 then -- even number, keep height\\\
                    currX = currX + 0 \\\
                else \\\
                    currX = currX - incrementX -- march down \\\
                end \\\
                -- note: when unit number even, the wedge is sloped. may need an odd/even test for better looks\\\
            end    \\\
\\\
        elseif formation == \\\"SCATTERED\\\" or formation == \\\"RANDOM\\\" then \\\
            -- use randomPointInCircle and tehn iterate over all vehicles for mindelta\\\
            processedUnits = {}\\\
            for i=1, num do\\\
                local emergencyBreak = 1 -- prevent endless loop\\\
                local lowDist = 10000\\\
                local uPoint = {}\\\
                local thePoint = {}\\\
                repeat     -- get random point intil mindistance to all is kept or emergencybreak\\\
                    for idx, rUnit in pairs(processedUnits) do -- get min dist to all positioned units\\\
                        thePoint = dcsCommon.randomPointInCircle(radius, innerRadius) -- returns x, 0, z\\\
                        uPoint.x = rUnit.x\\\
                        uPoint.y = 0\\\
                        uPoint.z = rUnit.y \\\
                        local dist = dcsCommon.dist(thePoint, uPoint) -- measure distance to unit\\\
                        if (dist < lowDist) then lowDist = dist end\\\
                    end\\\
                    emergencyBreak = emergencyBreak + 1\\\
                until (emergencyBreak > 20) or (lowDist > minDist)\\\
                -- we have random x, y \\\
                local u = theNewGroup.units[i] -- get unit to position\\\
                u.x = thePoint.x\\\
                u.y = thePoint.z -- z --> y mapping! \\\
                -- now add the unit to the 'processed' set \\\
                table.insert(processedUnits, u)\\\
            end    \\\
\\\
        elseif dcsCommon.stringStartsWith(formation, \\\"CIRCLE\\\") then\\\
            -- units are arranged on perimeter of circle defined by radius \\\
--            trigger.action.outText(\\\"formation circle detected\\\", 30)\\\
            local currAngle = 0\\\
            local angleInc = 2 * 3.14157 / num -- increase per spoke \\\
            for i=1, num do\\\
                local u = theNewGroup.units[i] -- get unit \\\
                u.x = radius * math.cos(currAngle)\\\
                u.y = radius * math.sin(currAngle)\\\
                \\\
                -- now baldower out heading \\\
                -- circle, circle_forward no modifier of heading\\\
                if dcsCommon.stringStartsWith(formation, \\\"CIRCLE_IN\\\") then \\\
                    -- make the heading inward faceing - that's angle + pi\\\
                    u.heading = u.heading + currAngle + 3.14157\\\
                elseif dcsCommon.stringStartsWith(formation, \\\"CIRCLE_OUT\\\") then \\\
                    u.heading = u.heading + currAngle + 0\\\
                end\\\
\\\
                currAngle = currAngle + angleInc\\\
            end\\\
        elseif formation == \\\"GRID\\\" or formation == \\\"SQUARE\\\" or formation == \\\"RECT\\\" then \\\
            if num < 2 then return end \\\
            -- arrange units in an w x h grid\\\
            -- e-g- 12 units = 4 x 3. \\\
            -- calculate w \\\
            local w = math.floor(num^(0.5) + 0.5)\\\
            dcsCommon.arrangeGroupInNColumns(theNewGroup, w, radius)\\\
            --[[--\\\
            local h = math.floor(num / w)\\\
            --trigger.action.outText(\\\"AdcsC: num=\\\" .. num .. \\\" w=\\\" .. w .. \\\"h=\\\" .. h .. \\\" -- num%w=\\\" .. num%w, 30)\\\
            if (num % w) > 0 then \\\
                h = h + 1\\\
            end\\\
            \\\
            --trigger.action.outText(\\\"BdcsC: num=\\\" .. num .. \\\" w=\\\" .. w .. \\\"h=\\\" .. h, 30)\\\
            \\\
            -- now w * h always >= num and num items fir in that grid\\\
            -- w is width, h is height, of course :) \\\
            -- now calculat xInc and yInc\\\
            local i = 1\\\
            local xInc = 0 \\\
            if w > 1 then xInc = 2 * radius / (w-1) end\\\
            local yInc = 0\\\
            if h > 1 then yInc = 2 * radius / (h-1) end \\\
            local currY = radius \\\
            if h < 2 then currY = 0 end -- special:_ place in Y middle if only one row)\\\
            while h > 0 do \\\
                local currX = radius \\\
                local wCnt = w \\\
                while wCnt > 0 and (i <= num) do \\\
                    local u = theNewGroup.units[i] -- get unit \\\
                    u.x = currX\\\
                    u.y = currY\\\
                    currX = currX - xInc\\\
                    wCnt = wCnt - 1\\\
                    i = i + 1\\\
                end\\\
                currY = currY - yInc \\\
                h = h - 1\\\
            end\\\
            --]]--\\\
        elseif formation == \\\"2DEEP\\\" or formation == \\\"2COLS\\\" then\\\
            if num < 2 then return end \\\
            -- arrange units in an 2 x h grid\\\
            local w = 2\\\
            dcsCommon.arrangeGroupInNColumnsDeep(theNewGroup, w, radius)\\\
\\\
        elseif formation == \\\"2WIDE\\\" then\\\
            if num < 2 then return end \\\
            -- arrange units in an 2 x h grid\\\
            local w = 2\\\
            dcsCommon.arrangeGroupInNColumns(theNewGroup, w, radius)\\\
        else \\\
            trigger.action.outText(\\\"dcsCommon - unknown formation: \\\" .. formation, 30)\\\
        end\\\
    \\\
    end\\\
    \\\
    function dcsCommon.arrangeGroupInNColumns(theNewGroup, w, radius)\\\
        local num = #theNewGroup.units\\\
        local h = math.floor(num / w)\\\
        if (num % w) > 0 then \\\
            h = h + 1\\\
        end\\\
        local i = 1\\\
        local xInc = 0 \\\
        if w > 1 then xInc = 2 * radius / (w-1) end\\\
        local yInc = 0\\\
        if h > 1 then yInc = 2 * radius / (h-1) end \\\
        local currY = radius \\\
        if h < 2 then currY = 0 end -- special:_ place in Y middle if only one row)\\\
        while h > 0 do \\\
            local currX = radius \\\
            local wCnt = w \\\
            while wCnt > 0 and (i <= num) do \\\
                local u = theNewGroup.units[i] -- get unit \\\
                u.x = currX\\\
                u.y = currY\\\
                currX = currX - xInc\\\
                wCnt = wCnt - 1\\\
                i = i + 1\\\
            end\\\
            currY = currY - yInc \\\
            h = h - 1\\\
        end\\\
    end\\\
    \\\
    function dcsCommon.arrangeGroupInNColumnsDeep(theNewGroup, w, radius)\\\
        local num = #theNewGroup.units\\\
        local h = math.floor(num / w)\\\
        if (num % w) > 0 then \\\
            h = h + 1\\\
        end\\\
        local i = 1\\\
        local yInc = 0 \\\
        if w > 1 then yInc = 2 * radius / (w-1) end\\\
        local xInc = 0\\\
        if h > 1 then xInc = 2 * radius / (h-1) end \\\
        local currX = radius \\\
        if h < 2 then currX = 0 end -- special:_ place in Y middle if only one row)\\\
        while h > 0 do \\\
            local currY = radius \\\
            local wCnt = w \\\
            while wCnt > 0 and (i <= num) do \\\
                local u = theNewGroup.units[i] -- get unit \\\
                u.x = currX\\\
                u.y = currY\\\
                currY = currY - yInc\\\
                wCnt = wCnt - 1\\\
                i = i + 1\\\
            end\\\
            currX = currX - xInc \\\
            h = h - 1\\\
        end\\\
    end\\\
    \\\
    \\\
    function dcsCommon.createGroundGroupWithUnits(name, theUnitTypes, radius, minDist, formation, innerRadius)\\\
        if not minDist then mindist = 4 end -- meters\\\
        if not formation then formation = \\\"line\\\" end \\\
        if not radius then radius = 30 end -- meters \\\
        if not innerRadius then innerRadius = 0 end\\\
        formation = formation:upper()\\\
        -- theUnitTypes can be either a single string or a table of strings\\\
        -- see here for TypeName https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB\\\
        -- formation defines how the units are going to be arranged in the\\\
        -- formation specified. \\\
        -- formations:\\\
        --    (default) \\\"line\\\" (left to right along x) -- that is Y direction\\\
        --    \\\"line_V\\\" a line top to bottom -- that is X direction\\\
        --    \\\"chevron\\\" - left to right middle too top\\\
        --    \\\"scattered\\\", \\\"random\\\" -- random, innerRadius used to clear area in center\\\
        --       \\\"circle\\\", \\\"circle_forward\\\" -- circle, forward facing\\\
        --    \\\"circle_in\\\" -- circle, inwarf facing\\\
        --    \\\"circle_out\\\" -- circle, outward facing\\\
\\\
        -- first, we create a group\\\
        local theNewGroup = dcsCommon.createEmptyGroundGroupData(name)\\\
        \\\
        -- now add a single unit or multiple units\\\
        if type(theUnitTypes) ~= \\\"table\\\" then \\\
--            trigger.action.outText(\\\"dcsCommon - i am here\\\", 30)\\\
--            trigger.action.outText(\\\"dcsCommon - name \\\" .. name, 30)\\\
--            trigger.action.outText(\\\"dcsCommon - unit type \\\" .. theUnitTypes, 30)\\\
            \\\
            local aUnit = {}\\\
            aUnit = dcsCommon.createGroundUnitData(name .. \\\"-1\\\", theUnitTypes, false)\\\
--            trigger.action.outText(\\\"dcsCommon - unit name retval \\\" .. aUnit.name, 30)\\\
            dcsCommon.addUnitToGroupData(aUnit, theNewGroup, 0, 0) -- create with data at location (0,0)\\\
            return theNewGroup\\\
        end \\\
\\\
        -- if we get here, theUnitTypes is a table\\\
        -- now loop and create a unit for each table\\\
        local num = 1\\\
        for key, theType in pairs(theUnitTypes) do \\\
            -- trigger.action.outText(\\\"+++dcsC: creating unit \\\" .. name .. \\\"-\\\" .. num .. \\\": \\\" .. theType, 30)\\\
            local aUnit = dcsCommon.createGroundUnitData(name .. \\\"-\\\"..num, theType, false)\\\
            dcsCommon.addUnitToGroupData(aUnit, theNewGroup, 0, 0)\\\
            num = num + 1\\\
        end\\\
        \\\
        dcsCommon.arrangeGroupDataIntoFormation(theNewGroup, radius, minDist, formation, innerRadius)\\\
        return theNewGroup\\\
\\\
    \\\
    end\\\
\\\
-- create a new group, based on group in mission. Groups coords are 0,0 for group and all\\\
-- x,y and heading\\\
    function dcsCommon.createGroupDataFromLiveGroup(name, newName) \\\
        if not newName then newName = dcsCommon.uuid(\\\"uniqName\\\") end\\\
        -- get access to the group\\\
        local liveGroup = Group.getByName(name)\\\
        if not liveGroup then return nil end\\\
        -- get the categorty\\\
        local cat = liveGroup:getCategory()\\\
        local theNewGroup = {}\\\
        \\\
        -- create a new empty group at (0,0) \\\
        if cat == Group.Category.AIRPLANE or cat == Group.Category.HELICOPTER then \\\
            theNewGroup = dcsCommon.createEmptyAircraftGroupData(newName)\\\
        elseif cat == Group.Category.GROUND then\\\
            theNewGroup = dcsCommon.createEmptyGroudGroupData(newName)\\\
        else \\\
            trigger.action.outText(\\\"dcsCommon - unknown category: \\\" .. cat, 30)\\\
            return nil\\\
        end\\\
        \\\
\\\
        -- now get all units from live group and create data units\\\
        -- note that unit data for group has x=0, y=0\\\
        liveUnits = liveGroup:getUnits()\\\
        \\\
        for index, theUnit in pairs(liveUnits) do \\\
            -- for each unit we get the desc \\\
            local desc = theUnit:getDesc() -- of interest is only typename \\\
            local newUnit = dcsCommon.createGroundUnitData(dcsCommon.uuid(newName),\\\
                                                           desc.typeName,\\\
                                                           false)\\\
            -- we now basically have a ground unit at (0,0) \\\
            -- add mandatory fields by type\\\
            if cat == Group.Category.AIRPLANE or cat == Group.Category.HELICOPTER then \\\
                newUnit.alt = 100 -- make it 100m\\\
                newUnit.alt_type = \\\"RADIO\\\" -- AGL\\\
                newUnit.speed = 77 -- m/s --> 150 knots\\\
                newUnit.payload = dcsCommon.createPayload() -- empty payload\\\
                newUnit.callsign = dcsCommon.createCallsign() -- 'enfield11'\\\
                \\\
            elseif cat == Group.Category.GROUND then\\\
                -- we got all we need\\\
            else \\\
                -- trigger.action.outText(\\\"dcsCommon - unknown category: \\\" .. cat, 30)\\\
                -- return nil\\\
                -- we also got all we need\\\
            end            \\\
            \\\
        end\\\
    \\\
    end;\\\
    \\\
\\\
    function dcsCommon.rotatePointAroundOrigin(inX, inY, angle) -- angle in degrees\\\
        local degrees =  3.14152 / 180 -- ok, it's actually radiants. \\\
        angle = angle * degrees -- turns into rads\\\
        local c = math.cos(angle)\\\
        local s = math.sin(angle)\\\
        local px\\\
        local py \\\
        px = inX * c - inY * s\\\
        py = inX * s + inY * c\\\
        return px, py        \\\
    end\\\
\\\
    function dcsCommon.rotateUnitData(theUnit, degrees, cx, cy)\\\
        if not cx then cx = 0 end\\\
        if not cz then cz = 0 end\\\
        local cy = cz \\\
        --trigger.action.outText(\\\"+++dcsC:rotGrp cy,cy = \\\"..cx .. \\\",\\\" .. cy, 30)\\\
        \\\
        local rads = degrees *  3.14152 / 180\\\
        do\\\
            theUnit.x = theUnit.x - cx -- MOVE TO ORIGIN OF ROTATION\\\
            theUnit.y = theUnit.y - cy                 \\\
            theUnit.x, theUnit.y = dcsCommon.rotatePointAroundOrigin(theUnit.x, theUnit.y, degrees)\\\
            theUnit.x = theUnit.x + cx -- MOVE BACK \\\
            theUnit.y = theUnit.y + cy                 \\\
\\\
            -- may also want to increase heading by degreess\\\
            theUnit.heading = theUnit.heading + rads \\\
        end\\\
    end\\\
    \\\
\\\
    function dcsCommon.rotateGroupData(theGroup, degrees, cx, cz)\\\
        if not cx then cx = 0 end\\\
        if not cz then cz = 0 end\\\
        local cy = cz \\\
        --trigger.action.outText(\\\"+++dcsC:rotGrp cy,cy = \\\"..cx .. \\\",\\\" .. cy, 30)\\\
        \\\
        local rads = degrees *  3.14152 / 180\\\
        -- turns all units in group around the group's center by degrees.\\\
        -- may also need to turn individual units by same amount\\\
        for i, theUnit in pairs (theGroup.units) do\\\
            theUnit.x = theUnit.x - cx -- MOVE TO ORIGIN OF ROTATION\\\
            theUnit.y = theUnit.y - cy                 \\\
            theUnit.x, theUnit.y = dcsCommon.rotatePointAroundOrigin(theUnit.x, theUnit.y, degrees)\\\
            theUnit.x = theUnit.x + cx -- MOVE BACK \\\
            theUnit.y = theUnit.y + cy                 \\\
\\\
            -- may also want to increase heading by degreess\\\
            theUnit.heading = theUnit.heading + rads \\\
        end\\\
    end\\\
\\\
    function dcsCommon.offsetGroupData(theGroup, dx, dy)\\\
        -- add dx and dy to group's and all unit's coords\\\
        for i, theUnit in pairs (theGroup.units) do \\\
            theUnit.x = theUnit.x + dx\\\
            theUnit.y = theUnit.y + dy\\\
        end\\\
        \\\
        theGroup.x = theGroup.x + dx\\\
        theGroup.y = theGroup.y + dy \\\
    end\\\
    \\\
    function dcsCommon.moveGroupDataTo(theGroup, xAbs, yAbs)\\\
        local dx = xAbs-theGroup.x\\\
        local dy = yAbs-theGroup.y\\\
        dcsCommon.offsetGroupData(theGroup, dx, dy)\\\
    end\\\
    \\\
    -- static objectr shapes and types are defined here\\\
    -- https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB/Statics\\\
    \\\
    function dcsCommon.createStaticObjectData(name, objType, heading, dead, cargo, mass)\\\
        local staticObj = {}\\\
        if not heading then heading = 0 end \\\
        if not dead then dead = false end \\\
        if not cargo then cargo = false end \\\
        objType = dcsCommon.trim(objType) \\\
        \\\
        staticObj.heading = heading\\\
        -- staticObj.groupId = 0\\\
        -- staticObj.shape_name = shape -- e.g. H-Windsock_RW\\\
        staticObj.type = objType  -- e.g. Windsock\\\
        -- [\\\"unitId\\\"] = 3,\\\
        staticObj.rate = 1 -- score when killed\\\
        staticObj.name = name\\\
        -- staticObj.category = \\\"Fortifications\\\",\\\
        staticObj.y = 0\\\
        staticObj.x = 0\\\
        staticObj.dead = dead\\\
        staticObj.canCargo = cargo -- to cargo\\\
        if cargo then \\\
            if not mass then mass = 1234 end \\\
            staticObj.mass = mass -- to cargo\\\
        end\\\
        return staticObj\\\
    end\\\
    \\\
    function dcsCommon.createStaticObjectDataAt(loc, name, objType, heading, dead)\\\
        local theData = dcsCommon.createStaticObjectData(name, objType, heading, dead)\\\
        theData.x = loc.x\\\
        theData.y = loc.z \\\
        return theData\\\
    end\\\
    \\\
    function dcsCommon.createStaticObjectForCoalitionAtLocation(theCoalition, loc, name, objType, heading, dead) \\\
        if not heading then heading = math.random(360) * 3.1415 / 180 end\\\
        local theData = dcsCommon.createStaticObjectDataAt(loc, name, objType, heading, dead)\\\
        local theStatic = coalition.addStaticObject(theCoalition, theData)\\\
        return theStatic\\\
    end\\\
    \\\
    function dcsCommon.createStaticObjectForCoalitionInRandomRing(theCoalition, objType, x, z, innerRadius, outerRadius, heading, alive) \\\
        if not outerRadius then outerRadius = innerRadius end\\\
        if not heading then heading = math.random(360) * 3.1415 / 180 end\\\
        local dead = not alive\\\
        local p = dcsCommon.randomPointInCircle(outerRadius, innerRadius, x, z)\\\
        local theData = dcsCommon.createStaticObjectData(dcsCommon.uuid(\\\"static\\\"), objType, heading, dead)\\\
        theData.x = p.x\\\
        theData.y = p.z \\\
        \\\
        local theStatic = coalition.addStaticObject(theCoalition, theData)\\\
        return theStatic\\\
    end\\\
    \\\
    \\\
    \\\
    function dcsCommon.linkStaticDataToUnit(theStatic, theUnit, dx, dy, heading)\\\
        if not theStatic then \\\
            trigger.action.OutText(\\\"+++dcsC: NIL theStatic on linkStatic!\\\", 30)\\\
            return \\\
        end\\\
        -- NOTE: we may get current heading and subtract/add \\\
        -- to original heading \\\
        local rotX, rotY = dcsCommon.rotatePointAroundOrigin(dx, dy, -heading)\\\
        \\\
        if not theUnit then return end\\\
        if not theUnit:isExist() then return end \\\
        theStatic.linkOffset = true \\\
        theStatic.linkUnit = theUnit:getID()\\\
        local unitPos = theUnit:getPoint()\\\
        local offsets = {}\\\
        offsets.x = rotX  \\\
        offsets.y = rotY \\\
        offsets.angle = 0\\\
        theStatic.offsets = offsets\\\
    end\\\
    \\\
    function dcsCommon.offsetStaticData(theStatic, dx, dy)\\\
        theStatic.x = theStatic.x + dx\\\
        theStatic.y = theStatic.y + dy\\\
        -- now check if thre is a route (for linked objects)\\\
        if theStatic.route then \\\
            -- access points[1] x and y and copy from main\\\
            theStatic.route.points[1].x = theStatic.x\\\
            theStatic.route.points[1].y = theStatic.y\\\
        end\\\
    end\\\
    \\\
    function dcsCommon.moveStaticDataTo(theStatic, x, y)\\\
        theStatic.x = x\\\
        theStatic.y = y\\\
        -- now check if thre is a route (for linked objects)\\\
        if theStatic.route then \\\
            -- access points[1] x and y and copy from main\\\
            theStatic.route.points[1].x = theStatic.x\\\
            theStatic.route.points[1].y = theStatic.y\\\
        end\\\
\\\
    end\\\
    \\\
--\\\
--\\\
-- M I S C   M E T H O D S \\\
--\\\
--\\\
\\\
    function dcsCommon.arrayContainsString(theArray, theString) \\\
        if not theArray then return false end\\\
        if not theString then return false end\\\
        for i = 1, #theArray do \\\
            if theArray[i] == theString then return true end \\\
        end\\\
        return false \\\
    end\\\
    \\\
    function dcsCommon.splitString(inputstr, sep) \\\
        if sep == nil then\\\
            sep = \\\"%s\\\"\\\
        end\\\
        if inputstr == nil then \\\
            inputstr = \\\"\\\"\\\
        end\\\
        \\\
        local t={}\\\
        for str in string.gmatch(inputstr, \\\"([^\\\"..sep..\\\"]+)\\\") do\\\
            table.insert(t, str)\\\
        end\\\
        return t\\\
    \\\
    end\\\
    \\\
    function dcsCommon.trimFront(inputstr) \\\
        if not inputstr then return nil end \\\
        local s = inputstr\\\
        while string.len(s) > 1 and string.sub(s, 1, 1) == \\\" \\\" do \\\
            local snew = string.sub(s, 2) -- all except first\\\
            s = snew\\\
        end\\\
        return s\\\
    end\\\
    \\\
    function dcsCommon.trimBack(inputstr)\\\
        if not inputstr then return nil end \\\
        local s = inputstr\\\
        while string.len(s) > 1 and string.sub(s, -1) == \\\" \\\" do \\\
            local snew = string.sub(s, 1, -2) -- all except last\\\
            s = snew\\\
        end\\\
        return s\\\
    end\\\
    \\\
    function dcsCommon.trim(inputstr) \\\
        local t1 = dcsCommon.trimFront(inputstr)\\\
        local t2 = dcsCommon.trimBack(t1)\\\
        return t2\\\
    end\\\
    \\\
    function dcsCommon.trimArray(theArray)\\\
        local trimmedArray = {}\\\
        for idx, element in pairs(theArray) do \\\
            local tel = dcsCommon.trim(element)\\\
            table.insert(trimmedArray, tel)\\\
        end\\\
        return trimmedArray\\\
    end\\\
    \\\
    function dcsCommon.stringIsPositiveNumber(theString)\\\
        -- only full integer positive numbers supported \\\
        if not theString then return false end \\\
--        if theString == \\\"\\\" then return false end \\\
        for i = 1, #theString do \\\
            local c = theString:sub(i,i)\\\
            if c < \\\"0\\\" or c > \\\"9\\\" then return false end \\\
        end\\\
        return true \\\
    end\\\
    \\\
    function dcsCommon.stringStartsWithDigit(theString)\\\
        if #theString < 1 then return false end \\\
        local c = string.sub(theString, 1, 1) \\\
        return c >= \\\"0\\\" and c <= \\\"9\\\" \\\
    end\\\
    \\\
    function dcsCommon.stringStartsWithLetter(theString)\\\
        if #theString < 1 then return false end \\\
        local c = string.sub(theString, 1, 1)\\\
        if c >= \\\"a\\\" and c <= \\\"z\\\" then return true end  \\\
        if c >= \\\"A\\\" and c <= \\\"Z\\\" then return true end \\\
        return false \\\
    end\\\
    \\\
    function dcsCommon.stringStartsWith(theString, thePrefix)\\\
        return theString:find(thePrefix) == 1\\\
    end\\\
    \\\
    function dcsCommon.removePrefix(theString, thePrefix)\\\
        if not dcsCommon.stringStartsWith(theString, thePrefix) then \\\
            return theString\\\
        end;\\\
        return theString:sub(1 + #thePrefix)\\\
    end\\\
    \\\
    function dcsCommon.stringEndsWith(theString, theEnding)\\\
        return theEnding == \\\"\\\" or theString:sub(-#theEnding) == theEnding\\\
    end\\\
    \\\
    function dcsCommon.removeEnding(theString, theEnding) \\\
        if not dcsCommon.stringEndsWith(theString, theEnding) then \\\
            return theString\\\
        end\\\
        return theString:sub(1, #theString - #theEnding)\\\
    end\\\
    \\\
    function dcsCommon.containsString(inString, what, caseSensitive)\\\
        if (not caseSensitive) then \\\
            inString = string.upper(inString)\\\
            what = string.upper(what)\\\
        end\\\
        if inString == what then return true end -- when entire match \\\
        return string.find(inString, what)\\\
    end\\\
    \\\
    function dcsCommon.bool2Text(theBool) \\\
        if not theBool then theBool = false end \\\
        if theBool then return \\\"true\\\" end \\\
        return \\\"false\\\"\\\
    end\\\
    \\\
    function dcsCommon.bool2YesNo(theBool)\\\
        if not theBool then theBool = false end \\\
        if theBool then return \\\"yes\\\" end \\\
        return \\\"no\\\"\\\
    end\\\
\\\
    -- recursively show the contents of a variable\\\
    function dcsCommon.dumpVar(key, value, prefix, inrecursion)\\\
        if not inrecursion then \\\
            -- output a marker to find in the log / screen\\\
            env.info(\\\"*** dcsCommon vardump START\\\")\\\
        end\\\
        if not value then value = \\\"nil\\\" end\\\
        if not prefix then prefix = \\\"\\\" end\\\
        prefix = \\\" \\\" .. prefix\\\
        if type(value) == \\\"table\\\" then \\\
            env.info(prefix .. key .. \\\": [ \\\")\\\
            -- iterate through all kvp\\\
            for k,v in pairs (value) do\\\
                dcsCommon.dumpVar(k, v, prefix, true)\\\
            end\\\
            env.info(prefix .. \\\" ] - end \\\" .. key)\\\
            \\\
        elseif type(value) == \\\"boolean\\\" then \\\
            local b = \\\"false\\\"\\\
            if value then b = \\\"true\\\" end\\\
            env.info(prefix .. key .. \\\": \\\" .. b)\\\
            \\\
        else -- simple var, show contents, ends recursion\\\
            env.info(prefix .. key .. \\\": \\\" .. value)\\\
        end\\\
        \\\
        if not inrecursion then \\\
            -- output a marker to find in the log / screen\\\
            trigger.action.outText(\\\"=== dcsCommon vardump END\\\", 30)\\\
            env.info(\\\"=== dcsCommon vardump END\\\")\\\
        end\\\
    end\\\
    \\\
    function dcsCommon.dumpVar2Str(key, value, prefix, inrecursion)\\\
        if not inrecursion then \\\
            -- output a marker to find in the log / screen\\\
            trigger.action.outText(\\\"*** dcsCommon vardump START\\\",30)\\\
        end\\\
        if not value then value = \\\"nil\\\" end\\\
        if not prefix then prefix = \\\"\\\" end\\\
        prefix = \\\" \\\" .. prefix\\\
        if type(value) == \\\"table\\\" then \\\
            trigger.action.outText(prefix .. key .. \\\": [ \\\", 30)\\\
            -- iterate through all kvp\\\
            for k,v in pairs (value) do\\\
                dcsCommon.dumpVar2Str(k, v, prefix, true)\\\
            end\\\
            trigger.action.outText(prefix .. \\\" ] - end \\\" .. key, 30)\\\
            \\\
        elseif type(value) == \\\"boolean\\\" then \\\
            local b = \\\"false\\\"\\\
            if value then b = \\\"true\\\" end\\\
            trigger.action.outText(prefix .. key .. \\\": \\\" .. b, 30)\\\
            \\\
        else -- simple var, show contents, ends recursion\\\
            trigger.action.outText(prefix .. key .. \\\": \\\" .. value, 30)\\\
        end\\\
        \\\
        if not inrecursion then \\\
            -- output a marker to find in the log / screen\\\
            trigger.action.outText(\\\"=== dcsCommon vardump END\\\", 30)\\\
            --env.info(\\\"=== dcsCommon vardump END\\\")\\\
        end\\\
    end\\\
    \\\
\\\
    dcsCommon.simpleUUID = 76543 -- a number to start. as good as any\\\
    function dcsCommon.numberUUID()\\\
        dcsCommon.simpleUUID = dcsCommon.simpleUUID + 1\\\
        return dcsCommon.simpleUUID\\\
    end\\\
\\\
    function dcsCommon.uuid(prefix)\\\
        dcsCommon.uuIdent = dcsCommon.uuIdent + 1\\\
        if not prefix then prefix = dcsCommon.uuidStr end\\\
        return prefix .. \\\"-\\\" .. dcsCommon.uuIdent\\\
    end\\\
    \\\
    function dcsCommon.event2text(id) \\\
        if not id then return \\\"error\\\" end\\\
        if id == 0 then return \\\"invalid\\\" end\\\
        -- translate the event id to text\\\
        local events = {\\\"shot\\\", \\\"hit\\\", \\\"takeoff\\\", \\\"land\\\",\\\
                        \\\"crash\\\", \\\"eject\\\", \\\"refuel\\\", \\\"dead\\\",\\\
                        \\\"pilot dead\\\", \\\"base captured\\\", \\\"mission start\\\", \\\"mission end\\\", -- 12\\\
                        \\\"took control\\\", \\\"refuel stop\\\", \\\"birth\\\", \\\"human failure\\\", \\\
                        \\\"det. failure\\\", \\\"engine start\\\", \\\"engine stop\\\", \\\"player enter unit\\\",\\\
                        \\\"player leave unit\\\", \\\"player comment\\\", \\\"start shoot\\\", \\\"end shoot\\\",\\\
                        \\\"mark add\\\", \\\"mark changed\\\", \\\"makr removed\\\", \\\"kill\\\", \\\
                        \\\"score\\\", \\\"unit lost\\\", \\\"land after eject\\\", \\\"Paratrooper land\\\", \\\
                        \\\"chair discard after eject\\\", \\\"weapon add\\\", \\\"trigger zone\\\", \\\"landing quality mark\\\",\\\
                        \\\"BDA\\\", \\\"max\\\"}\\\
        if id > #events then return \\\"Unknown (ID=\\\" .. id .. \\\")\\\" end\\\
        return events[id]\\\
    end\\\
\\\
    function dcsCommon.smokeColor2Text(smokeColor)\\\
        if (smokeColor == 0) then return \\\"Green\\\" end\\\
        if (smokeColor == 1) then return \\\"Red\\\" end\\\
        if (smokeColor == 2) then return \\\"White\\\" end\\\
        if (smokeColor == 3) then return \\\"Orange\\\" end\\\
        if (smokeColor == 4) then return \\\"Blue\\\" end\\\
        \\\
        return (\\\"unknown: \\\" .. smokeColor)\\\
    end\\\
    \\\
    function dcsCommon.smokeColor2Num(smokeColor)\\\
        if not smokeColor then smokeColor = \\\"green\\\" end \\\
        if type(smokeColor) ~= \\\"string\\\" then return 0 end \\\
        smokeColor = smokeColor:lower()\\\
        if (smokeColor == \\\"green\\\") then return 0 end \\\
        if (smokeColor == \\\"red\\\") then return 1 end \\\
        if (smokeColor == \\\"white\\\") then return 2 end \\\
        if (smokeColor == \\\"orange\\\") then return 3 end \\\
        if (smokeColor == \\\"blue\\\") then return 4 end \\\
        return 0\\\
    end\\\
    \\\
    function dcsCommon.markPointWithSmoke(p, smokeColor)\\\
        local x = p.x \\\
        local z = p.z -- do NOT change the point directly\\\
        -- height-correct\\\
        local y = land.getHeight({x = x, y = z})\\\
        local newPoint= {x = x, y = y + 2, z = z}\\\
        trigger.action.smoke(newPoint, smokeColor)\\\
    end\\\
\\\
--\\\
--\\\
-- V E C T O R   M A T H \\\
--\\\
--\\\
function dcsCommon.vAdd(a, b) \\\
    local r = {}\\\
    if not a then a = {x = 0, y = 0, z = 0} end\\\
    if not b then b = {x = 0, y = 0, z = 0} end\\\
    r.x = a.x + b.x \\\
    r.y = a.y + b.y \\\
    r.z = a.z + b.z \\\
    return r \\\
end\\\
\\\
function dcsCommon.vSub(a, b) \\\
    local r = {}\\\
    if not a then a = {x = 0, y = 0, z = 0} end\\\
    if not b then b = {x = 0, y = 0, z = 0} end\\\
    r.x = a.x - b.x \\\
    r.y = a.y - b.y \\\
    r.z = a.z - b.z \\\
    return r \\\
end\\\
\\\
function dcsCommon.vMultScalar(a, f) \\\
    local r = {}\\\
    if not a then a = {x = 0, y = 0, z = 0} end\\\
    if not f then f = 0 end\\\
    r.x = a.x * f \\\
    r.y = a.y * f \\\
    r.z = a.z * f \\\
    return r \\\
end\\\
\\\
function dcsCommon.vLerp (a, b, t)\\\
    if not a then a = {x = 0, y = 0, z = 0} end\\\
    if not b then b = {x = 0, y = 0, z = 0} end\\\
    \\\
    local d = dcsCommon.vSub(b, a)\\\
    local dt = dcsCommon.vMultScalar(d, t)\\\
    local r = dcsCommon.vAdd(a, dt)\\\
    return r\\\
end\\\
\\\
function dcsCommon.mag(x, y, z) \\\
    if not x then x = 0 end\\\
    if not y then y = 0 end \\\
    if not z then z = 0 end \\\
    \\\
    return (x * x + y * y + z * z)^0.5\\\
end\\\
\\\
function dcsCommon.vMag(a) \\\
    if not a then return 0 end \\\
    if not a.x then a.x = 0 end \\\
    if not a.y then a.y = 0 end \\\
    if not a.z then a.z = 0 end\\\
    return dcsCommon.mag(a.x, a.y, a.z) \\\
end\\\
\\\
function dcsCommon.magSquare(x, y, z) \\\
    if not x then x = 0 end\\\
    if not y then y = 0 end \\\
    if not z then z = 0 end \\\
    \\\
    return (x * x + y * y + z * z)\\\
end\\\
\\\
function dcsCommon.vNorm(a) \\\
    if not a then return {x = 0, y = 0, z = 0} end \\\
    m = dcsCommon.vMag(a)\\\
    if m <= 0 then return {x = 0, y = 0, z = 0} end \\\
    local r = {}\\\
    r.x = a.x / m \\\
    r.y = a.y / m \\\
    r.z = a.z / m\\\
    return r \\\
end\\\
\\\
function dcsCommon.dot (a, b) \\\
    if not a then a = {} end \\\
    if not a.x then a.x = 0 end \\\
    if not a.y then a.y = 0 end \\\
    if not a.z then a.z = 0 end\\\
    if not b then b = {} end \\\
    if not b.x then b.x = 0 end \\\
    if not b.y then b.y = 0 end \\\
    if not b.z then b.z = 0 end \\\
    \\\
    return a.x * b.x + a.y * b.y + a.z * b.z \\\
end\\\
--\\\
-- UNIT MISC\\\
-- \\\
function dcsCommon.isSceneryObject(theUnit)\\\
    if not theUnit then return false end\\\
    return theUnit.getCoalition == nil -- scenery objects do not return a coalition \\\
end\\\
\\\
function dcsCommon.isTroopCarrier(theUnit)\\\
    -- return true if conf can carry troups\\\
    if not theUnit then return false end \\\
    local uType = theUnit:getTypeName()\\\
    if dcsCommon.arrayContainsString(dcsCommon.troopCarriers, uType) then \\\
        -- may add additional tests before returning true\\\
        return true\\\
    end\\\
    return false\\\
end\\\
\\\
function dcsCommon.getUnitAlt(theUnit)\\\
    if not theUnit then return 0 end\\\
    if not theUnit:isExist() then return 0 end \\\
    local p = theUnit:getPoint()\\\
    return p.y \\\
end\\\
\\\
function dcsCommon.getUnitAGL(theUnit)\\\
    if not theUnit then return 0 end\\\
    if not theUnit:isExist() then return 0 end \\\
    local p = theUnit:getPoint()\\\
    local alt = p.y \\\
    local loc = {x = p.x, y = p.z}\\\
    local landElev = land.getHeight(loc)\\\
    return alt - landElev\\\
end \\\
\\\
function dcsCommon.getUnitSpeed(theUnit)\\\
    if not theUnit then return 0 end\\\
    if not theUnit:isExist() then return 0 end \\\
    local v = theUnit:getVelocity()\\\
    return dcsCommon.mag(v.x, v.y, v.z)\\\
end\\\
\\\
-- closing velocity of u1 and u2, seen from u1\\\
function dcsCommon.getClosingVelocity(u1, u2)\\\
    if not u1 then return 0 end \\\
    if not u2 then return 0 end \\\
    if not u1:isExist() then return 0 end \\\
    if not u2:isExist() then return 0 end \\\
    local v1 = u1:getVelocity()\\\
    local v2 = u2:getVelocity()\\\
    local dV = dcsCommon.vSub(v1,v2)\\\
    local a = u1:getPoint()\\\
    local b = u2:getPoint() \\\
    local aMinusB = dcsCommon.vSub(a,b) -- vector from u2 to u1\\\
    local abMag = dcsCommon.vMag(aMinusB) -- distance u1 to u2 \\\
    if abMag < .0001 then return 0 end \\\
    -- project deltaV onto vector from u2 to u1 \\\
    local vClose = dcsCommon.dot(dV, aMinusB) / abMag \\\
    return vClose \\\
end\\\
\\\
function dcsCommon.getGroupAvgSpeed(theGroup)\\\
    if not theGroup then return 0 end \\\
    if not dcsCommon.isGroupAlive(theGroup) then return 0 end \\\
    local totalSpeed = 0\\\
    local cnt = 0 \\\
    local livingUnits = theGroup:getUnits()\\\
    for idx, theUnit in pairs(livingUnits) do \\\
        cnt = cnt + 1\\\
        totalSpeed = totalSpeed + dcsCommon.getUnitSpeed(theUnit)\\\
    end \\\
    if cnt == 0 then return 0 end \\\
    return totalSpeed / cnt \\\
end\\\
 \\\
function dcsCommon.getGroupMaxSpeed(theGroup)\\\
    if not theGroup then return 0 end \\\
    if not dcsCommon.isGroupAlive(theGroup) then return 0 end \\\
    local maxSpeed = 0\\\
    local livingUnits = theGroup:getUnits()\\\
    for idx, theUnit in pairs(livingUnits) do \\\
        currSpeed = dcsCommon.getUnitSpeed(theUnit)\\\
        if currSpeed > maxSpeed then maxSpeed = currSpeed end \\\
    end \\\
    return maxSpeed\\\
end \\\
\\\
function dcsCommon.getUnitHeading(theUnit)\\\
    if not theUnit then return 0 end \\\
    if not theUnit:isExist() then return 0 end \\\
    local pos = theUnit:getPosition() -- returns three vectors, p is location\\\
\\\
    local heading = math.atan2(pos.x.z, pos.x.x)\\\
    -- make sure positive only, add 260 degrees\\\
    if heading < 0 then\\\
        heading = heading + 2 * math.pi    -- put heading in range of 0 to 2*pi\\\
    end\\\
    return heading \\\
end\\\
\\\
function dcsCommon.getUnitHeadingDegrees(theUnit)\\\
    local heading = dcsCommon.getUnitHeading(theUnit)\\\
    return heading * 57.2958 -- 180 / math.pi \\\
end\\\
\\\
function dcsCommon.unitIsInfantry(theUnit)\\\
    if not theUnit then return false end \\\
    if not theUnit:isExist() then return end\\\
    local theType = theUnit:getTypeName()\\\
    local isInfantry =  \\\
                dcsCommon.containsString(theType, \\\"infantry\\\", false) or \\\
                dcsCommon.containsString(theType, \\\"paratrooper\\\", false) or\\\
                dcsCommon.containsString(theType, \\\"stinger\\\", false) or\\\
                dcsCommon.containsString(theType, \\\"manpad\\\", false) or\\\
                dcsCommon.containsString(theType, \\\"soldier\\\", false) or \\\
                dcsCommon.containsString(theType, \\\"SA-18 Igla\\\", false)\\\
    return isInfantry\\\
end\\\
\\\
function dcsCommon.coalition2county(inCoalition)\\\
    -- simply return UN troops for 0 neutral,\\\
    -- joint red for 1  red\\\
    -- joint blue for 2 blue \\\
    if inCoalition == 1 then return 81 end -- cjtf red\\\
    if inCoalition == 2 then return 80 end -- blue \\\
    if type(inCoalition) == \\\"string\\\" then \\\
            inCoalition = inCoalition:lower()\\\
            if inCoalition == \\\"red\\\" then return 81 end\\\
            if inCoalition == \\\"blue\\\" then return 80 end\\\
    end\\\
        \\\
    trigger.action.outText(\\\"+++dcsC: coalition2county in (\\\" .. inCoalition .. \\\") converts to UN (82)!\\\", 30)\\\
    return 82 -- UN \\\
    \\\
end\\\
\\\
--\\\
--\\\
-- INIT\\\
--\\\
--\\\
    -- init any variables the lib requires internally\\\
    function dcsCommon.init()\\\
        cbID = 0\\\
        dcsCommon.uuIdent = 0\\\
        if (dcsCommon.verbose) or true then\\\
          trigger.action.outText(\\\"dcsCommon v\\\" .. dcsCommon.version .. \\\" loaded\\\", 10)\\\
        end\\\
    end\\\
\\\
    \\\
-- do init. \\\
dcsCommon.init()\\\
\\\
--[[--\\\
\\\
to do: \\\
- formation 2Column\\\
- formation 3Column\\\
\\\
-]]--\\\
\");a_do_script(\"-- cf/x zone management module\\\
-- reads dcs zones and makes them accessible and mutable \\\
-- by scripting.\\\
--\\\
-- Copyright (c) 2021, 2022 by Christian Franz and cf/x AG\\\
--\\\
\\\
cfxZones = {}\\\
cfxZones.version = \\\"2.5.8\\\"\\\
--[[-- VERSION HISTORY\\\
 - 2.2.4 - getCoalitionFromZoneProperty\\\
         - getStringFromZoneProperty\\\
 - 2.2.5 - createGroundUnitsInZoneForCoalition corrected coalition --> country \\\
 - 2.2.6 - getVectorFromZoneProperty(theZone, theProperty, defaultVal)\\\
 - 2.2.7 - allow 'yes' as 'true' for boolean attribute \\\
 - 2.2.8 - getBoolFromZoneProperty supports default \\\
         - cfxZones.hasProperty\\\
 - 2.3.0 - property names are case insensitive \\\
 - 2.3.1 - getCoalitionFromZoneProperty allows 0, 1, 2 also\\\
 - 2.4.0 - all zones look for owner attribute, and set it to 0 (neutral) if not present \\\
 - 2.4.1 - getBoolFromZoneProperty upgraded by expected bool \\\
         - markZoneWithSmoke raised by 3 meters\\\
 - 2.4.2 - getClosestZone also returns delta \\\
 - 2.4.3 - getCoalitionFromZoneProperty() accepts 'all' as neutral \\\
           createUniqueZoneName()\\\
           getStringFromZoneProperty returns default if property value = \\\"\\\"\\\
           corrected bug in addZoneToManagedZones\\\
 - 2.4.4 - getPoint(aZone) returns uip-to-date pos for linked and normal zones\\\
         - linkUnit can use \\\"useOffset\\\" property to keep relative position\\\
 - 2.4.5 - updated various methods to support getPoint when referencing \\\
           zone.point  \\\
 - 2.4.6 - corrected spelling in markZoneWithSmoke\\\
 - 2.4.7 - copy reference to dcs zone into cfx zone \\\
 - 2.4.8 - getAllZoneProperties\\\
 - 2.4.9 - createSimpleZone no longer requires location \\\
         - parse dcs adds empty .properties = {} if none tehre \\\
         - createCircleZone adds empty properties \\\
         - createPolyZone adds empty properties \\\
 - 2.4.10 - pickRandomZoneFrom now defaults to all cfxZones.zones\\\
          - getBoolFromZoneProperty also recognizes 0, 1\\\
          - removed autostart\\\
 - 2.4.11 - removed typo in get closest zone \\\
 - 2.4.12 - getStringFromZoneProperty\\\
 - 2.5.0  - harden getZoneProperty and all getPropertyXXXX\\\
 - 2.5.1  - markZoneWithSmoke supports alt attribute \\\
 - 2.5.2  - getPoint also writes through to zone itself for optimization\\\
          - new method getPositiveRangeFromZoneProperty(theZone, theProperty, default)\\\
 - 2.5.3  - new getAllGroupsInZone()\\\
 - 2.5.4  - cleaned up getZoneProperty break on no properties \\\
          - extractPropertyFromDCS trims key and property \\\
 - 2.5.5  - pollFlag() centralized for banging \\\
          - allStaticsInZone\\\
 - 2.5.6  - flag accessor setFlagValue(), getFlagValue()  \\\
          - pollFlag supports theZone as final parameter\\\
          - randomDelayFromPositiveRange\\\
          - isMEFlag\\\
 - 2.5.7  - pollFlag supports dml flags\\\
 - 2.5.8  - flagArrayFromString\\\
          - getFlagNumber invokes tonumber() before returning result \\\
 \\\
--]]--\\\
cfxZones.verbose = false\\\
cfxZones.caseSensitiveProperties = false -- set to true to make property names case sensitive \\\
cfxZones.ups = 1 -- updates per second. updates moving zones\\\
\\\
cfxZones.zones = {} -- these are the zone as retrieved from the mission.\\\
                    -- ALWAYS USE THESE, NEVER DCS's ZONES!!!!\\\
\\\
-- a zone has the following attributes\\\
-- x, z -- coordinate of center. note they have correct x, 0, z coordinates so no y-->z mapping\\\
-- radius (zero if quad zone)\\\
-- isCircle (true if quad zone)\\\
-- poly the quad coords are in the poly attribute and are a \\\
-- 1..n, wound counter-clockwise as (currently) in DCS:\\\
-- lower left, lower right upper left, upper right, all coords are x, 0, z \\\
-- bounds - contain the AABB coords for the zone: ul (upper left), ur, ll (lower left), lr \\\
--          for both circle and poly, all (x, 0, z)\\\
\\\
-- zones can carry information in their names that can get processed into attributes\\\
-- use \\\
-- zones can also carry information in their 'properties' tag that ME allows to \\\
-- edit. cfxZones provides an easy method to access these properties \\\
--  - getZoneProperty (returns as string)\\\
--  - getMinMaxFromZoneProperty\\\
--  - getBoolFromZoneProperty\\\
--  - getNumberFromZoneProperty\\\
\\\
\\\
-- SUPPORTED PROPERTIES\\\
-- - \\\"linkedUnit\\\" - zone moves with unit of that name. must be exact match\\\
--   can be combined with other attributes that extend (e.g. scar manager and\\\
--   limited pilots/airframes \\\
--\\\
\\\
--\\\
-- readZonesFromDCS is executed exactly once at the beginning\\\
-- from then on, use only the cfxZones.zones table \\\
-- WARNING: cfxZones is NOT case-sensitive. All zone names are \\\
-- indexed by upper case. If you have two zones with same name but \\\
-- different case, one will be replaced\\\
--\\\
\\\
function cfxZones.readFromDCS(clearfirst)\\\
    if (clearfirst) then\\\
        cfxZones.zones = {}\\\
    end\\\
    -- not all missions have triggers or zones\\\
    if not env.mission.triggers then \\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"cf/x zones: no env.triggers defined\\\", 10)\\\
        end\\\
        return\\\
    end\\\
    \\\
    if not env.mission.triggers.zones then \\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"cf/x zones: no zones defined\\\", 10)\\\
        end\\\
        return;\\\
    end\\\
\\\
    -- we only retrieve the data we need. At this point it is name, location and radius\\\
    -- and put this in our own little  structure. we also convert to all upper case name for index\\\
    -- and assume that the name may also carry meaning, e.g. 'LZ:' defines a landing zone\\\
    -- so we can quickly create other sets from this\\\
    -- zone object. DCS 2.7 introduced quads, so this is supported as well\\\
    --   name - name in upper case\\\
    --   isCircle - true if circular zone \\\
    --   isPoly - true if zone is defined by convex polygon, e.g. quad \\\
    --   point - vec3 (x 0 z) - zone's in-world center, used to place the coordinate\\\
    --   radius - number, zero when quad\\\
    --   bounds - aabb with attributes ul, ur, ll, lr (upper left .. lower right) as (x, 0, z)\\\
    --   poly - array 1..n of poly points, wound counter-clockwise \\\
    \\\
    for i, dcsZone in pairs(env.mission.triggers.zones) do\\\
        if type(dcsZone) == 'table' then -- hint taken from MIST: verify type when reading from dcs\\\
                                         -- dcs data is like a box of chocolates...\\\
            local newZone = {}\\\
            -- name, converted to upper is used only for indexing\\\
            -- the original name remains untouched\\\
            newZone.dcsZone = dcsZone\\\
            newZone.name = dcsZone.name\\\
            newZone.isCircle = false\\\
            newZone.isPoly = false\\\
            newZone.radius = 0\\\
            newZone.poly = {}\\\
            newZone.bounds = {}\\\
            newZone.properties = {} -- dcs has this too, copy if present\\\
            if dcsZone.properties then \\\
                newZone.properties = dcsZone.properties \\\
            else\\\
                newZone.properties = {}\\\
            end -- WARNING: REF COPY. May need to clone \\\
            \\\
            local upperName = newZone.name:upper()\\\
            \\\
            -- location as 'point'\\\
            -- WARNING: zones locs are 2D (x,y) pairs, whily y in DCS is altitude.\\\
            --          so we need to change (x,y) into (x, 0, z). Since Zones have no\\\
            --          altitude (they are an infinite cylinder) this works. Remember to \\\
            --          drop y from zone calculations to see if inside. \\\
            newZone.point = cfxZones.createPoint(dcsZone.x, 0, dcsZone.y)\\\
\\\
\\\
            -- start type processing. if zone.type exists, we have a mission \\\
            -- created with 2.7 or above, else earlier \\\
            local zoneType = 0\\\
            if (dcsZone.type) then \\\
                zoneType = dcsZone.type \\\
            end\\\
            \\\
            if zoneType == 0 then \\\
                -- circular zone \\\
                newZone.isCircle = true \\\
                newZone.radius = dcsZone.radius\\\
    \\\
            elseif zoneType == 2 then\\\
                -- polyZone\\\
                newZone.isPoly = true \\\
                newZone.radius = dcsZone.radius -- radius is still written in DCS, may change later\\\
                -- now transfer all point in the poly\\\
                -- note: DCS in 2.7 misspells vertices as 'verticies'\\\
                -- correct vor this \\\
                local verts = {}\\\
                if dcsZone.verticies then verts = dcsZone.verticies \\\
                else \\\
                    -- in later versions, this was corrected\\\
                    verts = dcsZone.vertices -- see if this is ever called\\\
                end\\\
                \\\
                for v=1, #verts do\\\
                    local dcsPoint = verts[v]\\\
                    local polyPoint = cfxZones.createPointFromDCSPoint(dcsPoint) -- (x, y) -- (x, 0, y-->z)\\\
                    newZone.poly[v] = polyPoint\\\
                end\\\
            else \\\
                \\\
                trigger.action.outText(\\\"cf/x zones: malformed zone #\\\" .. i .. \\\" unknown type \\\" .. zoneType, 10)\\\
            end\\\
            \\\
\\\
            -- calculate bounds\\\
            cfxZones.calculateZoneBounds(newZone) \\\
\\\
            -- add to my table\\\
            cfxZones.zones[upperName] = newZone -- WARNING: UPPER ZONE!!!\\\
            --trigger.action.outText(\\\"znd: procced \\\" .. newZone.name .. \\\" with radius \\\" .. newZone.radius, 30)\\\
        else\\\
            if cfxZones.verbose then \\\
                trigger.action.outText(\\\"cf/x zones: malformed zone #\\\" .. i .. \\\" dropped\\\", 10)\\\
            end\\\
        end -- else var not a table\\\
        \\\
    end -- for all zones kvp\\\
end -- readFromDCS\\\
\\\
function cfxZones.calculateZoneBounds(theZone)\\\
    if not (theZone) then return \\\
    end\\\
    \\\
    local bounds = theZone.bounds -- copy ref!\\\
    \\\
    if theZone.isCircle then \\\
        -- aabb are easy: center +/- radius \\\
        local center = theZone.point\\\
        local radius = theZone.radius \\\
        -- dcs uses z+ is down on map\\\
        -- upper left is center - radius \\\
        bounds.ul = cfxZones.createPoint(center.x - radius, 0, center.z - radius)\\\
        bounds.ur = cfxZones.createPoint(center.x + radius, 0, center.z - radius)\\\
        bounds.ll = cfxZones.createPoint(center.x - radius, 0, center.z + radius)\\\
        bounds.lr = cfxZones.createPoint(center.x + radius, 0, center.z + radius)\\\
        \\\
    elseif theZone.isPoly then\\\
        local poly = theZone.poly -- ref copy!\\\
        -- create the four points\\\
        local ll = cfxZones.createPointFromPoint(poly[1])\\\
        local lr = cfxZones.createPointFromPoint(poly[1])\\\
        local ul = cfxZones.createPointFromPoint(poly[1])\\\
        local ur = cfxZones.createPointFromPoint(poly[1])\\\
\\\
        -- now iterate through all points and adjust bounds accordingly \\\
        for v=2, #poly do \\\
             local vertex = poly[v]\\\
             if (vertex.x < ll.x) then ll.x = vertex.x; ul.x = vertex.x end \\\
             if (vertex.x > lr.x) then lr.x = vertex.x; ur.x = vertex.x end \\\
             if (vertex.z < ul.z) then ul.z = vertex.z; ur.z = vertex.z end\\\
             if (vertex.z > ll.z) then ll.z = vertex.z; lr.z = vertex.z end \\\
            \\\
        end\\\
        \\\
        -- now keep the new point references\\\
        -- and store them in the zone's bounds\\\
        bounds.ll = ll\\\
        bounds.lr = lr\\\
        bounds.ul = ul\\\
        bounds.ur = ur \\\
    else \\\
        -- huston, we have a problem\\\
        if cfxZones.verbose then \\\
            trigger.action.outText(\\\"cf/x zones: calc bounds: zone \\\" .. theZone.name .. \\\" has unknown type\\\", 30)\\\
        end\\\
    end\\\
    \\\
end\\\
\\\
function cfxZones.createPoint(x, y, z)\\\
    local newPoint = {}\\\
    newPoint.x = x\\\
    newPoint.y = y\\\
    newPoint.z = z \\\
    return newPoint\\\
end\\\
\\\
function cfxZones.copyPoint(inPoint) \\\
    local newPoint = {}\\\
    newPoint.x = inPoint.x\\\
    newPoint.y = inPoint.y\\\
    newPoint.z = inPoint.z \\\
    return newPoint    \\\
end\\\
\\\
function cfxZones.createHeightCorrectedPoint(inPoint) -- this should be in dcsCommon\\\
    local cP = cfxZones.createPoint(inPoint.x, land.getHeight({x=inPoint.x, y=inPoint.z}),inPoint.z)\\\
    return cP\\\
end\\\
\\\
function cfxZones.getHeightCorrectedZonePoint(theZone)\\\
    return cfxZones.createHeightCorrectedPoint(theZone.point)\\\
end\\\
\\\
function cfxZones.createPointFromPoint(inPoint)\\\
    return cfxZones.copyPoint(inPoint)\\\
end\\\
\\\
function cfxZones.createPointFromDCSPoint(inPoint) \\\
    return cfxZones.createPoint(inPoint.x, 0, inPoint.y)\\\
end\\\
\\\
\\\
function cfxZones.createRandomPointInsideBounds(bounds)\\\
    local x = math.random(bounds.ll.x, ur.x)\\\
    local z = math.random(bounds.ll.z, ur.z)\\\
    return cfxZones.createPoint(x, 0, z)\\\
end\\\
\\\
function cfxZones.addZoneToManagedZones(theZone)\\\
    local upperName = string.upper(theZone.name) -- newZone.name:upper()\\\
    cfxZones.zones[upperName] = theZone\\\
end\\\
\\\
function cfxZones.createUniqueZoneName(inName, searchSet)\\\
    if not inName then return nil end \\\
    if not searchSet then searchSet = cfxZones.zones end \\\
    inName = inName:upper()\\\
    while searchSet[inName] ~= nil do \\\
        inName = inName .. \\\"X\\\"\\\
    end\\\
    return inName\\\
end\\\
\\\
function cfxZones.createSimpleZone(name, location, radius, addToManaged)\\\
    if not radius then radius = 10 end\\\
    if not addToManaged then addToManaged = false end \\\
    if not location then \\\
        location = {}\\\
    end\\\
    if not location.x then location.x = 0 end \\\
    if not location.z then location.z = 0 end \\\
    \\\
    local newZone = cfxZones.createCircleZone(name, location.x, location.z, radius)\\\
    \\\
    if addToManaged then \\\
        cfxZones.addZoneToManagedZones(newZone)\\\
    end\\\
    return newZone\\\
end\\\
\\\
function cfxZones.createCircleZone(name, x, z, radius) \\\
    local newZone = {}\\\
    newZone.isCircle = true\\\
    newZone.isPoly = false\\\
    newZone.poly = {}\\\
    newZone.bounds = {}\\\
            \\\
    newZone.name = name\\\
    newZone.radius = radius\\\
    newZone.point = cfxZones.createPoint(x, 0, z)\\\
 \\\
    -- props \\\
    newZone.properties = {}\\\
    \\\
    -- calculate my bounds\\\
    cfxZones.calculateZoneBounds(newZone)\\\
    \\\
    return newZone\\\
end\\\
\\\
function cfxZones.createPolyZone(name, poly) -- poly must be array of point type\\\
local newZone = {}\\\
    newZone.isCircle = false\\\
    newZone.isPoly = true\\\
    newZone.poly = {}\\\
    newZone.bounds = {}\\\
            \\\
    newZone.name = name\\\
    newZone.radius = 0\\\
    -- copy poly\\\
    for v=1, #poly do \\\
        local theVertex = poly[v] \\\
        newZone.poly[v] = cfxZones.createPointFromPoint(theVertex) \\\
    end\\\
    \\\
    -- properties \\\
    newZone.properties = {}\\\
    \\\
    cfxZones.calculateZoneBounds(newZone)\\\
end\\\
\\\
\\\
\\\
function cfxZones.createRandomZoneInZone(name, inZone, targetRadius, entirelyInside)\\\
    -- create a new circular zone with center placed inside inZone\\\
    -- if entirelyInside is false, only the zone's center is guaranteed to be inside\\\
    -- inZone.\\\
    \\\
--    trigger.action.outText(\\\"Zones: creating rZiZ with tr = \\\" .. targetRadius .. \\\" for \\\" .. inZone.name .. \\\" that as r = \\\" .. inZone.radius, 10)\\\
    \\\
    if inZone.isCircle then \\\
        local sourceRadius = inZone.radius\\\
        if entirelyInside and targetRadius > sourceRadius then targetRadius = sourceRadius end\\\
        if entirelyInside then sourceRadius = sourceRadius - targetRadius end\\\
    \\\
        -- ok, let's first create a random percentage value for the new radius\\\
        local percent = 1 / math.random(100)\\\
        -- now lets get a random degree\\\
        local degrees = math.random(360) * 3.14152 / 180 -- ok, it's actually radiants. \\\
        local r = sourceRadius * percent \\\
        local x = inZone.point.x + r * math.cos(degrees)\\\
        local z = inZone.point.z + r * math.sin(degrees)\\\
        -- construct new zone\\\
        local newZone = cfxZones.createCircleZone(name, x, z, targetRadius)\\\
        return newZone\\\
    \\\
    elseif inZone.isPoly then \\\
        -- we have a poly zone. the way we do this is simple:\\\
        -- generate random x, z with ranges of the bounding box \\\
        -- until the point falls within the polygon.\\\
        local newPoint = {}\\\
        local emergencyBrake = 0\\\
        repeat\\\
            newPoint = cfxZones.createRandomPointInsideBounds(inZone.bounds)\\\
            emergencyBrake = emergencyBrake + 1\\\
            if (emergencyBrake > 100) then \\\
                newPoint = cfxZones.copyPoint(inZone.Point)\\\
                trigger.action.outText(\\\"CreateZoneInZone: mergency brake for inZone\\\" .. inZone.name,  10)\\\
                break\\\
            end\\\
        until cfxZones.isPointInsidePoly(newPoint, inZone.poly)\\\
        \\\
        -- construct new zone\\\
        local newZone = cfxZones.createCircleZone(name, newPoint.x, newPoint.z, targetRadius)\\\
        return newZone\\\
        \\\
    else \\\
        -- zone type unknown\\\
        trigger.action.outText(\\\"CreateZoneInZone: unknown zone type for inZone =\\\" .. inZone.name ,  10)\\\
        return nil \\\
    end\\\
end\\\
\\\
-- polygon inside zone calculations\\\
\\\
\\\
-- isleft returns true if point P is to the left of line AB \\\
-- by determining the sign (up or down) of the normal vector of \\\
-- the two vectors PA and PB in the y coordinate. We arbitrarily define\\\
-- left as being > 0, so right is <= 0. As long as we always use the \\\
-- same comparison, it does not matter what up or down mean.\\\
-- this is important because we don't know if dcs always winds quads\\\
-- the same way, we must simply assume that they are wound as a polygon \\\
function cfxZones.isLeftXZ(A, B, P)\\\
    return ((B.x - A.x)*(P.z - A.z) - (B.z - A.z)*(P.x - A.x)) > 0\\\
end\\\
\\\
-- returns true/false for inside\\\
function cfxZones.isPointInsideQuad(thePoint, A, B, C, D) \\\
    -- Inside test (only convex polygons): \\\
    -- point lies on the same side of each quad's vertex AB, BC, CD, DA\\\
    -- how do we find out which side a point lies on? via the cross product\\\
    -- see isLeft below\\\
    \\\
    -- so all we need to do is make sure all results of isLeft for all\\\
    -- four sides are the same\\\
    mustMatch = isLeftXZ(A, B, thePoint) -- all test results must be the same and we are ok\\\
                                       -- they just must be the same side.\\\
    if (cfxZones.isLeftXZ(B, C, thePoint ~= mustMatch)) then return false end -- on other side than all before\\\
    if (cfxZones.isLeftXZ(C, D, thePoint ~= mustMatch)) then return false end \\\
    if (cfxZones.isLeftXZ(D, A, thePoint ~= mustMatch)) then return false end\\\
    return true\\\
end\\\
\\\
-- generalized version of insideQuad, assumes winding of poly, poly convex, poly closed\\\
function cfxZones.isPointInsidePoly(thePoint, poly)\\\
    local mustMatch = cfxZones.isLeftXZ(poly[1], poly[2], thePoint)\\\
    for v=2, #poly-1 do \\\
        if cfxZones.isLeftXZ(poly[v], poly[v+1], thePoint) ~= mustMatch then return false end\\\
    end\\\
    -- final test\\\
    if cfxZones.isLeftXZ(poly[#poly], poly[1], thePoint) ~= mustMatch then return false end\\\
    \\\
    return true\\\
end;\\\
\\\
function cfxZones.isPointInsideZone(thePoint, theZone)\\\
    local p = {x=thePoint.x, y = 0, z = thePoint.z} -- zones have no altitude\\\
    if (theZone.isCircle) then \\\
        local zp = cfxZones.getPoint(theZone)\\\
        local d = dcsCommon.dist(p, theZone.point)\\\
        return d < theZone.radius\\\
    end \\\
    \\\
    if (theZone.isPoly) then \\\
        --trigger.action.outText(\\\"zne: isPointInside: \\\" .. theZone.name .. \\\" is Polyzone!\\\", 30)\\\
        return (cfxZones.isPointInsidePoly(p, theZone.poly))\\\
    end\\\
\\\
    trigger.action.outText(\\\"isPointInsideZone: Unknown zone type for \\\" .. outerZone.name, 10)\\\
end\\\
\\\
-- isZoneInZone returns true if center of innerZone is inside  outerZone\\\
function cfxZones.isZoneInsideZone(innerZone, outerZone) \\\
    return cfxZones.isPointInsideZone(innerZone.point, outerZone)\\\
\\\
    \\\
end\\\
\\\
function cfxZones.getZonesContainingPoint(thePoint, testZones) -- return array \\\
    if not testZones then \\\
        testZones = cfxZones.zones \\\
    end \\\
    \\\
    local containerZones = {}\\\
    for tName, tData in pairs(testZones) do \\\
        if cfxZones.isPointInsideZone(thePoint, tData) then \\\
            table.insert(containerZones, tData)\\\
        end\\\
    end\\\
\\\
    return containerZones\\\
end\\\
\\\
function cfxZones.getFirstZoneContainingPoint(thePoint, testZones)\\\
    if not testZones then \\\
        testZones = cfxZones.zones \\\
    end \\\
    \\\
    for tName, tData in pairs(testZones) do \\\
        if cfxZones.isPointInsideZone(thePoint, tData) then \\\
            return tData\\\
        end\\\
    end\\\
\\\
    return nil\\\
end\\\
\\\
function cfxZones.getAllZonesInsideZone(superZone, testZones) -- returnes array!\\\
    if not testZones then \\\
        testZones = cfxZones.zones \\\
    end \\\
    \\\
    local containedZones = {}\\\
    for zName, zData in pairs(testZones) do\\\
        if cfxZones.isZoneInsideZone(zData, superZone) then \\\
            if zData ~= superZone then \\\
                -- we filter superzone because superzone usually resides \\\
                -- inside itself \\\
                table.insert(containedZones, zData)\\\
            end\\\
        end\\\
    end\\\
    return containedZones \\\
end\\\
\\\
function cfxZones.getZonesWithAttributeNamed(attributeName, testZones)\\\
    if not testZones then testZones = cfxZones.zones end \\\
    local attributZones = {}\\\
    for aName,aZone in pairs(testZones) do\\\
        local attr = cfxZones.getZoneProperty(aZone, attributeName)\\\
        if attr then \\\
            -- this zone has the requested attribute\\\
            table.insert(attributZones, aZone)\\\
        end\\\
    end\\\
    return attributZones\\\
end\\\
\\\
--\\\
-- units / groups in zone\\\
--\\\
function cfxZones.allGroupsInZone(theZone, categ) -- categ is optional, must be code \\\
    -- warning: does not check for exiting!\\\
    --trigger.action.outText(\\\"Zone \\\" .. theZone.name .. \\\" radius \\\" .. theZone.radius, 30)\\\
    local inZones = {}\\\
    local coals = {0, 1, 2} -- all coalitions\\\
    for idx, coa in pairs(coals) do \\\
        local allGroups = coalition.getGroups(coa, categ)\\\
        for key, group in pairs(allGroups) do -- iterate all groups\\\
            if cfxZones.isGroupPartiallyInZone(group, theZone) then\\\
                table.insert(inZones, group)\\\
            end\\\
        end\\\
    end\\\
    return inZones\\\
end\\\
\\\
function cfxZones.allStaticsInZone(theZone) -- categ is optional, must be code \\\
    -- warning: does not check for exiting!\\\
    local inZones = {}\\\
    local coals = {0, 1, 2} -- all coalitions\\\
    for idx, coa in pairs(coals) do \\\
        local allStats = coalition.getStaticObjects(coa)\\\
        for key, statO in pairs(allStats) do -- iterate all groups\\\
            local oP = statO:getPoint()\\\
            if cfxZones.pointInZone(oP, theZone) then\\\
                table.insert(inZones, statO)\\\
            end\\\
        end\\\
    end\\\
    return inZones\\\
end\\\
\\\
function cfxZones.groupsOfCoalitionPartiallyInZone(coal, theZone, categ) -- categ is optional\\\
    local groupsInZone = {}\\\
    local allGroups = coalition.getGroups(coal, categ)\\\
    for key, group in pairs(allGroups) do -- iterate all groups\\\
        if group:isExist() then\\\
            if cfxZones.isGroupPartiallyInZone(group, theZone) then\\\
                table.insert(groupsInZone, group)            \\\
            end\\\
        end\\\
    end\\\
    return groupsInZone\\\
end\\\
\\\
function cfxZones.isGroupPartiallyInZone(aGroup, aZone)\\\
    if not aGroup then return false end \\\
    if not aZone then return false end \\\
        \\\
    if not aGroup:isExist() then return false end \\\
    local allUnits = aGroup:getUnits()\\\
    for uk, aUnit in pairs (allUnits) do \\\
        if aUnit:isExist() and aUnit:getLife() > 1 then         \\\
            local p = aUnit:getPoint()\\\
            local inzone, percent, dist = cfxZones.pointInZone(p, aZone)\\\
            if inzone then -- cfxZones.isPointInsideZone(p, aZone) then             \\\
                --trigger.action.outText(\\\"zne: YAY <\\\" .. aUnit:getName() .. \\\"> IS IN \\\" .. aZone.name, 30) \\\
                return true\\\
            end \\\
            --trigger.action.outText(\\\"zne: <\\\" .. aUnit:getName() .. \\\"> not in \\\" .. aZone.name .. \\\", dist = \\\" .. dist .. \\\", rad = \\\", aZone.radius, 30) \\\
        end\\\
    end\\\
    return false\\\
end\\\
\\\
function cfxZones.isEntireGroupInZone(aGroup, aZone)\\\
    if not aGroup then return false end \\\
    if not aZone then return false end \\\
    if not aGroup:isExist() then return false end \\\
    local allUnits = aGroup:getUnits()\\\
    for uk, aUnit in pairs (allUnits) do \\\
        if aUnit:isExist() and aUnit:getLife() > 1 then \\\
            local p = aUnit:getPoint()\\\
            if not cfxZones.isPointInsideZone(p, aZone) then \\\
                return false\\\
            end\\\
        end\\\
    end\\\
    return true\\\
end\\\
\\\
\\\
--\\\
-- Zone Manipulation\\\
--\\\
\\\
function cfxZones.offsetZone(theZone, dx, dz)\\\
    -- first, update center \\\
    theZone.point.x = theZone.point.x + dx\\\
    theZone.point.z = theZone.point.z + dz \\\
    \\\
    -- now process all polygon points - it's empty for circular, so don't worry\\\
    for v=1, #theZone.poly do \\\
        theZone.poly[v].x = theZone.poly[v].x + dx\\\
        theZone.poly[v].z = theZone.poly[v].z + dz \\\
    end\\\
end\\\
\\\
function cfxZones.moveZoneTo(theZone, x, z)\\\
    local dx = x - theZone.point.x\\\
    local dz = z - theZone.point.z \\\
    cfxZones.offsetZone(theZone, dx, dz)\\\
end;\\\
\\\
function cfxZones.centerZoneOnUnit(theZone, theUnit) \\\
    local thePoint = theUnit:getPoint()\\\
    cfxZones.moveZoneTo(theZone, thePoint.x, thePoint.z)\\\
end\\\
\\\
\\\
--[[\\\
-- no longer makes sense with poly zones\\\
function cfxZones.isZoneEntirelyInsideZone(innerZone, outerZone)\\\
    if (innerZone.radius > outerZone.radius) then return false end -- cant fit inside\\\
    local d = dcsCommon.dist(innerZone.point, outerZone.point)\\\
    local reducedR = outerZone.radius - innerZone.radius\\\
    return d < reducedR\\\
end;\\\
--]]\\\
\\\
function cfxZones.dumpZones(zoneTable)\\\
    if not zoneTable then zoneTable = cfxZones.zones end \\\
    \\\
    trigger.action.outText(\\\"Zones START\\\", 10)\\\
    for i, zone in pairs(zoneTable) do \\\
        local myType = \\\"unknown\\\"\\\
        if zone.isCircle then myType = \\\"Circle\\\" end\\\
        if zone.isPoly then myType = \\\"Poly\\\" end \\\
        \\\
        trigger.action.outText(\\\"#\\\".. i .. \\\": \\\" .. zone.name .. \\\" of type \\\" .. myType, 10)\\\
    end\\\
    trigger.action.outText(\\\"Zones END\\\", 10)\\\
end\\\
\\\
function cfxZones.stringStartsWith(theString, thePrefix)\\\
    return theString:find(thePrefix) == 1\\\
end\\\
\\\
function cfxZones.keysForTable(theTable)\\\
    local keyset={}\\\
    local n=0\\\
\\\
    for k,v in pairs(tab) do\\\
        n=n+1\\\
        keyset[n]=k\\\
    end\\\
    return keyset\\\
end\\\
\\\
\\\
--\\\
-- return all zones that have a specific named property\\\
--\\\
function cfxZones.zonesWithProperty(propertyName, searchSet)\\\
    if not searchSet then searchSet = cfxZones.zones end \\\
    local theZones = {}\\\
    for k, aZone in pairs(searchSet) do \\\
        if not aZone then \\\
            trigger.action.outText(\\\"+++zone: nil aZone for \\\" .. k, 30)\\\
        else \\\
            local lU = cfxZones.getZoneProperty(aZone, propertyName)\\\
            if lU then \\\
                table.insert(theZones, aZone)\\\
            end\\\
        end\\\
    end    \\\
    return theZones\\\
end\\\
\\\
--\\\
-- return all zones from the zone table that begin with string prefix\\\
--\\\
function cfxZones.zonesStartingWithName(prefix, searchSet)\\\
    \\\
    if not searchSet then searchSet = cfxZones.zones end \\\
    \\\
--    trigger.action.outText(\\\"Enter: zonesStartingWithName for \\\" .. prefix , 30)\\\
    local prefixZones = {}\\\
    prefix = prefix:upper() -- all zones have UPPERCASE NAMES! THEY SCREAM AT YOU\\\
    for name, zone in pairs(searchSet) do\\\
--        trigger.action.outText(\\\"testing \\\" .. name:upper() .. \\\" starts with \\\" .. prefix , 30)\\\
        if cfxZones.stringStartsWith(name:upper(), prefix) then\\\
            prefixZones[name] = zone -- note: ref copy!\\\
            --trigger.action.outText(\\\"zone with prefix <\\\" .. prefix .. \\\"> found: \\\" .. name, 10)\\\
        end\\\
    end\\\
    \\\
    return prefixZones\\\
end\\\
\\\
--\\\
-- return all zones from the zone table that begin with the string or set of strings passed in prefix \\\
-- if you pass 'true' as second (optional) parameter, it will first look for all zones that begin\\\
-- with '+' and return only those. Use during debugging to force finding a specific zone\\\
--\\\
function cfxZones.zonesStartingWith(prefix, searchSet, debugging)\\\
    -- you can force zones by having their name start with \\\"+\\\"\\\
    -- which will force them to return immediately if debugging is true for this call\\\
\\\
    if (debugging) then \\\
        local debugZones = cfxZones.zonesStartingWithName(\\\"+\\\", searchSet)\\\
        if not (next(debugZones) == nil) then -- # operator only works on array elements \\\
            --trigger.action.outText(\\\"returning zones with prefix <\\\" .. prefix .. \\\">\\\", 10)\\\
            return debugZones \\\
        end \\\
    end\\\
    \\\
    --trigger.action.outText(\\\"#debugZones is  <\\\" .. #debugZones .. \\\">\\\", 10)\\\
\\\
    if (type(prefix) == \\\"string\\\") then \\\
        return cfxZones.zonesStartingWithName(prefix, searchSet)\\\
    end\\\
    \\\
    local allZones = {}\\\
    for i=1, #prefix do \\\
        -- iterate through all names in prefix set\\\
        local theName = prefix[i]\\\
        local newZones = cfxZones.zonesStartingWithName(theName, searchSet)\\\
        -- add them all to current table\\\
        for zName, zInfo in pairs(newZones) do \\\
            allZones[zName] = zInfo -- will also replace doublets\\\
        end\\\
    end\\\
    \\\
    return allZones\\\
end\\\
\\\
function cfxZones.getZoneByName(aName, searchSet) \\\
    if not searchSet then searchSet = cfxZones.zones end \\\
    aName = aName:upper()\\\
    return searchSet[aName] -- the joys of key value pairs\\\
end\\\
\\\
function cfxZones.getZonesContainingString(aString, searchSet) \\\
    if not searchSet then searchSet = cfxZones.zones end\\\
    aString = string.upper(aString)\\\
    resultSet = {}\\\
    for zName, zData in pairs(searchSet) do \\\
        if aString == string.upper(zData.name) then \\\
            resultSet[zName] = zData\\\
        end\\\
    end\\\
    \\\
end;\\\
\\\
-- filter zones by range to a point. returns indexed set\\\
function cfxZones.getZonesInRange(point, range, theZones)\\\
    if not theZones then theZones = cfxZones.zones end\\\
    \\\
    local inRangeSet = {}\\\
    for zName, zData in pairs (theZones) do \\\
        if dcsCommon.dist(point, zData.point) < range then \\\
            table.insert(inRangeSet, zData)\\\
        end\\\
    end\\\
    return inRangeSet \\\
end\\\
\\\
-- get closest zone returns the zone that is closest to point \\\
function cfxZones.getClosestZone(point, theZones)\\\
    if not theZones then theZones = cfxZones.zones end\\\
    local currDelta = math.huge \\\
    local closestZone = nil\\\
    for zName, zData in pairs(theZones) do \\\
        local zPoint = cfxZones.getPoint(zData)\\\
        local delta = dcsCommon.dist(point, zPoint)\\\
        if (delta < currDelta) then \\\
            currDelta = delta\\\
            closestZone = zData\\\
        end\\\
    end\\\
    return closestZone, currDelta \\\
end\\\
\\\
-- return a random zone from the table passed in zones\\\
function cfxZones.pickRandomZoneFrom(zones)\\\
    if not zones then zones = cfxZones.zones end\\\
    local indexedZones = dcsCommon.enumerateTable(zones)\\\
    local r = math.random(#indexedZones)\\\
    return indexedZones[r]\\\
end\\\
\\\
-- return an zone element by index \\\
function cfxZones.getZoneByIndex(theZones, theIndex) \\\
    local enumeratedZones = dcsCommon.enumerateTable(theZones)\\\
    if (theIndex > #enumeratedZones) then\\\
        trigger.action.outText(\\\"WARNING: zone index \\\" .. theIndex .. \\\" out of bounds - max = \\\" .. #enumeratedZones, 30)\\\
        return nil end\\\
    if (theIndex < 1) then return nil end\\\
    \\\
    return enumeratedZones[theIndex]\\\
end\\\
\\\
-- place a smoke marker in center of zone, offset by dx, dy \\\
function cfxZones.markZoneWithSmoke(theZone, dx, dz, smokeColor, alt)\\\
    if not alt then alt = 5 end \\\
    local point = cfxZones.getPoint(theZone) --{} -- theZone.point\\\
    point.x = point.x + dx -- getpoint updates and returns copy \\\
    point.z = point.z + dz \\\
    -- get height at point \\\
    point.y = land.getHeight({x = point.x, y = point.z}) + alt\\\
    -- height-correct\\\
    --local newPoint= {x = point.x, y = land.getHeight({x = point.x, y = point.z}) + 3, z= point.z}\\\
    trigger.action.smoke(point, smokeColor)\\\
end\\\
\\\
-- place a smoke marker in center of zone, offset by radius and degrees \\\
function cfxZones.markZoneWithSmokePolar(theZone, radius, degrees, smokeColor, alt)\\\
    local rads = degrees * math.pi / 180\\\
    local dx = radius * math.sin(rads)\\\
    local dz = radius * math.cos(rads)\\\
    cfxZones.markZoneWithSmoke(theZone, dx, dz, smokeColor, alt)\\\
end\\\
\\\
-- place a smoke marker in center of zone, offset by radius and randomized degrees \\\
function cfxZones.markZoneWithSmokePolarRandom(theZone, radius, smokeColor)\\\
    local degrees = math.random(360)\\\
    cfxZones.markZoneWithSmokePolar(theZone, radius, degrees, smokeColor)\\\
end\\\
\\\
\\\
-- unitInZone returns true if theUnit is inside the zone \\\
-- the second value returned is the percentage of distance\\\
-- from center to rim, with 100% being entirely in center, 0 = outside\\\
-- the third value returned is the distance to center\\\
function cfxZones.pointInZone(thePoint, theZone)\\\
    if not (theZone) then return false, 0, 0 end\\\
        \\\
    local pflat = {x = thePoint.x, y = 0, z = thePoint.z}\\\
    \\\
    local zpoint = cfxZones.getPoint(theZone) -- updates zone if linked \\\
    local ppoint = thePoint -- xyz\\\
    local pflat = {x = ppoint.x, y = 0, z = ppoint.z}\\\
    local dist = dcsCommon.dist(zpoint, pflat)\\\
    \\\
    if theZone.isCircle then \\\
        if theZone.radius <= 0 then \\\
            return false, 0, 0\\\
        end\\\
\\\
        local success = dist < theZone.radius\\\
        local percentage = 0\\\
        if (success) then \\\
            percentage = 1 - dist / theZone.radius \\\
        end\\\
        return success, percentage, dist \\\
    \\\
    elseif theZone.isPoly then\\\
        local success = cfxZones.isPointInsidePoly(pflat, theZone.poly)\\\
        return success, 0, dist\\\
    else \\\
        trigger.action.outText(\\\"pointInZone: Unknown zone type for \\\" .. theZone.name, 10)\\\
    end\\\
\\\
    return false\\\
end\\\
\\\
function cfxZones.unitInZone(theUnit, theZone)\\\
    if not (theUnit) then return false, 0, 0 end\\\
    if not (theUnit:isExist()) then return false, 0, 0 end\\\
    -- force zone update if it is linked to another zone \\\
    -- pointInZone does update\\\
    local thePoint = theUnit:getPoint()\\\
    return cfxZones.pointInZone(thePoint, theZone)\\\
    \\\
end\\\
\\\
-- returns all units of the input set that are inside the zone \\\
function cfxZones.unitsInZone(theUnits, theZone)\\\
    if not theUnits then return {} end\\\
    if not theZone then return {} end\\\
    \\\
    local zoneUnits = {}\\\
    for index, aUnit in pairs(theUnits) do \\\
        if cfxZones.unitInZone(aUnit, theZone) then \\\
            table.insert( zoneUnits, aUnit)\\\
        end\\\
    end\\\
    return zoneUnits\\\
end\\\
\\\
function cfxZones.closestUnitToZoneCenter(theUnits, theZone)\\\
    -- does not care if they really are in zone. call unitsInZone first\\\
    -- if you need to have them filtered\\\
    -- theUnits MUST BE ARRAY\\\
    if not theUnits then return nil end\\\
    if #theUnits == 0 then return nil end\\\
    local closestUnit = theUnits[1]\\\
    for i=2, #theUnits do\\\
        local aUnit = theUnits[i]\\\
        if dcsCommon.dist(theZone.point, closestUnit:getPoint()) > dcsCommon.dist(theZone.point, aUnit:getPoint()) then \\\
            closestUnit = aUnit\\\
        end\\\
    end\\\
    return closestUnit\\\
end\\\
\\\
function cfxZones.anyPlayerInZone(theZone) -- returns first player it finds\\\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do\\\
        local playerUnit = pinfo.unit\\\
        if (cfxZones.unitInZone(playerUnit, theZone)) then \\\
            return true, playerUnit\\\
        end\\\
    end -- for all players \\\
    return false, nil\\\
end\\\
\\\
\\\
-- grow zone\\\
function cfxZones.growZone()\\\
    -- circular zones simply increase radius\\\
    -- poly zones: not defined \\\
    \\\
end\\\
\\\
\\\
-- creating units in a zone\\\
function cfxZones.createGroundUnitsInZoneForCoalition (theCoalition, groupName, theZone, theUnits, formation, heading) \\\
    -- theUnits can be string or table of string \\\
    if not groupName then groupName = \\\"G_\\\"..theZone.name end \\\
    -- group name will be taken from zone name and prependend with \\\"G_\\\"\\\
    local theGroup = dcsCommon.createGroundGroupWithUnits(groupName, theUnits, theZone.radius, nil, formation)\\\
    \\\
    -- turn the entire formation to heading\\\
    if (not heading) then heading = 0 end\\\
    dcsCommon.rotateGroupData(theGroup, heading) -- currently, group is still at origin, no cx, cy\\\
    \\\
    \\\
    -- now move the group to center of theZone\\\
    dcsCommon.moveGroupDataTo(theGroup, \\\
                          theZone.point.x, \\\
                          theZone.point.z) -- watchit: Z!!!\\\
\\\
\\\
    -- create the group in the world and return it\\\
    -- first we need to translate the coalition to a legal \\\
    -- country. we use UN for neutral, cjtf for red and blue \\\
    local theSideCJTF = dcsCommon.coalition2county(theCoalition)\\\
    return coalition.addGroup(theSideCJTF, Group.Category.GROUND, theGroup)\\\
\\\
end\\\
\\\
-- parsing zone names. The first part of the name until the first blank \\\" \\\" \\\
-- is the prefix and is dropped unless keepPrefix is true. \\\
-- all others are regarded as key:value pairs and are then added \\\
-- to the zone \\\
-- separated by equal sign \\\"=\\\" AND MUST NOT CONTAIN BLANKS\\\
--\\\
-- example usage \\\"followZone unit=rotary-1 dx=30 dy=25 rotateWithHeading=true\\\
--\\\
-- OLD DEPRECATED TECH -- TO BE DECOMMISSIONED SOON, DO NOT USE\\\
-- \\\
--[[--\\\
function cfxZones.parseZoneNameIntoAttributes(theZone, keepPrefix)\\\
--    trigger.action.outText(\\\"Parsing zone:  \\\".. theZone.name, 30)\\\
    if not keepPrefix then keepPrefix = false end -- simply for clarity\\\
    -- now split the name into space-separated strings\\\
    local attributes = dcsCommon.splitString(theZone.name, \\\" \\\")\\\
    if not keepPrefix then table.remove(attributes, 1) end -- pop prefix\\\
\\\
    -- now parse all substrings and add them as attributes to theZone\\\
    for i=1, #attributes do \\\
        local a = attributes[i]\\\
        local kvp = dcsCommon.splitString(a, \\\"=\\\")\\\
        if #kvp == 2 then \\\
            -- we have key value pair\\\
            local theKey = kvp[1]\\\
            local theValue = kvp[2]\\\
            theZone[theKey] = theValue \\\
--            trigger.action.outText(\\\"Zone \\\".. theZone.name .. \\\" parsed: Key = \\\" .. theKey .. \\\", Value = \\\" .. theValue, 30)\\\
        else \\\
--            trigger.action.outText(\\\"Zone \\\".. theZone.name .. \\\": dropped attribute \\\" .. a, 30)\\\
        end\\\
    end \\\
end\\\
--]]--\\\
-- OLD DEPRECATED TECH -- TO BE DECOMMISSIONED SOON, DO NOT USE\\\
--[[--\\\
function cfxZones.processCraterZones ()\\\
    local craters = cfxZones.zonesStartingWith(\\\"crater\\\")\\\
\\\
    \\\
\\\
    -- all these zones need to be processed and their name infor placed into attributes\\\
    for cName, cZone in pairs(craters) do\\\
        cfxZones.parseZoneNameIntoAttributes(cZone)\\\
        \\\
        -- blow stuff up at the location of the zone \\\
        local cPoint = cZone.point\\\
        cPoint.y = land.getHeight({x = cPoint.x, y = cPoint.z})  -- compensate for ground level\\\
        trigger.action.explosion(cPoint, 900)\\\
         \\\
        -- now interpret and act on the crater info \\\
        -- to destroy and place fire. \\\
        \\\
        -- fire has small, medium, large \\\
        -- eg. fire=large\\\
        \\\
    end\\\
end\\\
--]]--\\\
--\\\
-- Flag Pulling \\\
--\\\
function cfxZones.pollFlag(theFlag, method, theZone) \\\
    if cfxZones.verbose then \\\
        trigger.action.outText(\\\"+++zones: polling flag \\\" .. theFlag .. \\\" with \\\" .. method, 30)\\\
    end \\\
    \\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++zones: nil theZone on pollFlag\\\", 30)\\\
    end\\\
    \\\
    method = method:lower()\\\
    --trigger.action.outText(\\\"+++zones: polling \\\" .. theZone.name .. \\\" method \\\" .. method .. \\\" flag \\\" .. theFlag, 30)\\\
    local currVal = cfxZones.getFlagValue(theFlag, theZone)\\\
    if method == \\\"inc\\\" or method == \\\"f+1\\\" then \\\
        --trigger.action.setUserFlag(theFlag, currVal + 1)\\\
        cfxZones.setFlagValue(theFlag, currVal+1, theZone)\\\
        \\\
    elseif method == \\\"dec\\\" or method == \\\"f-1\\\" then \\\
        -- trigger.action.setUserFlag(theFlag, currVal - 1)\\\
        cfxZones.setFlagValue(theFlag, currVal-1, theZone)\\\
\\\
    elseif method == \\\"off\\\" or method == \\\"f=0\\\" then \\\
        -- trigger.action.setUserFlag(theFlag, 0)\\\
        cfxZones.setFlagValue(theFlag, 0, theZone)\\\
\\\
    elseif method == \\\"flip\\\" or method == \\\"xor\\\" then \\\
        if currVal ~= 0 then \\\
--            trigger.action.setUserFlag(theFlag, 0)\\\
            cfxZones.setFlagValue(theFlag, 0, theZone)\\\
\\\
        else \\\
            --trigger.action.setUserFlag(theFlag, 1)\\\
            cfxZones.setFlagValue(theFlag, 1, theZone)\\\
        end\\\
        \\\
    else \\\
        if method ~= \\\"on\\\" and method ~= \\\"f=1\\\" then \\\
            trigger.action.outText(\\\"+++zones: unknown method <\\\" .. method .. \\\"> - using 'on'\\\", 30)\\\
        end\\\
        -- default: on.\\\
--        trigger.action.setUserFlag(theFlag, 1)\\\
        cfxZones.setFlagValue(theFlag, 1, theZone)\\\
\\\
    end\\\
    \\\
    if cfxZones.verbose then\\\
        local newVal = cfxZones.getFlagValue(theFlag, theZone)\\\
        trigger.action.outText(\\\"+++zones: flag <\\\" .. theFlag .. \\\"> changed from \\\" .. currVal .. \\\" to \\\" .. newVal, 30)\\\
    end \\\
end\\\
\\\
function cfxZones.setFlagValue(theFlag, theValue, theZone)\\\
    local zoneName = \\\"<dummy>\\\"\\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++Zne: no zone on setFlagValue\\\")\\\
    else \\\
        zoneName = theZone.name -- for flag wildcards\\\
    end\\\
    \\\
    if type(theFlag) == \\\"number\\\" then \\\
        -- straight set, ME flag \\\
        trigger.action.setUserFlag(theFlag, theValue)\\\
        return \\\
    end\\\
    \\\
    -- we assume it's a string now\\\
    theFlag = dcsCommon.trim(theFlag) -- clear leading/trailing spaces\\\
    local nFlag = tonumber(theFlag) \\\
    if nFlag then \\\
        trigger.action.setUserFlag(theFlag, theValue)\\\
        return \\\
    end\\\
    \\\
    -- now do wildcard processing. we have alphanumeric\\\
    if dcsCommon.stringStartsWith(theFlag, \\\"*\\\") then  \\\
        theFlag = zoneName .. theFlag\\\
    end\\\
    trigger.action.setUserFlag(theFlag, theValue)\\\
end \\\
\\\
function cfxZones.getFlagValue(theFlag, theZone)\\\
    local zoneName = \\\"<dummy>\\\"\\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++Zne: no zone on getFlagValue\\\", 30)\\\
    else \\\
        zoneName = theZone.name -- for flag wildcards\\\
    end\\\
    \\\
    if type(theFlag) == \\\"number\\\" then \\\
        -- straight get, ME flag \\\
        return tonumber(trigger.misc.getUserFlag(theFlag))\\\
    end\\\
    \\\
    -- we assume it's a string now\\\
    theFlag = dcsCommon.trim(theFlag) -- clear leading/trailing spaces\\\
    local nFlag = tonumber(theFlag) \\\
    if nFlag then \\\
        return tonumber(trigger.misc.getUserFlag(theFlag))\\\
    end\\\
    \\\
    -- now do wildcard processing. we have alphanumeric\\\
    if dcsCommon.stringStartsWith(theFlag, \\\"*\\\") then  \\\
            theFlag = zoneName .. theFlag\\\
    end\\\
    return tonumber(trigger.misc.getUserFlag(theFlag))\\\
end\\\
\\\
function cfxZones.isMEFlag(inFlag)\\\
    -- do NOT use me\\\
    trigger.action.outText(\\\"+++zne: warning: deprecated isMEFlag\\\", 30)\\\
    return true \\\
    -- returns true if inFlag is a pure positive number\\\
--    inFlag = dcsCommon.trim(inFlag)\\\
--    return dcsCommon.stringIsPositiveNumber(inFlag)\\\
end\\\
\\\
function cfxZones.flagArrayFromString(inString)\\\
-- original code from RND flag\\\
    if string.len(inString) < 1 then \\\
        trigger.action.outText(\\\"+++zne: empty flags\\\", 30)\\\
        return {} \\\
    end\\\
    if cfxZones.verbose then \\\
        trigger.action.outText(\\\"+++zne: processing <\\\" .. inString .. \\\">\\\", 30)\\\
    end \\\
    \\\
    local flags = {}\\\
    local rawElements = dcsCommon.splitString(inString, \\\",\\\")\\\
    -- go over all elements \\\
    for idx, anElement in pairs(rawElements) do \\\
        if dcsCommon.stringStartsWithDigit(anElement) and  dcsCommon.containsString(anElement, \\\"-\\\") then \\\
            -- interpret this as a range\\\
            local theRange = dcsCommon.splitString(anElement, \\\"-\\\")\\\
            local lowerBound = theRange[1]\\\
            lowerBound = tonumber(lowerBound)\\\
            local upperBound = theRange[2]\\\
            upperBound = tonumber(upperBound)\\\
            if lowerBound and upperBound then\\\
                -- swap if wrong order\\\
                if lowerBound > upperBound then \\\
                    local temp = upperBound\\\
                    upperBound = lowerBound\\\
                    lowerBound = temp \\\
                end\\\
                -- now add add numbers to flags\\\
                for f=lowerBound, upperBound do \\\
                    table.insert(flags, tostring(f))\\\
                end\\\
            else\\\
                -- bounds illegal\\\
                trigger.action.outText(\\\"+++zne: ignored range <\\\" .. anElement .. \\\"> (range)\\\", 30)\\\
            end\\\
        else\\\
            -- single number\\\
            f = dcsCommon.trim(anElement) -- DML flag upgrade: accept strings tonumber(anElement)\\\
            if f then \\\
                table.insert(flags, f)\\\
\\\
            else \\\
                trigger.action.outText(\\\"+++zne: ignored element <\\\" .. anElement .. \\\"> (single)\\\", 30)\\\
            end\\\
        end\\\
    end\\\
    if cfxZones.verbose then \\\
        trigger.action.outText(\\\"+++zne: <\\\" .. #flags .. \\\"> flags total\\\", 30)\\\
    end \\\
    return flags\\\
end\\\
\\\
--\\\
-- PROPERTY PROCESSING \\\
--\\\
\\\
function cfxZones.getAllZoneProperties(theZone, caseInsensitive) -- return as dict \\\
    if not caseInsensitive then caseInsensitive = false end \\\
    if not theZone then return {} end \\\
    \\\
    local dcsProps = theZone.properties -- zone properties in dcs format \\\
    local props = {}\\\
    -- dcs has all properties as array with values .key and .value \\\
    -- so convert them into a dictionary \\\
    for i=1, #dcsProps do \\\
        local theProp = dcsProps[i]\\\
        local theKey = \\\"dummy\\\"\\\
        if string.len(theProp.key) > 0 then theKey = theProp.key end \\\
        if caseInsensitive then theKey = theKey:upper() end \\\
        props[theKey] = theProp.value\\\
    end\\\
    return props \\\
end\\\
\\\
function cfxZones.extractPropertyFromDCS(theKey, theProperties)\\\
-- trim\\\
    theKey = dcsCommon.trim(theKey) \\\
--    make lower case conversion if not case sensitive\\\
    if not cfxZones.caseSensitiveProperties then \\\
        theKey = string.lower(theKey)\\\
    end\\\
\\\
-- iterate all keys and compare to what we are looking for     \\\
    for i=1, #theProperties do\\\
        local theP = theProperties[i]\\\
         \\\
        local existingKey = dcsCommon.trim(theP.key)  \\\
        if not cfxZones.caseSensitiveProperties then \\\
            existingKey = string.lower(existingKey)\\\
        end\\\
        if existingKey == theKey then \\\
            return theP.value\\\
        end\\\
    end\\\
    return nil \\\
end\\\
\\\
function cfxZones.getZoneProperty(cZone, theKey)\\\
    if not cZone then \\\
        trigger.action.outText(\\\"+++zone: no zone in getZoneProperty\\\", 30)\\\
        return nil\\\
    end \\\
    if not theKey then \\\
        trigger.action.outText(\\\"+++zone: no property key in getZoneProperty for zone \\\" .. cZone.name, 30)\\\
--        breakme.here = 1\\\
        return \\\
    end    \\\
\\\
    local props = cZone.properties\\\
    local theVal = cfxZones.extractPropertyFromDCS(theKey, props)\\\
    return theVal\\\
end\\\
\\\
function cfxZones.getStringFromZoneProperty(theZone, theProperty, default)\\\
    \\\
    if not default then default = \\\"\\\" end\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    if not p then return default end\\\
    if type(p) == \\\"string\\\" then \\\
        if p == \\\"\\\" then p = default end \\\
        return p\\\
    end\\\
    return default -- warning. what if it was a number first?\\\
end\\\
\\\
function cfxZones.getMinMaxFromZoneProperty(theZone, theProperty)\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    local theNumbers = dcsCommon.splitString(p, \\\" \\\")\\\
\\\
    return tonumber(theNumbers[1]), tonumber(theNumbers[2])\\\
    \\\
end\\\
\\\
function cfxZones.randomDelayFromPositiveRange(minVal, maxVal) \\\
    if not maxVal then return minVal end \\\
    if not minVal then return maxVal end \\\
    local delay = maxVal\\\
    if minVal > 0 and minVal < delay then \\\
        -- we want a randomized from time from minTime .. delay\\\
        local varPart = delay - minVal + 1\\\
        varPart = dcsCommon.smallRandom(varPart) - 1\\\
        delay = minVal + varPart\\\
    end\\\
    return delay \\\
end\\\
\\\
function cfxZones.getPositiveRangeFromZoneProperty(theZone, theProperty, default)\\\
    -- reads property as string, and interprets as range 'a-b'. \\\
    -- if not a range but single number, returns both for upper and lower \\\
    --trigger.action.outText(\\\"***Zne: enter with <\\\" .. theZone.name .. \\\">: range for property <\\\" .. theProperty .. \\\">!\\\", 30)\\\
    if not default then default = 0 end \\\
    local lowerBound = default\\\
    local upperBound = default \\\
    \\\
    local rangeString = cfxZones.getStringFromZoneProperty(theZone, theProperty, \\\"\\\")\\\
    if dcsCommon.containsString(rangeString, \\\"-\\\") then \\\
        local theRange = dcsCommon.splitString(rangeString, \\\"-\\\")\\\
        lowerBound = theRange[1]\\\
        lowerBound = tonumber(lowerBound)\\\
        upperBound = theRange[2]\\\
        upperBound = tonumber(upperBound)\\\
        if lowerBound and upperBound then\\\
            -- swap if wrong order\\\
            if lowerBound > upperBound then \\\
                local temp = upperBound\\\
                upperBound = lowerBound\\\
                lowerBound = temp \\\
            end\\\
--            if rndFlags.verbose then \\\
--            trigger.action.outText(\\\"+++Zne: detected range <\\\" .. lowerBound .. \\\", \\\" .. upperBound .. \\\">\\\", 30)\\\
--            end\\\
        else\\\
            -- bounds illegal\\\
            trigger.action.outText(\\\"+++Zne: illegal range  <\\\" .. rangeString .. \\\">, using \\\" .. default .. \\\"-\\\" .. default, 30)\\\
            lowerBound = default\\\
            upperBound = default \\\
        end\\\
    else \\\
        upperBound = cfxZones.getNumberFromZoneProperty(theZone, theProperty, default) -- between pulses \\\
        lowerBound = upperBound\\\
    end\\\
--    trigger.action.outText(\\\"+++Zne: returning <\\\" .. lowerBound .. \\\", \\\" .. upperBound .. \\\">\\\", 30)\\\
    return lowerBound, upperBound\\\
end\\\
\\\
function cfxZones.hasProperty(theZone, theProperty) \\\
    return cfxZones.getZoneProperty(theZone, theProperty) ~= nil \\\
end\\\
\\\
\\\
function cfxZones.getBoolFromZoneProperty(theZone, theProperty, defaultVal)\\\
    if not defaultVal then defaultVal = false end \\\
    if type(defaultVal) ~= \\\"boolean\\\" then \\\
        defaultVal = false \\\
    end\\\
\\\
    if not theZone then \\\
        trigger.action.outText(\\\"WARNING: NIL Zone in getBoolFromZoneProperty\\\", 30)\\\
        return defaultVal\\\
    end\\\
\\\
\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    if not p then return defaultVal end\\\
\\\
    -- make sure we compare so default always works when \\\
    -- answer isn't exactly the opposite\\\
    p = p:lower() \\\
    if defaultVal == false then \\\
        -- only go true if exact match to yes or true \\\
        theBool = false \\\
        theBool = (p == 'true') or (p == 'yes') or p == \\\"1\\\"\\\
        return theBool\\\
    end\\\
    \\\
    local theBool = true \\\
    -- only go false if exactly no or false or \\\"0\\\"\\\
    theBool = (p ~= 'false') and (p ~= 'no') and (p ~= \\\"0\\\") \\\
    return theBool\\\
end\\\
\\\
function cfxZones.getCoalitionFromZoneProperty(theZone, theProperty, default)\\\
    if not default then default = 0 end\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    if not p then return default end  \\\
    if type(p) == \\\"number\\\" then -- can't currently really happen\\\
        if p == 1 then return 1 end \\\
        if p == 2 then return 2 end \\\
        return 0\\\
    end\\\
    \\\
    if type(p) == \\\"string\\\" then \\\
        if p == \\\"1\\\" then return 1 end \\\
        if p == \\\"2\\\" then return 2 end \\\
        if p == \\\"0\\\" then return 0 end \\\
        \\\
        p = p:lower()\\\
        \\\
        if p == \\\"red\\\" then return 1 end \\\
        if p == \\\"blue\\\" then return 2 end \\\
        if p == \\\"neutral\\\" then return 0 end\\\
        if p == \\\"all\\\" then return 0 end \\\
        return default \\\
    end\\\
    \\\
    return default \\\
end\\\
\\\
function cfxZones.getNumberFromZoneProperty(theZone, theProperty, default)\\\
--TODO: trim string \\\
    if not default then default = 0 end\\\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\\\
    p = tonumber(p)\\\
    if not p then return default else return p end\\\
end\\\
\\\
function cfxZones.getVectorFromZoneProperty(theZone, theProperty, minDims, defaultVal)\\\
    if not minDims then minDims = 0 end \\\
    if not defaultVal then defaultVal = 0 end \\\
    local s = cfxZones.getStringFromZoneProperty(theZone, theProperty, \\\"\\\")\\\
    local sVec = dcsCommon.splitString(s, \\\",\\\")\\\
    local nVec = {}\\\
    for idx, numString in pairs (sVec) do \\\
        local n = tonumber(numString)\\\
        if not n then n = defaultVal end\\\
        table.insert(nVec, n)\\\
    end\\\
    -- make sure vector contains at least minDims values \\\
    while #nVec < minDims do \\\
        table.insert(nVec, defaultVal)\\\
    end\\\
    \\\
    return nVec \\\
end\\\
\\\
function cfxZones.getSmokeColorStringFromZoneProperty(theZone, theProperty, default) -- smoke as 'red', 'green', or 1..5\\\
    if not default then default = \\\"red\\\" end \\\
    local s = cfxZones.getStringFromZoneProperty(theZone, theProperty, default)\\\
    s = s:lower()\\\
    s = dcsCommon.trim(s)\\\
    -- check numbers \\\
    if (s == \\\"0\\\") then return \\\"green\\\" end\\\
    if (s == \\\"1\\\") then return \\\"red\\\" end\\\
    if (s == \\\"2\\\") then return \\\"white\\\" end\\\
    if (s == \\\"3\\\") then return \\\"orange\\\" end\\\
    if (s == \\\"4\\\") then return \\\"blue\\\" end\\\
    \\\
    if s == \\\"green\\\" or\\\
       s == \\\"red\\\" or\\\
       s == \\\"white\\\" or\\\
       s == \\\"orange\\\" or\\\
       s == \\\"blue\\\" then return s end\\\
\\\
    return default \\\
end\\\
\\\
--\\\
-- Moving Zones. They contain a link to their unit\\\
-- they are always located at an offset (x,z) or delta, phi \\\
-- to their master unit. delta phi allows adjustment for heading\\\
-- The cool thing about moving zones in cfx is that they do not\\\
-- require special handling, they are always updated \\\
-- and work with 'pointinzone' etc automatically\\\
\\\
-- Always works on cfx Zones, NEVER on DCS zones.\\\
--\\\
-- requires that readFromDCS has been done\\\
--\\\
function cfxZones.getPoint(aZone) -- always works, even linked, point can be reused \\\
    if aZone.linkedUnit then \\\
        local theUnit = aZone.linkedUnit\\\
        -- has a link. is link existing?\\\
        if theUnit:isExist() then \\\
            -- updates zone position \\\
            cfxZones.centerZoneOnUnit(aZone, theUnit)\\\
            cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)\\\
        end\\\
    end\\\
    local thePos = {}\\\
    thePos.x = aZone.point.x\\\
    thePos.y = 0 -- aZone.y \\\
    thePos.z = aZone.point.z\\\
    -- since we are at it, update the zone as well\\\
    aZone.point = thePos \\\
    return thePos \\\
end\\\
\\\
function cfxZones.linkUnitToZone(theUnit, theZone, dx, dy) -- note: dy is really Z, don't get confused!!!!\\\
    theZone.linkedUnit = theUnit\\\
    if not dx then dx = 0 end\\\
    if not dy then dy = 0 end \\\
    theZone.dx = dx\\\
    theZone.dy = dy \\\
end\\\
\\\
function cfxZones.updateMovingZones()\\\
    cfxZones.updateSchedule = timer.scheduleFunction(cfxZones.updateMovingZones, {}, timer.getTime() + 1/cfxZones.ups)\\\
    -- simply scan all cfx zones for the linkedUnit property and if there\\\
    -- update the zone's points\\\
    for aName,aZone in pairs(cfxZones.zones) do\\\
        if aZone.linkedUnit then \\\
            local theUnit = aZone.linkedUnit\\\
            -- has a link. is link existing?\\\
            if theUnit:isExist() then \\\
                cfxZones.centerZoneOnUnit(aZone, theUnit)\\\
                cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)\\\
                --trigger.action.outText(\\\"cf/x zones update \\\" .. aZone.name, 30)\\\
            end\\\
        end\\\
    end\\\
end\\\
\\\
function cfxZones.startMovingZones()\\\
    -- read all zoness, and look for a property called 'linkedUnit'\\\
    -- which will make them a linked zone if there is a unit that exists\\\
    for aName,aZone in pairs(cfxZones.zones) do\\\
        local lU = cfxZones.getZoneProperty(aZone, \\\"linkedUnit\\\")\\\
        if lU then \\\
            -- this zone is linked to a unit\\\
            theUnit = Unit.getByName(lU)\\\
            local useOffset = cfxZones.getBoolFromZoneProperty(aZone, \\\"useOffset\\\", false)\\\
            if useOffset then aZone.useOffset = true end\\\
            if theUnit then\\\
                local dx = 0\\\
                local dz = 0\\\
                if useOffset then \\\
                    local delta = dcsCommon.vSub(aZone.point,theUnit:getPoint()) -- delta = B - A \\\
                    dx = delta.x \\\
                    dz = delta.z\\\
                end\\\
                cfxZones.linkUnitToZone(theUnit, aZone, dx, dz)\\\
                --trigger.action.outText(\\\"cf/x zones: linked \\\" .. aZone.name .. \\\" to \\\" .. theUnit:getName(), 30)\\\
                if useOffset then \\\
                    --trigger.action.outText(\\\"and dx = \\\" .. dx .. \\\" dz = \\\" .. dz, 30)\\\
                end\\\
            end\\\
 \\\
        end\\\
    end\\\
end\\\
\\\
--\\\
-- init\\\
--\\\
\\\
function cfxZones.init()\\\
    -- read all zones into my own db\\\
    cfxZones.readFromDCS(true) -- true: erase old\\\
    \\\
    -- now, pre-read zone owner for all zones\\\
    -- note, all zones with this property are by definition owned zones.\\\
    -- and hence will be read anyway. this will merely ensure that the \\\
    -- ownership is established right away\\\
    -- unless owned zones module is missing, in which case \\\
    -- ownership is still established \\\
    local pZones = cfxZones.zonesWithProperty(\\\"owner\\\")\\\
    for n, aZone in pairs(pZones) do\\\
        aZone.owner = cfxZones.getCoalitionFromZoneProperty(aZone, \\\"owner\\\", 0)\\\
    end\\\
        \\\
    \\\
    -- now initialize moving zones\\\
    cfxZones.startMovingZones()\\\
    cfxZones.updateMovingZones() -- will auto-repeat\\\
    \\\
    trigger.action.outText(\\\"cf/x Zones v\\\".. cfxZones.version .. \\\": loaded\\\", 10)\\\
end\\\
\\\
-- get everything rolling\\\
cfxZones.init()\\\
\");a_do_script(\"-- cfx player handler for DCS Missions by cf/x AG\\\
-- \\\
-- a module that provides easy access to a mission's player data\\\
-- multi-player only\\\
--\\\
\\\
cfxPlayer = {}\\\
                           -- a call to cfxPlayer.start()\\\
cfxPlayer.version = \\\"3.0.1\\\"\\\
--[[-- VERSION HISTORY\\\
\\\
- 2.2.3 - fixed isPlayerUnit() wrong return of true instead of nil\\\
- 2.2.4 - getFirstGroupPlayer\\\
- 2.3.0 - added event filtering for monitors\\\
        - limited code clean-up\\\
        - removed XXXmatchUnitToPlayer\\\
        - corrected isPlayerUnit once more\\\
        - removed autostart option\\\
        - removed detectPlayersLeaving option \\\
- 3.0.0 - added detection of network players \\\
        - added new events newPlayer, changePlayer \\\
        - and leavePlayer (never called)\\\
- 3.0.1 - isPlayerUnit guard against scenery object or map object \\\
--]]--\\\
\\\
cfxPlayer.verbose = false;\\\
cfxPlayer.running = false \\\
cfxPlayer.ups = 1 -- updates per second: how often do we query the players \\\
                  -- a good value is 1\\\
cfxPlayer.playerDB = {} -- the list of all player UNITS\\\
        -- attributes\\\
            -- name - name of unit occupied by player\\\
            -- unit - unit this player is controlling\\\
            -- unitName - same as name\\\
            -- group - group this unit belongs to. can't change without also changing unit\\\
            -- groupName - name of group\\\
            -- coalition\\\
cfxPlayerGroups = {} -- GLOBAL VAR \\\
-- list of all current groups that have players in them \\\
-- can call out to handlers if group is added or removed\\\
-- use this in MP games to organise messaging and keep score\\\
-- by default, groupinfo merely contains the .group reference \\\
-- and is accessed by name as key which is also accessible by .name\\\
            \\\
cfxPlayer.netPlayers = {} -- new for version 3: real player detection\\\
-- a dict sorted by player name that containts the unit name for last pass \\\
\\\
cfxPlayer.updateSchedule = 0 -- ID used for scheduling update\\\
cfxPlayer.coalitionSides = {0, 1, 2} -- we currently have neutral, red, blue\\\
\\\
cfxPlayer.monitors = {} -- callbacks for events\\\
\\\
---\\\
-- structure of playerInfo\\\
--   - name - player's unit name\\\
--   - unit - the unit the player is occupying. Multi-Crew: many people can be in same unit\\\
--   - unitName same as name \\\
\\\
--   - coalition - the side the unit is on, as a number \\\
function cfxPlayer.dumpRawPlayers()\\\
    trigger.action.outText(\\\"+++ debug: raw player dump ---\\\", 30)\\\
    for i=1, #cfxPlayer.coalitionSides do \\\
        local theSide = cfxPlayer.coalitionSides[i] \\\
        -- get all players for this side\\\
        local thePlayers = coalition.getPlayers(theSide) \\\
        for p=1, #thePlayers do \\\
            aPlayerUnit = thePlayers[p] -- docs say this is a unit table, not a person table!\\\
            trigger.action.outText(i .. \\\"-\\\" .. p ..\\\": unit: \\\" .. aPlayerUnit:getName() .. \\\" controlled by \\\" .. aPlayerUnit:getPlayerName() , 30)\\\
        end\\\
    end\\\
    trigger.action.outText(\\\"+++ debug: END DUMP ----\\\", 30)\\\
end\\\
\\\
\\\
function cfxPlayer.getAllPlayers()\\\
    return cfxPlayer.playerDB -- get entire db. make sure not to screw around with it\\\
end\\\
\\\
\\\
function cfxPlayer.getPlayerInfoByName(theUnitName) -- note: UNIT name\\\
    thePlayer = cfxPlayer.playerDB[theUnitName] -- access the entry, not we are accessing by unit name\\\
    return thePlayer\\\
end\\\
\\\
function cfxPlayer.getPlayerInfoByIndex(theIndex) \\\
    local enumeratedInfo = dcsCommon.enumerateTable(cfxPlayer.playerDB)\\\
    if (theIndex > #enumeratedInfo) then\\\
        trigger.action.outText(\\\"WARNING: player index \\\" .. theIndex .. \\\" out of bounds - max = \\\" .. #enumeratedInfo, 30)\\\
        return nil end\\\
    if (theIndex < 1) then return nil end\\\
    \\\
    return enumeratedInfo[theIndex]\\\
end\\\
\\\
-- this is now a true/false function that returns true if unit is player \\\
function cfxPlayer.XXXmatchUnitToPlayer(theUnit) -- what's difference to getPlayerInfo? GetPlayerInfo ALLOCATES if not exists \\\
\\\
    if not (theUnit) then return false end\\\
    if not (theUnit:isExist()) then return false end \\\
    \\\
    -- PATCH: if theUnit:getPlayerName() returns anything but nil\\\
    -- this is a player unit\\\
    -- unfortunately, this can sometimes fail\\\
    -- so make sure the function existst\\\
    -- it failed because the next level up function \\\
    -- returned true if i returned anything but nil, and I return \\\
    -- true or false, both not nil \\\
    -- this proc works \\\
    if not theUnit.getPlayerName then return false end \\\
    \\\
    local pName = theUnit:getPlayerName()\\\
    if pName ~= nil then \\\
        -- trigger.action.outText(\\\"+++matchUnit: player name \\\" .. pName .. \\\" for unit \\\" .. theUnit:getName(), 30)\\\
        return true \\\
    end \\\
    \\\
    if (true) then \\\
        return false\\\
    end \\\
    \\\
    -- ignmore old code below\\\
\\\
    for pname, pInfo in pairs(cfxPlayer.playerDB) do \\\
        if (pInfo.unit == theUnit) then \\\
            return pInfo\\\
        end\\\
    end\\\
    return nil\\\
end\\\
\\\
function cfxPlayer.XXXisPlayerUnitAlt(theUnit)\\\
    for pname, pInfo in pairs(cfxPlayer.playerDB) do \\\
        if (pInfo.unit == theUnit) then \\\
            return true\\\
        end\\\
    end\\\
    return false\\\
end\\\
\\\
function cfxPlayer.isPlayerUnit(theUnit)\\\
    -- new patch. simply check if getPlayerName returns something\\\
    if not theUnit then return false end \\\
    if not theUnit.getPlayerName then return false end -- map/static object \\\
    local pName = theUnit:getPlayerName()\\\
    if pName then return true end \\\
    return false \\\
    --\\\
    -- fixed, erroneously expected a nil from matchUnitToPlayer \\\
    --return (cfxPlayer.matchUnitToPlayer(theUnit)) -- was: ~=nil, wrong because match returns true/false\\\
end\\\
\\\
\\\
\\\
function cfxPlayer.getPlayerUnitType(thePlayerInfo) -- \\\
    if (thePlayerInfo) then \\\
        theUnit = thePlayerInfo.unit\\\
        if (theUnit) and (theUnit:isExist()) then \\\
            return theUnit:getTypeName()\\\
        end\\\
    end\\\
    return nil \\\
end\\\
\\\
\\\
-- get player's unit info\\\
-- accesses player DB and returns the player's info record for the\\\
-- player's Unit. If record does not exist in db, a new record is allocated\\\
-- returns true if verification succeeeds: player unit existed before, and\\\
-- false otherwise. in the latter case, A NEW playerInfo object is returned\\\
function cfxPlayer.getPlayerInfo(theUnit)\\\
    local playerName = theUnit:getPlayerName() -- retrieve the name \\\
    --- PATCH!!!!!!!\\\
    --- on multi-crew, we only have the pilot as getPlayerName. \\\
    --- we now switch to the unit's name instead \\\
    playerName = theUnit:getName() \\\
    \\\
    -- trigger.action.outText(\\\"Player: \\\".. playerName, 10)\\\
\\\
    local existingPlayer = cfxPlayer.getPlayerInfoByName(playerName) -- try and access DB\\\
    if existingPlayer then\\\
        -- this player exists in the db. return the record\\\
        return true, existingPlayer;\\\
\\\
    else\\\
        -- this is a new player.\\\
        -- set up a new playerinfo record for this name\\\
        local newPlayerInfo = {}\\\
        newPlayerInfo.name = playerName\\\
        newPlayerInfo.unit = theUnit\\\
        newPlayerInfo.unitName = theUnit:getName()\\\
        newPlayerInfo.group = theUnit:getGroup()\\\
        newPlayerInfo.groupName = newPlayerInfo.group:getName()\\\
        newPlayerInfo.coalition = theUnit:getCoalition() -- seems to work when first param is class self\\\
        -- note that this record did not exist, and return record\\\
        return false, newPlayerInfo\\\
    end\\\
    \\\
end;\\\
\\\
function cfxPlayer.getSinglePlayerAirframe()\\\
    -- ALWAYS return a string! This is for debugging purposes\\\
    local thePlayers = {}\\\
    local count = 0\\\
    local theAirframe = \\\"(none)\\\"\\\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do \\\
        count = count + 1\\\
        theAirframe = pinfo.unit:getTypeName()\\\
    end\\\
    if count < 2 then return theAirframe end -- also returns if count == 0\\\
    return \\\"<Multiplayer Not Yet Supported>\\\"\\\
end\\\
\\\
function cfxPlayer.getAnyPlayerAirframe()\\\
    -- use this for debugging, in single-player missions, or where it \\\
    -- is unimportant which player, just a player\\\
    -- assumes that all players use the same airframe or are in the \\\
    -- same group / unit \\\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do \\\
        if (pinfo.unit:isExist()) then \\\
            -- player may just have crashed or left\\\
            local theAirframe = pinfo.unit:getTypeName()\\\
            return theAirframe -- we simply stop after first successfuly access\\\
        end\\\
    end\\\
    return \\\"error: no player\\\"\\\
end\\\
\\\
function cfxPlayer.getFirstGroupPlayerName(theGroup)\\\
 -- get the name of player of the first \\\
 -- player-controlled unit I come across in \\\
 -- this group \\\
    local allGroupUnits = theGroup:getUnits()\\\
    for ukey, uvalue in pairs(allGroupUnits) do \\\
        -- iterate units in group\\\
        if (uvalue:isExist())  then -- and cfxPlayer.isPlayerUnit(uvalue)) \\\
            -- player may just have crashed or left\\\
            -- but all units in the same group have the same type when they are aircraft\\\
            if cfxPlayer.isPlayerUnit(uvalue) then \\\
                return uvalue:getPlayerName(), uvalue \\\
            end\\\
        end\\\
    end\\\
    return nil \\\
end\\\
\\\
function cfxPlayer.getAnyGroupPlayerAirframe(theGroup)\\\
    -- get the first player-driven unit in the group\\\
    -- and pass back the airframe that is being used \\\
    local allGroupUnits = theGroup:getUnits()\\\
    for ukey, uvalue in pairs(allGroupUnits) do \\\
        \\\
        if (uvalue:isExist())  then -- and cfxPlayer.isPlayerUnit(uvalue)) \\\
            -- player may just have crashed or left\\\
            -- but all units in the same group have the same type when they are aircraft\\\
            local theAirframe = uvalue:getTypeName()\\\
            return theAirframe -- we simply stop after first successfuly access\\\
        end\\\
    end\\\
    return \\\"error: no live player in group \\\"\\\
end\\\
\\\
\\\
\\\
function cfxPlayer.getAnyPlayerPosition()\\\
    -- use this for debugging, in single-player missions, or where it \\\
    -- is unimportant which player, just a player\\\
    -- will cause issues when you derive location info or group info \\\
    -- from that player\\\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do\\\
        if (pinfo.unit:isExist()) then \\\
            local thePoint = pinfo.unit:getPoint()\\\
            return thePoint -- we simply stop after first successfuly access\\\
        end\\\
    end\\\
    return nil\\\
end\\\
\\\
function cfxPlayer.getAnyGroupPlayerPosition(theGroup)\\\
    -- enter with dcs group to search for player units within\\\
    -- step one: get all units that belong to that group\\\
    local allGroupUnits = theGroup:getUnits()\\\
    -- we now iterate all returned units and look for \\\
    -- a unit that is a player unit.\\\
    for ukey, uvalue in pairs(allGroupUnits) do \\\
        -- we currently assume single-unit groups for players\\\
        if (uvalue:isExist()) then -- and cfxPlayer.isPlayerUnit(uvalue))\\\
            -- player may just have crashed or left\\\
            local thePoint = uvalue:getPoint()\\\
            return thePoint -- we simply stop after first successfuly access\\\
        end\\\
    \\\
    end\\\
    return nil\\\
end\\\
\\\
function cfxPlayer.getAnyGroupPlayerInfo(theGroup)\\\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do \\\
        if (pinfo.unit:isExist() and pinfo.group == theGroup) then \\\
            return pinfo -- we simply stop after first successfuly access\\\
        end\\\
    end\\\
    return \\\"error: no player\\\"\\\
end\\\
\\\
\\\
function cfxPlayer.getAllPlayerGroups()\\\
    -- merely accessot. better would be returning a copy \\\
    return cfxPlayerGroups    \\\
end\\\
\\\
function cfxPlayer.getGroupDataForGroupNamed(name)\\\
    if not name then return nil end \\\
    return cfxPlayerGroups[name]\\\
end\\\
\\\
function cfxPlayer.getPlayersInGroup(theGroup)\\\
    if not theGroup then return {} end\\\
    if not theGroup:isExist() then return {} end \\\
    local gName = theGroup:getName()\\\
    local thePlayers = {}\\\
    \\\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do         \\\
        local pgName = \\\"\\\"\\\
        if pinfo.group:isExist() then pgName = pinfo.group:getName() end \\\
        if (gName == pgName) then \\\
            table.insert(thePlayers, pinfo)\\\
        end\\\
    end\\\
    return thePlayers\\\
end\\\
\\\
-- update() is called regularly to check up on the players\\\
-- when a mismatch to last player state is found, callbacks \\\
-- can be invoked\\\
\\\
function cfxPlayer.update()\\\
    \\\
    -- first, re-schedule my next invocation\\\
    cfxPlayer.updateSchedule = timer.scheduleFunction(cfxPlayer.update, {}, timer.getTime() + 1/cfxPlayer.ups)\\\
    \\\
    -- now scan the coalitions for all players\\\
    local currCount = 0 -- number of players found this pass\\\
    local currDB = {} -- db of player units this pass\\\
    local currPlayerUnitsByNames = {}    \\\
    -- iterate over all colaitions \\\
    for i=1, #cfxPlayer.coalitionSides do \\\
        local theSide = cfxPlayer.coalitionSides[i] \\\
        -- get all player units for this side\\\
        local thePlayers = coalition.getPlayers(theSide) -- returns UNITs!!!\\\
\\\
        for p=1, #thePlayers do \\\
            -- we now iterate the Units and compare what we find\\\
            local thePlayerUnit = thePlayers[p]\\\
            local isExistingPlayerUnit, theInfo = cfxPlayer.getPlayerInfo(thePlayerUnit)\\\
            \\\
            if (not isExistingPlayerUnit) then \\\
                -- add Unit (not player!) to db\\\
                cfxPlayer.playerDB [theInfo.name] = theInfo\\\
                cfxPlayer.invokeMonitorsForEvent(\\\"new\\\", \\\"Player Unit \\\" .. theInfo.name .. \\\" entered mission\\\", theInfo, {})\\\
\\\
            else\\\
                -- player's unit existed last time around\\\
                -- see if something changed:\\\
    \\\
-- currently, we track units, not players. side changes for units can't happen AT ALL \\\
                \\\
                if theInfo.coalition ~= thePlayerUnit:getCoalition() then    \\\
                    local theData = {}\\\
                    theData.old = theInfo.coalition\\\
                    theData.new = thePlayerUnit:getCoalition()\\\
\\\
                    -- we invoke a callback\\\
                    cfxPlayer.invokeMonitorsForEvent(\\\"side\\\", \\\"Player \\\" .. theInfo.name .. \\\" switched sides to \\\" .. thePlayerUnit:getCoalition(), theInfo, theData)\\\
\\\
                end;\\\
\\\
-- we now check if the player has changed groups\\\
-- sinced we track units, this CANT HAPPEN AT ALL \\\
\\\
                if theInfo.group ~= thePlayerUnit:getGroup() then \\\
                    local theData = {}\\\
                    theData.old = theInfo.group\\\
                    theData.new = thePlayerUnit:getGroup()\\\
                    cfxPlayer.invokeMonitorsForEvent(\\\"group\\\", \\\"Player changed group to \\\" .. thePlayerUnit:getGroup():getName(), theInfo, theData)\\\
                    trigger.action.outText(\\\"+++ debug: Player \\\" .. theInfo.name .. \\\" changed GROUP to: \\\" .. thePlayerUnit:getGroup():getName(), 30)\\\
                end\\\
\\\
                -- we should now check if the player has changed units\\\
-- since we track units, this cant happen at all\\\
                if theInfo.unit ~= thePlayerUnit then\\\
                    -- player changed unit \\\
                    local theData = {}\\\
                    theData.old = theInfo.unit\\\
                    -- the old unit's name is still available in theInfo.unitName \\\
                    theData.oldUnitName = theInfo.unitName \\\
                    theData.new = thePlayerUnit\\\
                    -- update Player Info\\\
                    cfxPlayer.invokeMonitorsForEvent(\\\"unit\\\", \\\"Player changed unit to \\\" .. thePlayerUnit:getName(), theInfo, theData)\\\
                    \\\
                end\\\
                -- update the playerEntry. always done\\\
                theInfo.unit = thePlayerUnit\\\
                theInfo.unitName = thePlayerUnit:getName()\\\
                theInfo.coalition = thePlayerUnit:getCoalition()\\\
                theInfo.group = thePlayerUnit:getGroup()        \\\
            end;\\\
            \\\
            -- add this entry to current pass db so we can detect\\\
            -- any discrepancies to last pass\\\
            currDB[theInfo.name] = theInfo \\\
            \\\
            -- now update current network player name db\\\
            local playerUnitName = thePlayerUnit:getName()\\\
            if not thePlayerUnit:isExist() then playerUnitName = \\\"<none>\\\" end \\\
            currPlayerUnitsByNames[thePlayerUnit:getPlayerName()] = playerUnitName\\\
        end -- for all player units of this side\\\
    end -- for all sides\\\
    \\\
    -- we can now check if a player unit has disappeared    \\\
    -- we do this by checking that all old entries from cfxPlayer.playerDB\\\
    -- have an existing counterpart in new currDB\\\
    for name, info in pairs(cfxPlayer.playerDB) do\\\
        local matchingEntry = currDB[name]\\\
        if matchingEntry then \\\
            -- allright nothing to do\\\
        else\\\
            -- whoa, this record is missing!\\\
            -- do we care?\\\
            if true then -- (cfxPlayer.detectPlayersLeaving) then\\\
                -- yes! trigger an event\\\
                cfxPlayer.invokeMonitorsForEvent(\\\"leave\\\", \\\"Player left mission\\\", info, {})\\\
                -- we don't need to destroy entry, as we simply replace the\\\
                -- playerDB with currDB at end of update\\\
            else \\\
                -- no, just copy old data over. They'll be back\\\
                currDB[name] = info\\\
            end\\\
        end \\\
    end;\\\
    \\\
    -- we now perform a group check and update all groups for players \\\
    local currPlayerGroups = {}\\\
    for pName, pInfo in pairs(currDB) do \\\
        -- retrieve player unit and make sure it still exists\\\
        local theUnit = pInfo.unit\\\
        if theUnit:isExist() then \\\
            -- yeah, it exists allright. let's get to the group\\\
            local theGroup = theUnit:getGroup()\\\
            local gName = theGroup:getName()\\\
            -- see if this group is new\\\
            local thePGroup = cfxPlayerGroups[gName]\\\
            if not thePGroup then \\\
                -- allocate new group\\\
                thePGroup = {}\\\
                thePGroup.group = theGroup\\\
                thePGroup.name = gName \\\
                thePGroup.primeUnit = theUnit -- may be used as fallback\\\
                thePGroup.primeUnitName = theUnit:getName() -- also fallback only\\\
                thePGroup.id = theGroup:getID()\\\
                cfxPlayer.invokeMonitorsForEvent(\\\"newGroup\\\", \\\"New Player Group \\\" .. gName .. \\\" appeared\\\", nil, thePGroup)\\\
            end\\\
            currPlayerGroups[gName] = thePGroup -- update group table\\\
        end\\\
    end\\\
\\\
    -- now check if a player group has disappeared\\\
    for gkey, gval in pairs(cfxPlayerGroups) do \\\
        if not currPlayerGroups[gkey] then \\\
            cfxPlayer.invokeMonitorsForEvent(\\\"removeGroup\\\", \\\"A Player Group \\\" .. gkey .. \\\" vanished\\\", nil, gval) -- gval is OLD set, contains group \\\
        end\\\
    end\\\
    \\\
    -- version 3 addion: track network players\\\
    -- see if a new player has appeared \\\
    for aPlayerName, aPlayerUnitName in pairs(currPlayerUnitsByNames) do \\\
        -- see if this name was already in last \\\
        if cfxPlayer.netPlayers[aPlayerName] then \\\
            -- yes. but was it the same unit?\\\
            if cfxPlayer.netPlayers[aPlayerName] == currPlayerUnitsByNames[aPlayerName] then \\\
                -- all is well, no change \\\
            else \\\
                -- player has changed units \\\
                -- since they can't disappear, \\\
                -- this event can happen \\\
                local data = {}\\\
                data.oldUnitName = cfxPlayer.netPlayers[aPlayerName]\\\
                data.newUnitName = aPlayerUnitName\\\
                data.playerName = aPlayerName\\\
                if aPlayerUnitName == \\\"\\\" then aPlayerUnitName = \\\"<none>\\\" end \\\
                if aPlayerUnitName == \\\"<none>\\\" then \\\
                    -- unit no longer exists, player probably dead,\\\
                    -- parachuting or spectating. Maybe even left game\\\
                    -- resgisters as 'change' -- is 'left unit'\\\
                    cfxPlayer.invokeMonitorsForEvent(\\\"changePlayer\\\", \\\"A Player left unit \\\" .. data.oldUnitName, nil, data)\\\
                else \\\
                    -- changed to new unit\\\
                    cfxPlayer.invokeMonitorsForEvent(\\\"changePlayer\\\", \\\"A Player changed to unit \\\" .. aPlayerUnitName, nil, data)\\\
                end \\\
            end\\\
        else \\\
            -- this is a new player\\\
            local data = {}\\\
            data.playerName = aPlayerName\\\
            data.newUnitName = aPlayerUnitName\\\
            cfxPlayer.invokeMonitorsForEvent(\\\"newPlayer\\\", \\\"New Player appeared \\\" .. aPlayerName .. \\\" in unit \\\" .. aPlayerUnitName, nil, data)\\\
        end\\\
    end\\\
\\\
    -- version 3: detect if a player left \\\
    for oldPlayerName, oldUnitName in pairs(cfxPlayer.netPlayers) do \\\
        if not currPlayerUnitsByNames[oldPlayerName] then \\\
            --local data = {}\\\
            --data.playerName = oldPlayerName\\\
            --data.oldUnitName = oldUnitName\\\
            --cfxPlayer.invokeMonitorsForEvent(\\\"leavePlayer\\\", \\\"Player \\\" .. oldPlayerName .. \\\" disappeared from unit \\\" .. oldUnitName, nil, data)\\\
            --\\\
            -- we keep the player in the db by copying \\\
            -- it over and set the unit name to \\\"\\\"\\\
            -- will cause at least once 'change' event later \\\
            -- probably two in MP\\\
            currPlayerUnitsByNames[oldPlayerName] = \\\"<none>\\\"\\\
        end\\\
    end\\\
    \\\
    -- update playerGroups for this cycle\\\
    cfxPlayerGroups = currPlayerGroups\\\
    \\\
    -- update network player for this c<cle \\\
    cfxPlayer.netPlayers = currPlayerUnitsByNames\\\
    \\\
    -- finally, we simply replace the old db with the new one\\\
    cfxPlayer.playerDB = currDB;\\\
end\\\
\\\
function cfxPlayer.getAllNetPlayerNames ()\\\
    local themAll = {}\\\
    for aName, aUnitName in cfxPlayer.netPlayers do \\\
        table.insert(themAll, aName)\\\
    end\\\
    return themAll\\\
end\\\
\\\
function cfxPlayer.getPlayerUnitName(aPlayerName) \\\
    if not aPlayerName then return nil end \\\
    return cfxPlayer.netPlayers[aPlayerName]\\\
end\\\
\\\
function cfxPlayer.isPlayerSeated(aPlayerName)\\\
    local unitName = cfxPlayer.getPlayerUnitName(aPlayerName)\\\
    if not unitName then return false end \\\
    if unitName == \\\"\\\" or unitName == \\\"<none>\\\" then return false end \\\
    return true \\\
end\\\
\\\
-- add a monitor to be notified of player events\\\
-- may provide a whitelist of events as array of strings\\\
function cfxPlayer.addMonitor(callback, events)\\\
    local newMonitor = {}\\\
    newMonitor.callback = callback\\\
    newMonitor.events = events \\\
    cfxPlayer.monitors[callback] = newMonitor\\\
end;\\\
\\\
function cfxPlayer.removeMonitor(callback) \\\
    if (cfxMonitos[callback]) then \\\
        cfxMonitos[callback] = nil \\\
    end\\\
end\\\
\\\
function cfxPlayer.invokeMonitorsForEvent(evType, description, player, data)\\\
    for callback, monitor in pairs(cfxPlayer.monitors) do\\\
        -- should filter if evType is in monitor.events\\\
        if monitor.events and #monitor.events > 0 then \\\
            -- only invoke if this event is listed\\\
            if dcsCommon.arrayContainsString(monitor.events, evType) then \\\
                monitor.callback(evType, description, player, data)\\\
            end\\\
        else \\\
            monitor.callback(evType, description, player, data)\\\
        end\\\
    end\\\
end\\\
\\\
function cfxPlayer.getAllExistingPlayerUnitsRaw()\\\
    local apu = {}\\\
    for i=1, #cfxPlayer.coalitionSides do \\\
        local theSide = cfxPlayer.coalitionSides[i] \\\
        -- get all players for this side\\\
        local thePlayers = coalition.getPlayers(theSide) \\\
        for p=1, #thePlayers do \\\
            local aUnit = thePlayers[p]\\\
            if aUnit and aUnit:isExist() then \\\
                table.insert(apu, aUnit)\\\
            end\\\
        end\\\
    end\\\
    return apu \\\
end\\\
\\\
-- evType that can actually happen are 'new', 'leave' for units,\\\
-- 'newGroup' and 'removeGroup' for groups     \\\
function cfxPlayer.defaultMonitor(evType, description, info, data)\\\
    if cfxPlayer.verbose then\\\
        trigger.action.outText(\\\"+++Plr - evt '\\\".. evType ..\\\"': <\\\" .. description .. \\\">\\\", 30)\\\
        if (info) then \\\
            trigger.action.outText(\\\"+++Plr: for unit named: \\\" .. info.name, 30) \\\
        else \\\
            --trigger.action.outText(\\\"+++Plr: no player data\\\", 30)\\\
        end\\\
        --trigger.action.outText(\\\"+++Plr: desc: '\\\".. evType ..\\\"'<\\\" .. description .. \\\">\\\", 30)\\\
        -- we ignore the data block\\\
    end\\\
end\\\
\\\
function cfxPlayer.start()\\\
    trigger.action.outText(\\\"cf/x player v\\\".. cfxPlayer.version .. \\\": started\\\", 10)\\\
    cfxPlayer.running = true\\\
    cfxPlayer.update()    \\\
end\\\
\\\
function cfxPlayer.stop()\\\
    if cfxPlayer.verbose then \\\
        trigger.action.outText(\\\"cf/x player v\\\".. cfxPlayer.version .. \\\": stopped\\\", 10)\\\
    end\\\
    timer.removeFunction(cfxPlayer.updateSchedule) -- will require another start() to resume\\\
    cfxPlayer.running = false\\\
end\\\
\\\
function cfxPlayer.init()\\\
    trigger.action.outText(\\\"cf/x player v\\\".. cfxPlayer.version .. \\\": loaded\\\", 10)\\\
    -- when verbose, we also add a monitor to display player event\\\
    if cfxPlayer.verbose then \\\
        cfxPlayer.addMonitor(cfxPlayer.defaultMonitor, {})\\\
        trigger.action.outText(\\\"cf/x player isd verbose\\\", 10)\\\
    end\\\
    \\\
    cfxPlayer.start()\\\
end\\\
\\\
-- get everything rolling, but will only start if autostart is true\\\
cfxPlayer.init()\\\
\\\
--TODO: player status: ground, air, dead, none \\\
-- TODO: event when status changes ground/air/...\");a_do_script(\"cfxGroups = {}\\\
cfxGroups.version = \\\"1.1.0\\\"\\\
--[[--\\\
\\\
Module to read Unit data from DCS and make it available to scripts\\\
DOES NOT KEEP TRACK OF MISSION-CREATED GROUPS!!!!\\\
Main use is to access player groups for slot blocking etc since these \\\
groups can't be allocated dynamically\\\
\\\
Version history\\\
\\\
 1.0.0 - initial version\\\
 1.1.0 - for each player unit, store point(x, 0, y), and action for first WP, as well as name \\\
 \\\
--]]--\\\
\\\
cfxGroups.groups = {} -- all groups, indexed by name \\\
\\\
--[[-- group objects are \\\
    {\\\
        name= \\\"\\\", \\\
        coalition = \\\"\\\" (red, blue, neutral), \\\
        coanum = # (0, 1, 2 for neutral, red, blue)\\\
        category = \\\"\\\" (helicopter, ship, plane, vehicle, static),\\\
        hasPlayer = true/false,\\\
        playerUnits = {} (for each player unit in group: name, point, action)\\\
        \\\
    }\\\
    \\\
--]]--\\\
\\\
function cfxGroups.fetchAllGroupsFromDCS()\\\
    -- a mission is a lua table that is loaded by executing the miz. it builds\\\
    -- the environment mission table, accessible as env.mission \\\
    -- iterate the \\\"coalition\\\" table of the mission (note: NOT coalitionS)\\\
    -- inspired by mist, GIANT tip o'the hat to Grimes!    \\\
    \\\
    for coa_name_miz, coa_data in pairs(env.mission.coalition) do -- iterate all coalitions\\\
        local coa_name = coa_name_miz\\\
        if string.lower(coa_name_miz) == 'neutrals' then -- convert \\\"neutrals\\\" to \\\"neutral\\\", singular\\\
            coa_name = 'neutral'\\\
        end\\\
        -- directly convert coalition into number for easier access later\\\
        local coaNum = 0\\\
        if coa_name == \\\"red\\\" then coaNum = 1 end \\\
        if coa_name == \\\"blue\\\" then coaNum = 2 end \\\
        \\\
        if type(coa_data) == 'table' then\\\
            if coa_data.country then -- make sure there a country table for this coalition\\\
                for cntry_id, cntry_data in pairs(coa_data.country) do -- iterate all countries for this \\\
                    local countryName = string.lower(cntry_data.name)\\\
                    if type(cntry_data) == 'table' then    --just making sure\\\
                        for obj_type_name, obj_type_data in pairs(cntry_data) do\\\
                            if obj_type_name == \\\"helicopter\\\" or obj_type_name == \\\"ship\\\" or obj_type_name == \\\"plane\\\" or obj_type_name == \\\"vehicle\\\" or obj_type_name == \\\"static\\\" then --should be an unncessary check\\\
                                local category = obj_type_name\\\
                                if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then    --there's a group!\\\
\\\
                                    for group_num, group_data in pairs(obj_type_data.group) do\\\
                                        if group_data and group_data.units and type(group_data.units) == 'table' then    --making sure again- this is a valid group\\\
                                            local groupName = group_data.name\\\
                                            if env.mission.version > 7 then -- translate raw to actual \\\
                                                groupName = env.getValueDictByKey(groupName)\\\
                                            end\\\
                                            local hasPlayer = false \\\
                                            local playerUnits = {}\\\
                                            for unit_num, unit_data in pairs(group_data.units) do -- iterate units\\\
                                                -- see if there is at least one player in group \\\
                                                if unit_data.skill then \\\
                                                    if unit_data.skill == \\\"Client\\\" or  unit_data.skill == \\\"Player\\\" then\\\
                                                        -- this is player unit. save it, remember\\\
                                                        hasPlayer = true \\\
                                                        local playerData = {}\\\
                                                        playerData.name = unit_data.name\\\
                                                        playerData.point = {}\\\
                                                        playerData.point.x = unit_data.x\\\
                                                        playerData.point.y = 0\\\
                                                        playerData.point.z = unit_data.y\\\
                                                        playerData.action = \\\"none\\\" -- default \\\
                                                        \\\
                                                        -- access initial waypoint data by 'reaching up'\\\
                                                        -- into group data and extract route.points[1]\\\
                                                        if group_data.route and group_data.route.points and (#group_data.route.points > 0) then \\\
                                                            playerData.action = group_data.route.points[1].action\\\
                                                        end\\\
                                                        table.insert(playerUnits, playerData)\\\
                                                    end                                                        \\\
                                                end\\\
                                            end --for all units in group\\\
                        \\\
                                            local entry = {}\\\
                                            entry.name = groupName\\\
                                            entry.coalition = coa_name\\\
                                            entry.coaNum = coaNum \\\
                                            entry.category  = category\\\
                                            entry.hasPlayer = hasPlayer \\\
                                            entry.playerUnits = playerUnits\\\
                                            -- add to db\\\
                                            cfxGroups.groups[groupName] = entry\\\
                                            \\\
                                        end --if has group_data and group_data.units then\\\
                                    end --for all groups in category \\\
                                end --if has category data \\\
                            end --if plane, helo etc... category\\\
                        end --for all objects in country \\\
                    end --if has country data \\\
                end --for all countries in coalition\\\
            end --if coalition has country table \\\
        end -- if there is coalition data  \\\
    end --for all coalitions in mission \\\
end\\\
\\\
-- simply dump all groups to the screen\\\
function cfxGroups.showAllGroups()\\\
    for gName, gData in pairs (cfxGroups.groups) do \\\
        local isP = \\\"(NPC)\\\"\\\
        if gData.hasPlayer then isP = \\\"*PLAYER GROUP (\\\".. #gData.playerUnits ..\\\")*\\\" end\\\
        trigger.action.outText(gData.name.. \\\": \\\" .. isP .. \\\" - \\\" .. gData.category .. \\\", F:\\\" .. gData.coalition\\\
        .. \\\" (\\\" .. gData.coaNum .. \\\")\\\", 30)\\\
    end\\\
end\\\
\\\
-- return all cfxGroups that can have players in them\\\
-- includes groups that currently are not or not anymore alive\\\
function cfxGroups.getPlayerGroup()\\\
    local playerGroups = {}\\\
    for gName, gData in pairs (cfxGroups.groups) do \\\
        if gData.hasPlayer then\\\
            table.insert(playerGroups, gData)\\\
        end\\\
    end\\\
    return playerGroups \\\
end\\\
\\\
-- return all group names that can have players in them\\\
-- includes groups that currently are not or not anymore alive\\\
function cfxGroups.getPlayerGroupNames()\\\
    local playerGroups = {}\\\
    for gName, gData in pairs (cfxGroups.groups) do \\\
        if gData.hasPlayer then\\\
            table.insert(playerGroups, gName)\\\
        end\\\
    end\\\
    return playerGroups \\\
end\\\
\\\
\\\
function cfxGroups.start()\\\
    cfxGroups.fetchAllGroupsFromDCS() -- read all groups from mission. \\\
--    cfxGroups.showAllGroups()\\\
    \\\
    trigger.action.outText(\\\"cfxGroups version \\\" .. cfxGroups.version .. \\\" started\\\", 30)\\\
    return true \\\
    \\\
end\\\
\\\
cfxGroups.start() \\\
\\\
 \");a_do_script(\"cfxMX = {}\\\
cfxMX.version = \\\"1.1.0\\\"\\\
--[[--\\\
 Mission data decoder. Access to ME-built mission structures\\\
 \\\
 Copyright (c) 2022 by Christian Franz and cf/x AG\\\
 \\\
 Version History\\\
   1.0.0 - initial version \\\
   1.0.1 - getStaticFromDCSbyName()\\\
   1.1.0 - getStaticFromDCSbyName also copies groupID when not fetching orig\\\
         - on start up collects a cross reference table of all \\\
           original group id \\\
         - add linkUnit for statics \\\
   \\\
 \\\
--]]--\\\
cfxMX.groupNamesByID = {}\\\
cfxMX.groupIDbyName = {}\\\
cfxMX.groupDataByName = {}\\\
\\\
\\\
function cfxMX.getGroupFromDCSbyName(aName, fetchOriginal)\\\
    if not fetchOriginal then fetchOriginal = false end \\\
    -- fetch the group description for goup named aName (if exists)\\\
    -- returned structure must be parsed for useful information \\\
    -- returns data, category, countyID and coalitionID \\\
    -- unless fetchOriginal is true, creates a deep clone of \\\
    -- group data structure \\\
        \\\
    for coa_name_miz, coa_data in pairs(env.mission.coalition) do -- iterate all coalitions\\\
        local coa_name = coa_name_miz\\\
        if string.lower(coa_name_miz) == 'neutrals' then -- remove 's' at neutralS\\\
            coa_name = 'neutral'\\\
        end\\\
        -- directly convert coalition into number for easier access later\\\
        local coaNum = 0\\\
        if coa_name == \\\"red\\\" then coaNum = 1 end \\\
        if coa_name == \\\"blue\\\" then coaNum = 2 end \\\
        \\\
        if type(coa_data) == 'table' then -- coalition = {bullseye, nav_points, name, county}, \\\
                                          -- with county being an array \\\
            if coa_data.country then -- make sure there a country table for this coalition\\\
                for cntry_id, cntry_data in pairs(coa_data.country) do -- iterate all countries for this \\\
                    -- per country = {id, name, vehicle, helicopter, plane, ship, static}\\\
                    local countryName = string.lower(cntry_data.name)\\\
                    local countryID = cntry_data.id \\\
                    if type(cntry_data) == 'table' then    -- filter strings .id and .name \\\
                        for obj_type_name, obj_type_data in pairs(cntry_data) do\\\
                            if obj_type_name == \\\"helicopter\\\" or \\\
                               obj_type_name == \\\"ship\\\" or \\\
                               obj_type_name == \\\"plane\\\" or \\\
                               obj_type_name == \\\"vehicle\\\" or \\\
                               obj_type_name == \\\"static\\\" \\\
                            then -- (so it's not id or name)\\\
                                local category = obj_type_name\\\
                                if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then    --there's at least one group!\\\
                                    for group_num, group_data in pairs(obj_type_data.group) do\\\
                                        if group_data.name == aName then \\\
                                            local theGroup = group_data\\\
                                            -- usually we return a copy of this \\\
                                            if not fetchOriginal then \\\
                                                theGroup = dcsCommon.clone(group_data)\\\
                                            end\\\
                                            return theGroup, category, countryID  \\\
                                        end\\\
                                    end\\\
                                end --if has category data \\\
                            end --if plane, helo etc... category\\\
                        end --for all objects in country \\\
                    end --if has country data \\\
                end --for all countries in coalition\\\
            end --if coalition has country table \\\
        end -- if there is coalition data  \\\
    end --for all coalitions in mission \\\
    return nil, \\\"none\\\", \\\"none\\\"\\\
end\\\
\\\
function cfxMX.getStaticFromDCSbyName(aName, fetchOriginal)\\\
    if not fetchOriginal then fetchOriginal = false end \\\
    -- fetch the static description for static named aName (if exists)\\\
    -- returned structure must be parsed for useful information \\\
    -- returns data, category, countyID and parent group name \\\
    -- unless fetchOriginal is true, creates a deep clone of \\\
    -- static data structure \\\
        \\\
    for coa_name_miz, coa_data in pairs(env.mission.coalition) do -- iterate all coalitions\\\
        local coa_name = coa_name_miz\\\
        if string.lower(coa_name_miz) == 'neutrals' then -- remove 's' at neutralS\\\
            coa_name = 'neutral'\\\
        end\\\
        -- directly convert coalition into number for easier access later\\\
        local coaNum = 0\\\
        if coa_name == \\\"red\\\" then coaNum = 1 end \\\
        if coa_name == \\\"blue\\\" then coaNum = 2 end \\\
        \\\
        if type(coa_data) == 'table' then -- coalition = {bullseye, nav_points, name, county}, \\\
                                          -- with county being an array \\\
            if coa_data.country then -- make sure there a country table for this coalition\\\
                for cntry_id, cntry_data in pairs(coa_data.country) do -- iterate all countries for this \\\
                    -- per country = {id, name, vehicle, helicopter, plane, ship, static}\\\
                    local countryName = string.lower(cntry_data.name)\\\
                    local countryID = cntry_data.id \\\
                    if type(cntry_data) == 'table' then    -- filter strings .id and .name \\\
                        for obj_type_name, obj_type_data in pairs(cntry_data) do\\\
                            if obj_type_name == \\\"static\\\"\\\
--                               obj_type_name == \\\"helicopter\\\" or \\\
--                               obj_type_name == \\\"ship\\\" or \\\
--                               obj_type_name == \\\"plane\\\" or \\\
--                               obj_type_name == \\\"vehicle\\\" or \\\
--                               obj_type_name == \\\"static\\\" \\\
                            then -- (only look at statics)\\\
                                local category = obj_type_name\\\
                                if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then    --there's at least one static in group!\\\
                                    for group_num, group_data in pairs(obj_type_data.group) do\\\
                                        -- get linkUnit info if it exists\\\
                                        local linkUnit = nil \\\
                                        if group_data and group_data.route and group_data.route and group_data.route.points[1] then \\\
                                            linkUnit = group_data.route.points[1].linkUnit\\\
                                            if linkUnit then \\\
                                                --trigger.action.outText(\\\"MX: found missing link to \\\" .. linkUnit .. \\\" in \\\" .. group_data.name, 30)\\\
                                            end \\\
                                        end \\\
                                        \\\
                                        if group_data and group_data.units and type(group_data.units) == 'table' \\\
                                        then --make sure - again - that this is a valid group\\\
                                            for unit_num, unit_data in pairs(group_data.units) do -- iterate units\\\
                                                if unit_data.name == aName then \\\
                                                    local groupName = group_data.name\\\
                                                    local theStatic = unit_data\\\
                                                    if not fetchOriginal then \\\
                                                        theStatic = dcsCommon.clone(unit_data)\\\
                                                        -- copy group ID from group above\\\
                                                        theStatic.groupId = group_data.groupId  \\\
                                                        -- copy linked unit data \\\
                                                        theStatic.linkUnit = linkUnit\\\
                                                        \\\
                                                    end\\\
                                                    return theStatic, category, countryID, groupName  \\\
                                                \\\
                                                end -- if name match\\\
                                            end -- for all units \\\
                                        end -- has groups \\\
                                    \\\
                                    end -- is a static \\\
                                end --if has category data \\\
                            end --if plane, helo etc... category\\\
                        end --for all objects in country \\\
                    end --if has country data \\\
                end --for all countries in coalition\\\
            end --if coalition has country table \\\
        end -- if there is coalition data  \\\
    end --for all coalitions in mission \\\
    return nil, \\\"<none>\\\", \\\"<none>\\\", \\\"<no group name>\\\"\\\
end\\\
\\\
function cfxMX.createCrossReference()\\\
    for coa_name_miz, coa_data in pairs(env.mission.coalition) do -- iterate all coalitions\\\
        local coa_name = coa_name_miz\\\
        if string.lower(coa_name_miz) == 'neutrals' then -- remove 's' at neutralS\\\
            coa_name = 'neutral'\\\
        end\\\
        -- directly convert coalition into number for easier access later\\\
        local coaNum = 0\\\
        if coa_name == \\\"red\\\" then coaNum = 1 end \\\
        if coa_name == \\\"blue\\\" then coaNum = 2 end \\\
        \\\
        if type(coa_data) == 'table' then -- coalition = {bullseye, nav_points, name, county}, \\\
                                          -- with county being an array \\\
            if coa_data.country then -- make sure there a country table for this coalition\\\
                for cntry_id, cntry_data in pairs(coa_data.country) do -- iterate all countries for this \\\
                    -- per country = {id, name, vehicle, helicopter, plane, ship, static}\\\
                    local countryName = string.lower(cntry_data.name)\\\
                    local countryID = cntry_data.id \\\
                    if type(cntry_data) == 'table' then    -- filter strings .id and .name \\\
                        for obj_type_name, obj_type_data in pairs(cntry_data) do\\\
                            if obj_type_name == \\\"helicopter\\\" or \\\
                               obj_type_name == \\\"ship\\\" or \\\
                               obj_type_name == \\\"plane\\\" or \\\
                               obj_type_name == \\\"vehicle\\\" or \\\
                               obj_type_name == \\\"static\\\" \\\
                            then -- (so it's not id or name)\\\
                                local category = obj_type_name\\\
                                if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then    --there's at least one group!\\\
                                    for group_num, group_data in pairs(obj_type_data.group) do\\\
                                        local aName = group_data.name \\\
                                        local aID = group_data.groupId\\\
                                        cfxMX.groupNamesByID[aID] = aName\\\
                                        cfxMX.groupIDbyName[aName] = aID\\\
                                        cfxMX.groupDataByName[aName] = group_data\\\
                                    end\\\
                                end --if has category data \\\
                            end --if plane, helo etc... category\\\
                        end --for all objects in country \\\
                    end --if has country data \\\
                end --for all countries in coalition\\\
            end --if coalition has country table \\\
        end -- if there is coalition data  \\\
    end --for all coalitions in mission \\\
end\\\
\\\
function cfxMX.catText2ID(inText) \\\
    local outCat = 0 -- airplane \\\
    local c = inText:lower()\\\
    if c == \\\"helicopter\\\" then outCat = 1 end \\\
    if c == \\\"ship\\\" then outCat = 3 end \\\
    if c == \\\"plane\\\" then outCat = 0 end -- redundant \\\
    if c == \\\"vehicle\\\" then outCat = 2 end \\\
    if c == \\\"train\\\" then outCat = 4 end \\\
    if c == \\\"static\\\" then outCat = -1 end \\\
    return outCat\\\
end\\\
 \\\
function cfxMX.start()\\\
    cfxMX.createCrossReference()\\\
    trigger.action.outText(\\\"cfxMX: \\\"..#cfxMX.groupNamesByID .. \\\" groups processed successfully\\\", 30)\\\
end\\\
\\\
-- start \\\
cfxMX.start()\\\
\\\
\");a_do_script(\"raiseFlag = {}\\\
raiseFlag.version = \\\"1.0.1\\\"\\\
raiseFlag.verbose = false \\\
raiseFlag.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- always\\\
    \\\"cfxZones\\\", -- Zones, of course \\\
}\\\
raiseFlag.flags = {} \\\
--[[--\\\
    Raise A Flag module -- (c) 2022 by Christian Franz and cf/x AG\\\
    \\\
    Version History\\\
    1.0.0 - initial release \\\
    1.0.1 - synonym \\\"raiseFlag!\\\"\\\
    \\\
--]]--\\\
function raiseFlag.addRaiseFlag(theZone)\\\
    table.insert(raiseFlag.flags, theZone)\\\
end\\\
\\\
function raiseFlag.getRaiseFlagByName(aName) \\\
    for idx, aZone in pairs(raiseFlag.flags) do \\\
        if aName == aZone.name then return aZone end \\\
    end\\\
    if raiseFlag.verbose then \\\
        trigger.action.outText(\\\"+++rFlg: no raiseFlag with name <\\\" .. aName ..\\\">\\\", 30)\\\
    end \\\
    \\\
    return nil \\\
end\\\
\\\
--\\\
-- read attributes\\\
--\\\
function raiseFlag.createRaiseFlagWithZone(theZone)\\\
    -- get flag from faiseFlag itself\\\
    if cfxZones.hasProperty(theZone, \\\"raiseFlag\\\") then\\\
        theZone.raiseFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"raiseFlag\\\", \\\"<none>\\\") -- the flag to raise \\\
    else \\\
        theZone.raiseFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"raiseFlag!\\\", \\\"<none>\\\") -- the flag to raise \\\
    end \\\
    \\\
    theZone.flagValue = cfxZones.getNumberFromZoneProperty(theZone, \\\"value\\\", 1) -- value to set to\\\
\\\
    theZone.minAfterTime, theZone.maxAfterTime = cfxZones.getPositiveRangeFromZoneProperty(theZone, \\\"afterTime\\\", -1)\\\
\\\
    if cfxZones.hasProperty(theZone, \\\"stopFlag?\\\") then \\\
        theZone.triggerStopFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"stopFlag?\\\", \\\"none\\\")\\\
        theZone.lastTriggerStopValue = cfxZones.getFlagValue(theZone.triggerStopFlag, theZone) -- save last value\\\
    end\\\
    \\\
    theZone.scheduleID = nil \\\
    theZone.raiseStopped = false \\\
    \\\
    -- now simply schedule for invocation\\\
    local args = {}\\\
    args.theZone = theZone\\\
    if theZone.minAfterTime < 1 then \\\
        timer.scheduleFunction(raiseFlag.triggered, args, timer.getTime() + 0.5)\\\
    else\\\
        local delay = cfxZones.randomDelayFromPositiveRange(theZone.minAfterTime, theZone.maxAfterTime)        \\\
        timer.scheduleFunction(raiseFlag.triggered, args, timer.getTime() + delay)\\\
    end\\\
end\\\
\\\
function raiseFlag.triggered(args)\\\
    local theZone = args.theZone \\\
    if theZone.raiseStopped then return end \\\
    -- if we get here, we aren't stopped and do the flag pull\\\
    cfxZones.setFlagValue(theZone.raiseFlag, theZone.flagValue, theZone)\\\
end\\\
\\\
--\\\
-- update \\\
--\\\
function raiseFlag.update()\\\
    -- call me in a second to poll triggers\\\
    timer.scheduleFunction(raiseFlag.update, {}, timer.getTime() + 1)\\\
        \\\
    for idx, aZone in pairs(raiseFlag.flags) do\\\
        -- make sure to re-start before reading time limit\\\
        if aZone.triggerStopFlag then \\\
            local currTriggerVal = cfxZones.getFlagValue(aZone.triggerStopFlag, theZone)\\\
            if currTriggerVal ~= aZone.lastTriggerStopValue\\\
            then \\\
                theZone.raiseStopped = true -- we are done, no flag! \\\
            end\\\
        end\\\
    end\\\
end\\\
\\\
--\\\
-- config & go!\\\
--\\\
\\\
function raiseFlag.readConfigZone()\\\
    local theZone = cfxZones.getZoneByName(\\\"raiseFlagConfig\\\") \\\
    if not theZone then \\\
        if raiseFlag.verbose then \\\
            trigger.action.outText(\\\"+++rFlg: NO config zone!\\\", 30)\\\
        end \\\
        return \\\
    end \\\
    \\\
    raiseFlag.verbose = cfxZones.getBoolFromZoneProperty(theZone, \\\"verbose\\\", false)\\\
    \\\
    if raiseFlag.verbose then \\\
        trigger.action.outText(\\\"+++rFlg: read config\\\", 30)\\\
    end \\\
end\\\
\\\
function raiseFlag.start()\\\
    -- lib check\\\
    if not dcsCommon.libCheck then \\\
        trigger.action.outText(\\\"cfx raise flag requires dcsCommon\\\", 30)\\\
        return false \\\
    end \\\
    if not dcsCommon.libCheck(\\\"cfx Raise Flag\\\", raiseFlag.requiredLibs) then\\\
        return false \\\
    end\\\
    \\\
    -- read config \\\
    raiseFlag.readConfigZone()\\\
    \\\
    -- process cloner Zones \\\
    local attrZones = cfxZones.getZonesWithAttributeNamed(\\\"raiseFlag\\\")\\\
    for k, aZone in pairs(attrZones) do \\\
        raiseFlag.createRaiseFlagWithZone(aZone) -- process attributes\\\
        raiseFlag.addRaiseFlag(aZone) -- add to list\\\
    end\\\
    -- try synonym\\\
    attrZones = cfxZones.getZonesWithAttributeNamed(\\\"raiseFlag!\\\")\\\
    for k, aZone in pairs(attrZones) do \\\
        raiseFlag.createRaiseFlagWithZone(aZone) -- process attributes\\\
        raiseFlag.addRaiseFlag(aZone) -- add to list\\\
    end\\\
    \\\
    -- start update \\\
    raiseFlag.update()\\\
    \\\
    trigger.action.outText(\\\"cfx raiseFlag v\\\" .. raiseFlag.version .. \\\" started.\\\", 30)\\\
    return true \\\
end\\\
\\\
-- let's go!\\\
if not raiseFlag.start() then \\\
    trigger.action.outText(\\\"cfx Raise Flag aborted: missing libraries\\\", 30)\\\
    raiseFlag = nil \\\
end\");a_do_script(\"pulseFlags = {}\\\
pulseFlags.version = \\\"1.1.0\\\"\\\
pulseFlags.verbose = false \\\
pulseFlags.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- always\\\
    \\\"cfxZones\\\", -- Zones, of course \\\
}\\\
--[[--\\\
    Pulse Flags: DML module to regularly change a flag \\\
    \\\
    Copyright 2022 by Christian Franz and cf/x \\\
    \\\
    Version History\\\
    - 1.0.0 Initial version \\\
    - 1.0.1 pause behavior debugged \\\
    - 1.0.2 zero pulse optional initial pulse suppress\\\
    - 1.0.3 pollFlag switched to cfxZones \\\
            uses randomDelayFromPositiveRange\\\
            flag! now is string \\\
            WARNING: still needs full alphaNum flag upgrade \\\
    - 1.1.0 Full DML flag integration \\\
            removed zone!\\\
            made pulse and pulse! the out flag carrier\\\
            done!\\\
            pulsesDone! synonym\\\
            pausePulse? synonym\\\
            pulseMethod synonym\\\
            startPulse? synonym \\\
            pulseStopped synonym\\\
    \\\
--]]--\\\
\\\
pulseFlags.pulses = {}\\\
\\\
function pulseFlags.addPulse(aZone)\\\
    table.insert(pulseFlags.pulses, aZone)\\\
end\\\
\\\
--\\\
-- create a pulse \\\
--\\\
\\\
function pulseFlags.createPulseWithZone(theZone)\\\
    if cfxZones.hasProperty(theZone, \\\"pulse\\\") then \\\
        theZone.pulseFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"pulse\\\", \\\"*none\\\") -- the flag to pulse \\\
    end\\\
\\\
    if cfxZones.hasProperty(theZone, \\\"pulse!\\\") then \\\
        theZone.pulseFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"pulse!\\\", \\\"*none\\\") -- the flag to pulse \\\
    end\\\
    \\\
    -- time can be number, or number-number range\\\
    theZone.minTime, theZone.time = cfxZones.getPositiveRangeFromZoneProperty(theZone, \\\"time\\\", 1)\\\
    if pulseFlags.verbose then \\\
        trigger.action.outText(\\\"***PulF: zone <\\\" .. theZone.name .. \\\"> time is <\\\".. theZone.minTime ..\\\", \\\" .. theZone.time .. \\\"!\\\", 30)\\\
    end \\\
    \\\
    theZone.pulses = cfxZones.getNumberFromZoneProperty(theZone, \\\"pulses\\\", -1)\\\
    theZone.pulsesLeft = 0 -- will start new cycle \\\
        \\\
    -- trigger flags \\\
    if cfxZones.hasProperty(theZone, \\\"activate?\\\") then \\\
        theZone.activatePulseFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"activate?\\\", \\\"none\\\")\\\
        theZone.lastActivateValue = cfxZones.getFlagValue(theZone.activatePulseFlag, theZone) -- trigger.misc.getUserFlag(theZone.activatePulseFlag) -- save last value\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"startPulse?\\\") then \\\
        theZone.activatePulseFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"startPulse?\\\", \\\"none\\\")\\\
        theZone.lastActivateValue = cfxZones.getFlagValue(theZone.activatePulseFlag, theZone) -- trigger.misc.getUserFlag(theZone.activatePulseFlag) -- save last value\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"pause?\\\") then \\\
        theZone.pausePulseFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"pause?\\\", \\\"*none\\\")\\\
        theZone.lastPauseValue = cfxZones.getFlagValue(theZone.lastPauseValue, theZone)-- trigger.misc.getUserFlag(theZone.pausePulseFlag) -- save last value\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"pausePulse?\\\") then \\\
        theZone.pausePulseFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"pausePulse?\\\", \\\"*none\\\")\\\
        theZone.lastPauseValue = cfxZones.getFlagValue(theZone.lastPauseValue, theZone)-- trigger.misc.getUserFlag(theZone.pausePulseFlag) -- save last value\\\
    end\\\
    \\\
    theZone.pulsePaused = cfxZones.getBoolFromZoneProperty(theZone, \\\"paused\\\", false)\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"pulseStopped\\\") then \\\
        theZone.pulsePaused = cfxZones.getBoolFromZoneProperty(theZone, \\\"pulseStopped\\\", false)\\\
    end\\\
    \\\
    theZone.method = cfxZones.getStringFromZoneProperty(theZone, \\\"method\\\", \\\"flip\\\")\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"pulseMethod\\\") then\\\
        theZone.method = cfxZones.getStringFromZoneProperty(theZone, \\\"pulseMethod\\\", \\\"flip\\\")\\\
    end\\\
    -- done flag \\\
    if cfxZones.hasProperty(theZone, \\\"done+1\\\") then \\\
        theZone.pulseDoneFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"done+1\\\", \\\"*none\\\")\\\
    end\\\
    if cfxZones.hasProperty(theZone, \\\"pulsesDone!\\\") then \\\
        theZone.pulseDoneFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"pulsesDone!\\\", \\\"*none\\\")\\\
    end\\\
    if cfxZones.hasProperty(theZone, \\\"done!\\\") then \\\
        theZone.pulseDoneFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"done!\\\", \\\"*none\\\")\\\
    end\\\
\\\
    theZone.pulsing = false -- not running \\\
    theZone.hasPulsed = false \\\
    theZone.zeroPulse = cfxZones.getBoolFromZoneProperty(theZone, \\\"zeroPulse\\\", true)\\\
end\\\
\\\
--\\\
-- update \\\
-- \\\
\\\
\\\
function pulseFlags.doPulse(args) \\\
    local theZone = args[1]\\\
    -- check if we have been paused. if so, simply \\\
    -- exit with no new schedule \\\
    if theZone.pulsePaused then \\\
        theZone.pulsing = false \\\
        return \\\
    end \\\
    \\\
    -- do a poll on flags\\\
    -- first, we only do an initial pulse if zeroPulse is set\\\
    if theZone.hasPulsed or theZone.zeroPulse then \\\
        if pulseFlags.verbose then \\\
            trigger.action.outText(\\\"+++pulF: will bang \\\" .. theZone.pulseFlag, 30);\\\
        end\\\
        \\\
        cfxZones.pollFlag(theZone.pulseFlag, theZone.method, theZone) \\\
    \\\
        -- decrease count\\\
        if theZone.pulses > 0 then\\\
            -- only do this if ending\\\
            theZone.pulsesLeft = theZone.pulsesLeft - 1\\\
            \\\
            -- see if we are done \\\
            if theZone.pulsesLeft < 1 then \\\
                -- increment done flag if set \\\
                if theZone.pulseDoneFlag then \\\
                    --local currVal = cfxZones.getFlagValue(theZone.pulseDoneFlag, theZone)-- trigger.misc.getUserFlag(theZone.pulseDoneFlag)\\\
                    cfxZones.pollFlag(theZone.pulseDoneFlag, \\\"inc\\\", theZone) -- trigger.action.setUserFlag(theZone.pulseDoneFlag, currVal + 1)\\\
                end\\\
                if pulseFlags.verbose then \\\
                    trigger.action.outText(\\\"***PulF: pulse <\\\" .. theZone.name .. \\\"> ended!\\\", 30)\\\
                end \\\
                theZone.pulsing = false \\\
                theZone.pulsePaused = true \\\
                return \\\
            end\\\
        end\\\
    else \\\
        if pulseFlags.verbose then \\\
            trigger.action.outText(\\\"***PulF: pulse <\\\" .. theZone.name .. \\\"> delaying zero pulse!\\\", 30)\\\
        end\\\
    end\\\
    \\\
    theZone.hasPulsed = true -- we are past initial pulse\\\
    \\\
    -- if we get here, schedule next pulse\\\
    local delay = cfxZones.randomDelayFromPositiveRange(theZone.minTime, theZone.time)\\\
    \\\
    \\\
    -- schedule in delay time \\\
    theZone.timerID = timer.scheduleFunction(pulseFlags.doPulse, args, timer.getTime() + delay)\\\
    if pulseFlags.verbose then \\\
        trigger.action.outText(\\\"+++PulF: pulse <\\\" .. theZone.name .. \\\"> rescheduled in \\\" .. delay, 30)\\\
    end \\\
end\\\
 \\\
\\\
-- start new pulse, will reset \\\
function pulseFlags.startNewPulse(theZone)\\\
    theZone.pulsesLeft = theZone.pulses\\\
    local args = {theZone}\\\
    theZone.pulsing = true \\\
    if pulseFlags.verbose then \\\
        trigger.action.outText(\\\"+++PulF: starting pulse <\\\" .. theZone.name .. \\\">\\\", 30)\\\
    end \\\
    pulseFlags.doPulse(args) \\\
end\\\
\\\
function pulseFlags.update()\\\
    -- call me in a second to poll triggers\\\
    timer.scheduleFunction(pulseFlags.update, {}, timer.getTime() + 1)\\\
    \\\
    for idx, aZone in pairs(pulseFlags.pulses) do\\\
        -- see if pulse is running \\\
        if aZone.pulsing then \\\
            -- this zone has a pulse and has scheduled \\\
            -- a new pulse, nothing to do\\\
        \\\
        else \\\
            -- this zone has not scheduled a new pulse \\\
            -- let's see why \\\
            if aZone.pulsePaused then \\\
                -- ok, zone is paused. all clear \\\
            else \\\
                -- zone isn't paused. we need to start the zone \\\
                pulseFlags.startNewPulse(aZone)\\\
            end\\\
        end\\\
        \\\
        -- see if we got a pause or activate command\\\
        if aZone.activatePulseFlag then \\\
            local currTriggerVal = cfxZones.getFlagValue(aZone.activatePulseFlag, aZone) -- trigger.misc.getUserFlag(aZone.activatePulseFlag)\\\
            if currTriggerVal ~= aZone.lastActivateValue\\\
            then \\\
                if pulseFlags.verbose then \\\
                    trigger.action.outText(\\\"+++PulF: activating <\\\" .. aZone.name .. \\\">\\\", 30)\\\
                end \\\
                aZone.lastActivateValue = currTriggerVal\\\
                aZone.pulsePaused = false -- will start anew \\\
                \\\
            end\\\
        end\\\
        \\\
        if aZone.pausePulseFlag then \\\
            local currTriggerVal = cfxZones.getFlagValue(aZone.pausePulseFlag, aZone)-- trigger.misc.getUserFlag(aZone.pausePulseFlag)\\\
            if currTriggerVal ~= aZone.lastPauseValue\\\
            then \\\
                if pulseFlags.verbose then \\\
                    trigger.action.outText(\\\"+++PulF: pausing <\\\" .. aZone.name .. \\\">\\\", 30)\\\
                end \\\
                aZone.lastPauseValue = currTriggerVal\\\
                aZone.pulsePaused = true  -- prevents new start \\\
                if aZone.timerID then \\\
                     timer.removeFunction(aZone.timerID)\\\
                     aZone.timerID = nil \\\
                end \\\
            end\\\
        end\\\
    end\\\
end\\\
\\\
--\\\
-- start module and read config \\\
--\\\
function pulseFlags.readConfigZone()\\\
    -- note: must match exactly!!!!\\\
    local theZone = cfxZones.getZoneByName(\\\"pulseFlagsConfig\\\") \\\
    if not theZone then \\\
        if pulseFlags.verbose then \\\
            trigger.action.outText(\\\"+++PulF: NO config zone!\\\", 30)\\\
        end \\\
        return \\\
    end \\\
    \\\
    pulseFlags.verbose = cfxZones.getBoolFromZoneProperty(theZone, \\\"verbose\\\", false)\\\
    \\\
    if pulseFlags.verbose then \\\
        trigger.action.outText(\\\"+++PulF: read config\\\", 30)\\\
    end \\\
end\\\
\\\
function pulseFlags.start()\\\
    -- lib check\\\
    if not dcsCommon.libCheck then \\\
        trigger.action.outText(\\\"PulseFlags requires dcsCommon\\\", 30)\\\
        return false \\\
    end \\\
    if not dcsCommon.libCheck(\\\"cfx Pulse Flags\\\", \\\
        pulseFlags.requiredLibs) then\\\
        return false \\\
    end\\\
    \\\
    -- read config \\\
    pulseFlags.readConfigZone()\\\
    \\\
    -- process RND Zones \\\
    local attrZones = cfxZones.getZonesWithAttributeNamed(\\\"pulse\\\")\\\
    \\\
    -- now create a pulse gen for each one and add them\\\
    -- to our watchlist \\\
    for k, aZone in pairs(attrZones) do \\\
        pulseFlags.createPulseWithZone(aZone) -- process attribute and add to zone\\\
        pulseFlags.addPulse(aZone) -- remember it so we can pulse it\\\
    end\\\
    \\\
    local attrZones = cfxZones.getZonesWithAttributeNamed(\\\"pulse!\\\")\\\
    \\\
    -- now create a pulse gen for each one and add them\\\
    -- to our watchlist \\\
    for k, aZone in pairs(attrZones) do \\\
        pulseFlags.createPulseWithZone(aZone) -- process attribute and add to zone\\\
        pulseFlags.addPulse(aZone) -- remember it so we can pulse it\\\
    end\\\
    \\\
    -- start update in 1 second \\\
    --pulseFlags.update()\\\
    timer.scheduleFunction(pulseFlags.update, {}, timer.getTime() + 1)\\\
    \\\
    trigger.action.outText(\\\"cfx Pulse Flags v\\\" .. pulseFlags.version .. \\\" started.\\\", 30)\\\
    return true \\\
end\\\
\\\
-- let's go!\\\
if not pulseFlags.start() then \\\
    trigger.action.outText(\\\"cf/x Pulse Flags aborted: missing libraries\\\", 30)\\\
    pulseFlags = nil \\\
end\");a_do_script(\"rndFlags = {}\\\
rndFlags.version = \\\"1.1.0\\\"\\\
rndFlags.verbose = false \\\
rndFlags.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- always\\\
    \\\"cfxZones\\\", -- Zones, of course \\\
}\\\
--[[\\\
    Random Flags: DML module to select flags at random\\\
    and then change them\\\
    \\\
    Copyright 2022 by Christian Franz and cf/x \\\
    \\\
    Version History\\\
    1.0.0 - Initial Version \\\
    1.1.0 - DML flag conversion:\\\
                flagArrayFromString: strings OK, trim \\\
                remove pollFlag\\\
                pollFlag from cfxZones, include zone \\\
                randomBetween for pollSize\\\
                pollFlag to bang done with inc\\\
                getFlagValue in update \\\
                some code clean-up\\\
                rndMethod synonym \\\
--]]\\\
rndFlags.rndGen = {}\\\
\\\
function rndFlags.addRNDZone(aZone)\\\
    table.insert(rndFlags.rndGen, aZone)\\\
end\\\
\\\
function rndFlags.flagArrayFromString(inString)\\\
    if string.len(inString) < 1 then \\\
        trigger.action.outText(\\\"+++RND: empty flags\\\", 30)\\\
        return {} \\\
    end\\\
    if rndFlags.verbose then \\\
        trigger.action.outText(\\\"+++RND: processing <\\\" .. inString .. \\\">\\\", 30)\\\
    end \\\
    \\\
    local flags = {}\\\
    local rawElements = dcsCommon.splitString(inString, \\\",\\\")\\\
    -- go over all elements \\\
    for idx, anElement in pairs(rawElements) do \\\
        if dcsCommon.stringStartsWithDigit(anElement) and  dcsCommon.containsString(anElement, \\\"-\\\") then \\\
            -- interpret this as a range\\\
            local theRange = dcsCommon.splitString(anElement, \\\"-\\\")\\\
            local lowerBound = theRange[1]\\\
            lowerBound = tonumber(lowerBound)\\\
            local upperBound = theRange[2]\\\
            upperBound = tonumber(upperBound)\\\
            if lowerBound and upperBound then\\\
                -- swap if wrong order\\\
                if lowerBound > upperBound then \\\
                    local temp = upperBound\\\
                    upperBound = lowerBound\\\
                    lowerBound = temp \\\
                end\\\
                -- now add add numbers to flags\\\
                for f=lowerBound, upperBound do \\\
                    table.insert(flags, f)\\\
\\\
                end\\\
            else\\\
                -- bounds illegal\\\
                trigger.action.outText(\\\"+++RND: ignored range <\\\" .. anElement .. \\\"> (range)\\\", 30)\\\
            end\\\
        else\\\
            -- single number\\\
            f = dcsCommon.trim(anElement) -- DML flag upgrade: accept strings tonumber(anElement)\\\
            if f then \\\
                table.insert(flags, f)\\\
\\\
            else \\\
                trigger.action.outText(\\\"+++RND: ignored element <\\\" .. anElement .. \\\"> (single)\\\", 30)\\\
            end\\\
        end\\\
    end\\\
    if rndFlags.verbose then \\\
        trigger.action.outText(\\\"+++RND: <\\\" .. #flags .. \\\"> flags total\\\", 30)\\\
    end \\\
    return flags\\\
end\\\
\\\
--\\\
-- create rnd gen from zone \\\
--\\\
function rndFlags.createRNDWithZone(theZone)\\\
    local flags = cfxZones.getStringFromZoneProperty(theZone, \\\"flags!\\\", \\\"\\\")\\\
    if flags == \\\"\\\" then \\\
        -- let's try alternate spelling without \\\"!\\\"\\\
        flags = cfxZones.getStringFromZoneProperty(theZone, \\\"flags\\\", \\\"\\\") \\\
    end \\\
    -- now build the flag array from strings\\\
    local theFlags = rndFlags.flagArrayFromString(flags)\\\
    theZone.myFlags = theFlags\\\
\\\
\\\
    theZone.pollSizeMin, theZone.pollSize = cfxZones.getPositiveRangeFromZoneProperty(theZone, \\\"pollSize\\\", 1)\\\
    if rndFlags.verbose then \\\
        trigger.action.outText(\\\"+++RND: pollSize is <\\\" .. theZone.pollSizeMin .. \\\", \\\" .. theZone.pollSize .. \\\">\\\", 30)\\\
    end\\\
             \\\
    \\\
    theZone.remove = cfxZones.getBoolFromZoneProperty(theZone, \\\"remove\\\", false)\\\
\\\
    -- trigger flag \\\
    if cfxZones.hasProperty(theZone, \\\"f?\\\") then \\\
        theZone.triggerFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"f?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"in?\\\") then \\\
        theZone.triggerFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"in?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"rndPoll?\\\") then \\\
        theZone.triggerFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"rndPoll?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if theZone.triggerFlag then \\\
        theZone.lastTriggerValue = cfxZones.getFlagValue(theZone.triggerFlag, theZone) --trigger.misc.getUserFlag(theZone.triggerFlag) -- save last value\\\
    end\\\
    \\\
    theZone.onStart = cfxZones.getBoolFromZoneProperty(theZone, \\\"onStart\\\", false)\\\
    \\\
    if not theZone.onStart and not theZone.triggerFlag then \\\
        theZone.onStart = true \\\
    end\\\
    \\\
    theZone.rndMethod = cfxZones.getStringFromZoneProperty(theZone, \\\"method\\\", \\\"on\\\")\\\
    if cfxZones.hasProperty(theZone, \\\"rndMethod\\\") then \\\
        theZone.rndMethod = cfxZones.getStringFromZoneProperty(theZone, \\\"rndMethod\\\", \\\"on\\\")\\\
    end\\\
    \\\
    theZone.reshuffle = cfxZones.getBoolFromZoneProperty(theZone, \\\"reshuffle\\\", false)\\\
    if theZone.reshuffle then \\\
        -- create a backup copy we can reshuffle from \\\
        theZone.flagStore = dcsCommon.copyArray(theFlags)\\\
    end\\\
    \\\
    -- done flag \\\
    if cfxZones.hasProperty(theZone, \\\"done+1\\\") then \\\
        theZone.doneFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"done+1\\\", \\\"none\\\")\\\
    end\\\
end\\\
\\\
function rndFlags.reshuffle(theZone)\\\
    if rndFlags.verbose then \\\
        trigger.action.outText(\\\"+++RND: reshuffling zone \\\" .. theZone.name, 30)\\\
    end\\\
    theZone.myFlags = dcsCommon.copyArray(theZone.flagStore)\\\
end\\\
\\\
--\\\
-- fire RND\\\
-- \\\
\\\
function rndFlags.fire(theZone) \\\
    -- fire this rnd \\\
    -- create a local copy of all flags \\\
    if theZone.reshuffle and #theZone.myFlags < 1 then \\\
        rndFlags.reshuffle(theZone)\\\
    end\\\
    \\\
    local availableFlags = dcsCommon.copyArray(theZone.myFlags) \\\
    \\\
    -- do this pollSize times \\\
    local pollSize = dcsCommon.randomBetween(theZone.pollSizeMin, theZone.pollSize)\\\
\\\
    \\\
    if #availableFlags < 1 then \\\
        if rndFlags.verbose then \\\
            trigger.action.outText(\\\"+++RND: RND \\\" .. theZone.name .. \\\" ran out of flags. aborting fire\\\", 30)\\\
        end\\\
        \\\
        if theZone.doneFlag then\\\
            cfxZones.pollFlag(theZone.doneFlag, \\\"inc\\\", theZone)\\\
        end\\\
        \\\
        return \\\
    end\\\
    \\\
    if rndFlags.verbose then \\\
        trigger.action.outText(\\\"+++RND: firing RND \\\" .. theZone.name .. \\\" with pollsize \\\" .. pollSize .. \\\" on \\\" .. #availableFlags .. \\\" set size\\\", 30)\\\
    end\\\
    \\\
    for i=1, pollSize do \\\
        -- check there are still flags left \\\
        if #availableFlags < 1 then \\\
            trigger.action.outText(\\\"+++RND: no flags left in \\\" .. theZone.name .. \\\" in index \\\" .. i, 30)\\\
            theZone.myFlags = {} \\\
            if theZone.reshuffle then \\\
                rndFlags.reshuffle(theZone)\\\
            end\\\
            return \\\
        end\\\
        \\\
        -- select a flag, enforce uniqueness\\\
        local theFlagIndex = dcsCommon.smallRandom(#availableFlags)\\\
        \\\
        -- poll this flag and remove from available\\\
        local theFlag = table.remove(availableFlags,theFlagIndex)\\\
        \\\
        --rndFlags.pollFlag(theFlag, theZone.rndMethod)\\\
        if rndFlags.verbose then \\\
            trigger.action.outText(\\\"+++RND: polling \\\" .. theFlag .. \\\" with \\\" .. theZone.rndMethod, 30)\\\
        end\\\
        \\\
        cfxZones.pollFlag(theFlag, theZone.rndMethod, theZone) \\\
    end\\\
    \\\
    -- remove if requested\\\
    if theZone.remove then \\\
        theZone.myFlags = availableFlags\\\
    end\\\
end\\\
\\\
--\\\
-- update \\\
--\\\
function rndFlags.update()\\\
    -- call me in a second to poll triggers\\\
    timer.scheduleFunction(rndFlags.update, {}, timer.getTime() + 1)\\\
    \\\
    for idx, aZone in pairs(rndFlags.rndGen) do\\\
        if aZone.triggerFlag then \\\
            local currTriggerVal = cfxZones.getFlagValue(aZone.triggerFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerFlag)\\\
            if currTriggerVal ~= aZone.lastTriggerValue\\\
            then \\\
                if rndFlags.verbose then \\\
                    trigger.action.outText(\\\"+++RND: triggering \\\" .. aZone.name, 30)\\\
                end \\\
                rndFlags.fire(aZone)\\\
                aZone.lastTriggerValue = currTriggerVal\\\
            end\\\
\\\
        end\\\
    end\\\
end\\\
\\\
--\\\
-- start cycle: force all onStart to fire \\\
--\\\
function rndFlags.startCycle()\\\
    for idx, theZone in pairs(rndFlags.rndGen) do\\\
        if theZone.onStart then \\\
            if rndFlags.verbose then \\\
                trigger.action.outText(\\\"+++RND: starting \\\" .. theZone.name, 30)\\\
            end \\\
            rndFlags.fire(theZone)\\\
        end\\\
    end\\\
end\\\
\\\
\\\
--\\\
-- start module and read config \\\
--\\\
function rndFlags.readConfigZone()\\\
    -- note: must match exactly!!!!\\\
    local theZone = cfxZones.getZoneByName(\\\"rndFlagsConfig\\\") \\\
    if not theZone then \\\
        if rndFlags.verbose then \\\
            trigger.action.outText(\\\"***RND: NO config zone!\\\", 30)\\\
        end \\\
        return \\\
    end \\\
    \\\
    rndFlags.verbose = cfxZones.getBoolFromZoneProperty(theZone, \\\"verbose\\\", false)\\\
    \\\
    if rndFlags.verbose then \\\
        trigger.action.outText(\\\"***RND: read config\\\", 30)\\\
    end \\\
end\\\
\\\
function rndFlags.start()\\\
    -- lib check\\\
    if not dcsCommon.libCheck then \\\
        trigger.action.outText(\\\"RNDFlags requires dcsCommon\\\", 30)\\\
        return false \\\
    end \\\
    if not dcsCommon.libCheck(\\\"cfx Random Flags\\\", \\\
        rndFlags.requiredLibs) then\\\
        return false \\\
    end\\\
    \\\
    -- read config \\\
    rndFlags.readConfigZone()\\\
    \\\
    -- process RND Zones \\\
    local attrZones = cfxZones.getZonesWithAttributeNamed(\\\"RND\\\")\\\
    \\\
    -- now create an rnd gen for each one and add them\\\
    -- to our watchlist \\\
    for k, aZone in pairs(attrZones) do \\\
        rndFlags.createRNDWithZone(aZone) -- process attribute and add to zone\\\
        rndFlags.addRNDZone(aZone) -- remember it so we can smoke it\\\
    end\\\
    \\\
    -- start cycle \\\
    timer.scheduleFunction(rndFlags.startCycle, {}, timer.getTime() + 0.25)\\\
    \\\
    -- start update \\\
    timer.scheduleFunction(rndFlags.update, {}, timer.getTime() + 1)\\\
    \\\
    trigger.action.outText(\\\"cfx random Flags v\\\" .. rndFlags.version .. \\\" started.\\\", 30)\\\
    return true \\\
end\\\
\\\
-- let's go!\\\
if not rndFlags.start() then \\\
    trigger.action.outText(\\\"cf/x RND Flags aborted: missing libraries\\\", 30)\\\
    rndFlags = nil \\\
end\\\
\\\
-- TODO: move flags to RND!, rename RND to RND!, deprecate flags!\\\
\");a_do_script(\"delayFlag = {}\\\
delayFlag.version = \\\"1.1.0\\\"\\\
delayFlag.verbose = false  \\\
delayFlag.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- always\\\
    \\\"cfxZones\\\", -- Zones, of course \\\
}\\\
delayFlag.flags = {}\\\
\\\
--[[--\\\
    delay flags - simple flag switch & delay, allows for randomize\\\
    and dead man switching \\\
    \\\
    Copyright (c) 2022 by Christian Franz and cf/x AG\\\
    \\\
    Version History\\\
    1.0.0 - Initial Version \\\
    1.0.1 - message attribute \\\
    1.0.2 - slight spelling correction \\\
          - using cfxZones for polling \\\
          - removed pollFlag \\\
    1.0.3 - bug fix for config zone name\\\
          - removed message attribute, moved to own module \\\
          - triggerFlag --> triggerDelayFlag\\\
    1.0.4 - startDelay\\\
    1.1.0 - DML flag upgrade \\\
          - removed onStart. use local raiseFlag instead \\\
          - delayDone! synonym\\\
          - pauseDelay?\\\
          - unpauseDelay?\\\
    \\\
--]]--\\\
\\\
function delayFlag.addDelayZone(theZone)\\\
    table.insert(delayFlag.flags, theZone)\\\
end\\\
\\\
function delayFlag.getDelayZoneByName(aName) \\\
    for idx, aZone in pairs(delayFlag.flags) do \\\
        if aName == aZone.name then return aZone end \\\
    end\\\
    if delayFlag.verbose then \\\
        trigger.action.outText(\\\"+++dlyF: no delay flag with name <\\\" .. aName ..\\\">\\\", 30)\\\
    end \\\
    \\\
    return nil \\\
end\\\
\\\
--\\\
-- read attributes \\\
-- \\\
--\\\
-- create rnd gen from zone \\\
--\\\
function delayFlag.createTimerWithZone(theZone)\\\
    -- delay\\\
    theZone.delayMin, theZone.delayMax = cfxZones.getPositiveRangeFromZoneProperty(theZone, \\\"timeDelay\\\", 1) -- same as zone signature \\\
    if delayFlag.verbose then \\\
        trigger.action.outText(\\\"+++dlyF: time delay is <\\\" .. theZone.delayMin .. \\\", \\\" .. theZone.delayMax .. \\\"> seconds\\\", 30)\\\
    end\\\
    \\\
\\\
    -- trigger flag \\\
    if cfxZones.hasProperty(theZone, \\\"f?\\\") then \\\
        theZone.triggerDelayFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"f?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"in?\\\") then \\\
        theZone.triggerDelayFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"in?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"startDelay?\\\") then \\\
        theZone.triggerDelayFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"startDelay?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if theZone.triggerDelayFlag then \\\
        theZone.lastDelayTriggerValue = cfxZones.getFlagValue(theZone.triggerDelayFlag, theZone) -- trigger.misc.getUserFlag(theZone.triggerDelayFlag) -- save last value\\\
    end\\\
    \\\
    \\\
    theZone.method = cfxZones.getStringFromZoneProperty(theZone, \\\"method\\\", \\\"flip\\\")\\\
    \\\
    -- out flag \\\
    if cfxZones.hasProperty(theZone, \\\"out!\\\") then \\\
        theZone.delayDoneFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"out!\\\", -1)\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"delayDone!\\\") then \\\
        theZone.delayDoneFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"delayDone!\\\", -1)\\\
    end\\\
\\\
    -- stop the press!\\\
    if cfxZones.hasProperty(theZone, \\\"stopDelay?\\\") then \\\
        theZone.triggerStopDelay = cfxZones.getStringFromZoneProperty(theZone, \\\"stopDelay?\\\", \\\"none\\\")\\\
        theZone.lastTriggerStopValue = cfxZones.getFlagValue(theZone.triggerStopDelay, theZone)\\\
    end\\\
    \\\
    \\\
    \\\
    \\\
    -- init \\\
    theZone.delayRunning = false \\\
    theZone.timeLimit = -1 \\\
\\\
end\\\
\\\
\\\
--\\\
-- update \\\
-- \\\
\\\
function delayFlag.startDelay(theZone) \\\
    -- refresh timer \\\
    theZone.delayRunning = true\\\
    \\\
    -- set new expiry date \\\
    local delayMax = theZone.delayMax\\\
    local delayMin = theZone.delayMin\\\
    local delay = delayMax \\\
    \\\
    if delayMin ~= delayMax then \\\
        -- pick random in range , say 3-7 --> 5 s!\\\
        local delayDiff = (delayMax - delayMin) + 1 -- 7-3 + 1\\\
        delay = dcsCommon.smallRandom(delayDiff) - 1 --> 0-4\\\
        delay = delay + delayMin \\\
        if delay > theZone.delayMax then delay = theZone.delayMax end \\\
        if delay < 1 then delay = 1 end \\\
        \\\
        if delayFlag.verbose then \\\
            trigger.action.outText(\\\"+++dlyF: delay \\\" .. theZone.name .. \\\" range \\\" .. delayMin .. \\\"-\\\" .. delayMax .. \\\": selected \\\" .. delay, 30)\\\
        end\\\
    end\\\
    \\\
    theZone.timeLimit = timer.getTime() + delay \\\
end\\\
\\\
function delayFlag.update()\\\
    -- call me in a second to poll triggers\\\
    timer.scheduleFunction(delayFlag.update, {}, timer.getTime() + 1)\\\
    \\\
    local now = timer.getTime() \\\
    \\\
    for idx, aZone in pairs(delayFlag.flags) do\\\
        -- see if we need to stop \\\
        if aZone.triggerStopDelay then \\\
            local currTriggerVal = cfxZones.getFlagValue(aZone.triggerStopDelay, aZone)\\\
            if currTriggerVal ~= lastTriggerStopValue then \\\
                aZone.delayRunning = false -- simply stop.\\\
                if delayFlag.verbose then \\\
                    trigger.action.outText(\\\"+++dlyF: stopped delay \\\" .. aZone.name, 30)\\\
                end \\\
            end \\\
        end        \\\
        \\\
        -- make sure to re-start before reading time limit\\\
        if aZone.triggerDelayFlag then \\\
            local currTriggerVal = cfxZones.getFlagValue(aZone.triggerDelayFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerDelayFlag)\\\
            if currTriggerVal ~= aZone.lastDelayTriggerValue\\\
            then \\\
                if delayFlag.verbose then \\\
                    if aZone.delayRunning then \\\
                        trigger.action.outText(\\\"+++dlyF: re-starting timer \\\" .. aZone.name, 30)    \\\
                    else \\\
                        trigger.action.outText(\\\"+++dlyF: init timer for \\\" .. aZone.name, 30)\\\
                    end\\\
                end \\\
                delayFlag.startDelay(aZone) -- we restart even if running \\\
                aZone.lastDelayTriggerValue = currTriggerVal\\\
            end\\\
        end\\\
        \\\
        if aZone.delayRunning then \\\
            -- check expiry \\\
            if now > aZone.timeLimit then \\\
                -- end timer \\\
                aZone.delayRunning = false \\\
                -- poll flag \\\
                cfxZones.pollFlag(aZone.delayDoneFlag, aZone.method, aZone)\\\
                if delayFlag.verbose then \\\
                    trigger.action.outText(\\\"+++dlyF: banging on \\\" .. aZone.delayDoneFlag, 30)\\\
                end \\\
            end\\\
        end\\\
        \\\
    end\\\
end\\\
\\\
--\\\
-- START \\\
--\\\
function delayFlag.readConfigZone()\\\
    local theZone = cfxZones.getZoneByName(\\\"delayFlagsConfig\\\") \\\
    if not theZone then \\\
        if delayFlag.verbose then \\\
            trigger.action.outText(\\\"+++dlyF: NO config zone!\\\", 30)\\\
        end \\\
        return \\\
    end \\\
    \\\
    delayFlag.verbose = cfxZones.getBoolFromZoneProperty(theZone, \\\"verbose\\\", false)\\\
    \\\
    if delayFlag.verbose then \\\
        trigger.action.outText(\\\"+++dlyF: read config\\\", 30)\\\
    end \\\
end\\\
\\\
--[[--\\\
function delayFlag.onStart()\\\
    for idx, theZone in pairs(delayFlag.flags) do \\\
        if theZone.onStart then \\\
            if delayFlag.verbose then \\\
                trigger.action.outText(\\\"+++dlyF: onStart for <\\\"..theZone.name .. \\\">\\\", 30)\\\
            end\\\
            delayFlag.startDelay(theZone) \\\
        end \\\
    end\\\
end\\\
--]]--\\\
\\\
function delayFlag.start()\\\
    -- lib check\\\
    if not dcsCommon.libCheck then \\\
        trigger.action.outText(\\\"cfx Delay Flags requires dcsCommon\\\", 30)\\\
        return false \\\
    end \\\
    if not dcsCommon.libCheck(\\\"cfx Delay Flags\\\", \\\
        delayFlag.requiredLibs) then\\\
        return false \\\
    end\\\
    \\\
    -- read config \\\
    delayFlag.readConfigZone()\\\
    \\\
    -- process cloner Zones \\\
    local attrZones = cfxZones.getZonesWithAttributeNamed(\\\"timeDelay\\\")\\\
    for k, aZone in pairs(attrZones) do \\\
        delayFlag.createTimerWithZone(aZone) -- process attributes\\\
        delayFlag.addDelayZone(aZone) -- add to list\\\
    end\\\
    \\\
    -- kick onStart\\\
    --delayFlag.onStart()\\\
    \\\
    -- start update \\\
    delayFlag.update()\\\
    \\\
    trigger.action.outText(\\\"cfx Delay Flag v\\\" .. delayFlag.version .. \\\" started.\\\", 30)\\\
    return true \\\
end\\\
\\\
-- let's go!\\\
if not delayFlag.start() then \\\
    trigger.action.outText(\\\"cfx Delay Flag aborted: missing libraries\\\", 30)\\\
    delayFlag = nil \\\
end\");a_do_script(\"cloneZones = {}\\\
cloneZones.version = \\\"1.3.0\\\"\\\
cloneZones.verbose = false  \\\
cloneZones.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- always\\\
    \\\"cfxZones\\\", -- Zones, of course \\\
    \\\"cfxMX\\\", \\\
}\\\
cloneZones.cloners = {}\\\
cloneZones.callbacks = {}\\\
cloneZones.unitXlate = {}\\\
cloneZones.groupXlate = {} -- used to translate original groupID to cloned. only holds last spawned group id \\\
cloneZones.uniqueCounter = 9200000 -- we start group numbering here \\\
--[[--\\\
    Clones Groups from ME mission data\\\
    Copyright (c) 2022 by Christian Franz and cf/x AG\\\
    \\\
    Version History\\\
    1.0.0 - initial version \\\
    1.0.1 - preWipe attribute\\\
    1.1.0 - support for static objects\\\
          - despawn? attribute \\\
    1.1.1 - despawnAll: isExist guard \\\
          - map in? to f? \\\
    1.2.0 - Lua API integration: callbacks \\\
          - groupXlate struct\\\
          - unitXlate struct \\\
          - resolveReferences \\\
          - getGroupsInZone rewritten for data \\\
          - static resolve \\\
          - linkUnit resolve \\\
          - clone? synonym\\\
          - empty! and method attributes\\\
    1.3.0 - DML flag upgrade \\\
    \\\
--]]--\\\
\\\
--\\\
-- adding / removing from list \\\
--\\\
function cloneZones.addCloneZone(theZone)\\\
    table.insert(cloneZones.cloners, theZone)\\\
end\\\
\\\
function cloneZones.getCloneZoneByName(aName) \\\
    for idx, aZone in pairs(cloneZones.cloners) do \\\
        if aName == aZone.name then return aZone end \\\
    end\\\
    if cloneZones.verbose then \\\
        trigger.action.outText(\\\"+++clnZ: no clone with name <\\\" .. aName ..\\\">\\\", 30)\\\
    end \\\
    \\\
    return nil \\\
end\\\
\\\
--\\\
-- callbacks \\\
--\\\
\\\
function cloneZones.addCallback(theCallback)\\\
    if not theCallback then return end \\\
    table.insert(cloneZones.callbacks, theCallback)\\\
end\\\
\\\
-- reasons for callback \\\
-- \\\"will despawn group\\\" - args is the group about to be despawned\\\
-- \\\"did spawn group\\\" -- args is group that was spawned\\\
-- \\\"will despawn static\\\"\\\
-- \\\"did spawn static\\\"\\\
-- \\\"spawned\\\" -- completed spawn cycle. args contains .groups and .statics spawned \\\
-- \\\"empty\\\" -- all spawns have been killed, args is empty \\\
-- \\\"wiped\\\" -- preWipe executed \\\
-- \\\"<none\\\" -- something went wrong \\\
\\\
function cloneZones.invokeCallbacks(theZone, reason, args)\\\
    if not theZone then return end \\\
    if not reason then reason = \\\"<none>\\\" end \\\
    if not args then args = {} end \\\
    \\\
    -- invoke anyone who wants to know that a group \\\
    -- of people was rescued.\\\
    for idx, cb in pairs(cloneZones.callbacks) do \\\
        cb(theZone, reason, args)\\\
    end\\\
end\\\
\\\
-- group translation orig id \\\
\\\
--\\\
-- reading zones\\\
--\\\
function cloneZones.partOfGroupDataInZone(theZone, theUnits)\\\
    local zP = cfxZones.getPoint(theZone)\\\
    zP.y = 0\\\
    \\\
    for idx, aUnit in pairs(theUnits) do \\\
        local uP = {}\\\
        uP.x = aUnit.x \\\
        uP.y = 0\\\
        uP.z = aUnit.y -- !! y-z\\\
        local dist = dcsCommon.dist(uP, zP)\\\
        if dist <= theZone.radius then return true  end \\\
    end \\\
    return false \\\
end\\\
\\\
function cloneZones.allGroupsInZoneByData(theZone) \\\
    local theGroupsInZone = {}\\\
    local radius = theZone.radius \\\
    for groupName, groupData in pairs(cfxMX.groupDataByName) do \\\
        if groupData.units then \\\
            if cloneZones.partOfGroupDataInZone(theZone, groupData.units) then \\\
                theGroup = Group.getByName(groupName)\\\
                table.insert(theGroupsInZone, theGroup)\\\
            end\\\
        end\\\
    end\\\
    return theGroupsInZone\\\
end\\\
\\\
function cloneZones.createClonerWithZone(theZone) -- has \\\"Cloner\\\"\\\
    if cloneZones.verbose then \\\
        trigger.action.outText(\\\"+++clnZ: new cloner \\\" .. theZone.name, 30)\\\
    end\\\
\\\
    local localZones = cloneZones.allGroupsInZoneByData(theZone)  \\\
    local localObjects = cfxZones.allStaticsInZone(theZone)\\\
    theZone.cloner = true -- this is a cloner zoner \\\
    theZone.mySpawns = {}\\\
    theZone.myStatics = {}\\\
    theZone.origin = cfxZones.getPoint(theZone) -- save reference point for all groupVectors \\\
    \\\
    -- source tells us which template to use. it can be the following:\\\
    -- nothing (no attribute) - then we use whatever groups are in zone to \\\
    -- spawn as template \\\
    -- name of another spawner that provides the template \\\
    -- we can't simply use a group name as we lack the reference \\\
    -- location for delta \\\
    if cfxZones.hasProperty(theZone, \\\"source\\\") then \\\
        theZone.source = cfxZones.getStringFromZoneProperty(theZone, \\\"source\\\", \\\"<none>\\\")\\\
        if theZone.source == \\\"<none>\\\" then theZone.source = nil end \\\
    end \\\
    \\\
    if not theZone.source then \\\
        theZone.cloneNames = {} -- names of the groups. only present in template spawners\\\
        theZone.staticNames = {} -- names of all statics. only present in templates\\\
        \\\
        for idx, aGroup in pairs(localZones) do\\\
            local gName = aGroup:getName()\\\
            if gName then \\\
                table.insert(theZone.cloneNames, gName)\\\
                table.insert(theZone.mySpawns, aGroup) -- collect them for initial despawn\\\
                -- now get group data and save a lookup for \\\
                -- resolving internal references \\\
                local rawData, cat, ctry = cfxMX.getGroupFromDCSbyName(gName)\\\
                local origID = rawData.groupId\\\
--                cloneZones.templateGroups[gName] = origID \\\
--                cloneZones.templateGroupsReverse[origID] = gName\\\
            end     \\\
        end\\\
        \\\
        for idx, aStatic in pairs (localObjects) do \\\
            local sName = aStatic:getName()\\\
            if sName then \\\
                table.insert(theZone.staticNames, sName)\\\
                table.insert(theZone.myStatics, aStatic)\\\
            end\\\
        end\\\
        \\\
        cloneZones.despawnAll(theZone) \\\
        if (#theZone.cloneNames + #theZone.staticNames)    < 1 then \\\
            if cloneZones.verbose then \\\
                trigger.action.outText(\\\"+++clnZ: WARNING - Template in clone zone <\\\" .. theZone.name .. \\\"> is empty\\\", 30)\\\
            end \\\
            theZone.cloneNames = nil\\\
            theZone.staticNames = nil \\\
        end\\\
        if cloneZones.verbose then \\\
            trigger.action.outText(theZone.name .. \\\" clone template saved\\\", 30)\\\
        end\\\
    end\\\
    \\\
    -- f? and spawn? and other synonyms map to the same \\\
    if cfxZones.hasProperty(theZone, \\\"f?\\\") then \\\
        theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"f?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"in?\\\") then \\\
        theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"in?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"spawn?\\\") then \\\
        theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"spawn?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"clone?\\\") then \\\
        theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"clone?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if theZone.spawnFlag then \\\
        theZone.lastSpawnValue = cfxZones.getFlagValue(theZone.spawnFlag, theZone)\\\
    end\\\
    \\\
    -- deSpawn?\\\
    if cfxZones.hasProperty(theZone, \\\"deSpawn?\\\") then \\\
        theZone.deSpawnFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"deSpawn?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"deClone?\\\") then \\\
        theZone.deSpawnFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"deClone?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if theZone.deSpawnFlag then \\\
        theZone.lastDeSpawnValue = cfxZones.getFlagValue(theZone.deSpawnFlag, theZone)\\\
    end\\\
    \\\
    -- to be deprecated\\\
    theZone.onStart = cfxZones.getBoolFromZoneProperty(theZone, \\\"onStart\\\", false)\\\
    \\\
    theZone.moveRoute = cfxZones.getBoolFromZoneProperty(theZone, \\\"moveRoute\\\", false)\\\
    \\\
    theZone.preWipe = cfxZones.getBoolFromZoneProperty(theZone, \\\"preWipe\\\", false)\\\
    \\\
    -- to be deprecated\\\
    if cfxZones.hasProperty(theZone, \\\"empty+1\\\") then \\\
        theZone.emptyFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"empty+1\\\", \\\"<None>\\\") -- note string on number default\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"empty!\\\") then \\\
        theZone.emptyBangFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"empty!\\\", \\\"<None>\\\") -- note string on number default\\\
    end\\\
    \\\
    theZone.method = cfxZones.getStringFromZoneProperty(theZone, \\\"method\\\", \\\"inc\\\")\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"masterOwner\\\") then \\\
        theZone.masterOwner = cfxZones.getStringFromZoneProperty(theZone, \\\"masterOwner\\\", \\\"<none>\\\")\\\
    end\\\
    \\\
    theZone.turn = cfxZones.getNumberFromZoneProperty(theZone, \\\"turn\\\", 0)\\\
    \\\
    -- we end with clear plate \\\
end\\\
\\\
-- \\\
-- spawning, despawning\\\
--\\\
\\\
function cloneZones.despawnAll(theZone) \\\
    if cloneZones.verbose then \\\
        trigger.action.outText(\\\"wiping <\\\" .. theZone.name .. \\\">\\\", 30)\\\
    end \\\
    for idx, aGroup in pairs(theZone.mySpawns) do \\\
        --trigger.action.outText(\\\"++clnZ: despawn all \\\" .. aGroup.name, 30)\\\
        \\\
        if aGroup:isExist() then \\\
            cloneZones.invokeCallbacks(theZone, \\\"will despawn group\\\", aGroup)\\\
            Group.destroy(aGroup)\\\
        end \\\
    end\\\
    for idx, aStatic in pairs(theZone.myStatics) do \\\
        -- warning! may be mismatch because we are looking at groups\\\
        -- not objects. let's see\\\
        if aStatic:isExist() then \\\
            if cloneZones.verbose then \\\
                trigger.action.outText(\\\"Destroying static <\\\" .. aStatic:getName() .. \\\">\\\", 30)\\\
            end \\\
            cloneZones.invokeCallbacks(theZone, \\\"will despawn static\\\", aStatic)\\\
            Object.destroy(aStatic) -- we don't aStatio:destroy() to find out what it is\\\
        end \\\
    end\\\
    theZone.mySpawns = {}\\\
    theZone.myStatics = {}\\\
end\\\
\\\
function cloneZones.updateLocationsInGroupData(theData, zoneDelta, adjustAllWaypoints)\\\
    \\\
    -- remember that zoneDelta's [z] modifies theData's y!!\\\
    theData.x = theData.x + zoneDelta.x \\\
    theData.y = theData.y + zoneDelta.z -- !!!\\\
    local units = theData.units \\\
    for idx, aUnit in pairs(units) do \\\
        aUnit.x = aUnit.x + zoneDelta.x \\\
        aUnit.y = aUnit.y + zoneDelta.z -- again!!!!\\\
    end\\\
    -- now modifiy waypoints. we ALWAYS adjust the  \\\
    -- first waypoint, but only all others if asked \\\
    -- to \\\
    local theRoute = theData.route \\\
    if theRoute then \\\
        local thePoints = theRoute.points \\\
        if thePoints and #thePoints > 0 then \\\
            if adjustAllWaypoints then  \\\
                for i=1, #thePoints do \\\
                    thePoints[i].x = thePoints[i].x + zoneDelta.x \\\
                    thePoints[i].y = thePoints[i].y + zoneDelta.z -- (!!)\\\
\\\
                end\\\
            else \\\
                -- only first point \\\
                thePoints[1].x = thePoints[1].x + zoneDelta.x \\\
                thePoints[1].y = thePoints[1].y + zoneDelta.z -- (!!)\\\
            end \\\
            \\\
            -- if there is an airodrome id given in first waypoint, \\\
            -- adjust for closest location \\\
            local firstPoint = thePoints[1]\\\
            if firstPoint.airdromeId then \\\
                trigger.action.outText(\\\"first: airdrome adjust for \\\" .. theData.name .. \\\" now is \\\" .. firstPoint.airdromeId, 30)\\\
                local loc = {}\\\
                loc.x = firstPoint.x\\\
                loc.y = 0\\\
                loc.z = firstPoint.y \\\
                local bestAirbase = dcsCommon.getClosestAirbaseTo(loc)\\\
                firstPoint.airdromeId = bestAirbase:getID()\\\
                trigger.action.outText(\\\"first: adjusted to \\\" .. firstPoint.airdromeId, 30)\\\
            end\\\
            \\\
            -- adjust last point (landing)\\\
            if #thePoints > 1 then \\\
                local lastPoint = thePoints[#thePoints]\\\
                if firstPoint.airdromeId then \\\
                    trigger.action.outText(\\\"last: airdrome adjust for \\\" .. theData.name .. \\\" now is \\\" .. lastPoint.airdromeId, 30)\\\
                    local loc = {}\\\
                    loc.x = lastPoint.x\\\
                    loc.y = 0\\\
                    loc.z = lastPoint.y \\\
                    local bestAirbase = dcsCommon.getClosestAirbaseTo(loc)\\\
                    lastPoint.airdromeId = bestAirbase:getID()\\\
                    trigger.action.outText(\\\"last: adjusted to \\\" .. lastPoint.airdromeId, 30)\\\
                end\\\
            \\\
            end\\\
        end\\\
    end\\\
end\\\
function cloneZones.uniqueID()\\\
    local uid = cloneZones.uniqueCounter\\\
    cloneZones.uniqueCounter = cloneZones.uniqueCounter + 1\\\
    return uid \\\
end\\\
\\\
function cloneZones.uniqueNameGroupData(theData)  \\\
    theData.name = dcsCommon.uuid(theData.name)\\\
    local units = theData.units \\\
    for idx, aUnit in pairs(units) do \\\
        aUnit.name = dcsCommon.uuid(aUnit.name)\\\
    end \\\
end \\\
\\\
function cloneZones.uniqueIDGroupData(theData)\\\
    theData.groupId = cloneZones.uniqueID()\\\
end\\\
\\\
function cloneZones.uniqueIDUnitData(theData)\\\
    if not theData then return end \\\
    if not theData.units then return end \\\
    local units = theData.units \\\
    for idx, aUnit in pairs(units) do \\\
        aUnit.CZorigID = aUnit.unitId \\\
        aUnit.unitId = cloneZones.uniqueID()\\\
        aUnit.CZTargetID = aUnit.unitId\\\
    end \\\
\\\
end\\\
\\\
function cloneZones.resolveOwnership(spawnZone, ctry)\\\
    if not spawnZone.masterOwner then return ctry end \\\
\\\
    local masterZone = cfxZones.getZoneByName(spawnZone.masterOwner)\\\
    if not masterZone then \\\
        trigger.action.outText(\\\"+++clnZ: cloner \\\" .. spawnZone.name .. \\\" could not fine master owner <\\\" .. spawnZone.masterOwner .. \\\">\\\", 30)\\\
        return ctry \\\
    end\\\
    \\\
    if not masterZone.owner then \\\
        return ctry \\\
    end\\\
    \\\
    ctry = dcsCommon.getACountryForCoalition(masterZone.owner)\\\
    return ctry \\\
end\\\
\\\
--\\\
-- resolve external group references \\\
-- \\\
\\\
function cloneZones.resolveGroupID(gID, rawData, dataTable, reason)\\\
    local resolvedID = gID\\\
    local myOName = rawData.CZorigName\\\
    local groupName = cfxMX.groupNamesByID[gID]\\\
    --trigger.action.outText(\\\"Resolve for <\\\" .. myOName .. \\\"> the external ID: \\\" .. gID .. \\\" --> \\\" .. groupName .. \\\" for <\\\" .. reason.. \\\"> task\\\", 30)\\\
    \\\
    -- first, check if this an internal reference, i.e. inside the same \\\
    -- zone template \\\
    for idx, otherData in pairs(dataTable) do\\\
        -- look in own data table \\\
        if otherData.CZorigName == groupName then \\\
            -- using cfxMX for clarity only (name access)\\\
            resolvedID = otherData.CZTargetID\\\
            --trigger.action.outText(\\\"resolved (internally) \\\" .. gID .. \\\" to \\\" .. resolvedID, 30)\\\
            return resolvedID\\\
        end\\\
    end\\\
    \\\
    -- now check if we have spawned this before \\\
    local lastClone = cloneZones.groupXlate[gID]\\\
    if lastClone then \\\
        resolvedID = lastClone\\\
        --trigger.action.outText(\\\"resolved (EXT) \\\" .. gID .. \\\" to \\\" .. resolvedID, 30)\\\
        return resolvedID    \\\
    end\\\
    \\\
    -- if we get here, reference is not to a cloned item \\\
    --trigger.action.outText(\\\"resolved \\\" .. gID .. \\\" to \\\" .. resolvedID, 30)\\\
    return resolvedID\\\
end \\\
\\\
function cloneZones.resolveUnitID(uID, rawData, dataTable, reason)\\\
-- also resolves statics as they share ID with units \\\
    local resolvedID = uID\\\
    --trigger.action.outText(\\\"Resolve reference to unitId <\\\" .. uID .. \\\"> for <\\\" .. reason.. \\\"> task\\\", 30)\\\
    \\\
    -- first, check if this an internal reference, i.e. inside the same \\\
    -- zone template \\\
    for idx, otherData in pairs(dataTable) do\\\
        -- iterate all units\\\
        for idy, aUnit in pairs(otherData.units) do \\\
            if aUnit.CZorigID == uID then \\\
                resolvedID = aUnit.CZTargetID\\\
                --trigger.action.outText(\\\"resolved (internally) \\\" .. uID .. \\\" to \\\" .. resolvedID, 30)\\\
                return resolvedID\\\
            end\\\
        end        \\\
\\\
    end\\\
    \\\
    -- now check if we have spawned this before \\\
    local lastClone = cloneZones.unitXlate[uID]\\\
    if lastClone then \\\
        resolvedID = lastClone\\\
        --trigger.action.outText(\\\"resolved (U-EXT) \\\" .. uID .. \\\" to \\\" .. resolvedID, 30)\\\
        return resolvedID    \\\
    end\\\
    \\\
    -- if we get here, reference is not to a cloned item \\\
    --trigger.action.outText(\\\"resolved G-\\\" .. uID .. \\\" to \\\" .. resolvedID, 30)\\\
    return resolvedID\\\
end \\\
\\\
function cloneZones.resolveStaticLinkUnit(uID)\\\
    local resolvedID = uID\\\
    local lastClone = cloneZones.unitXlate[uID]\\\
    if lastClone then \\\
        resolvedID = lastClone\\\
        --trigger.action.outText(\\\"resolved (U-EXT) \\\" .. uID .. \\\" to \\\" .. resolvedID, 30)\\\
        return resolvedID    \\\
    end\\\
    return resolvedID\\\
end\\\
\\\
function cloneZones.resolveWPReferences(rawData, theZone, dataTable)\\\
-- check to see if we really need data table, as we have theZone \\\
-- perform a check of route for group or unit references \\\
    if not rawData then return end \\\
    local myOName = rawData.CZorigName \\\
\\\
    if rawData.route and rawData.route.points then \\\
        local points = rawData.route.points \\\
        for idx, aPoint in pairs(points) do \\\
            -- check if there is a link unit here and resolve \\\
            if aPoint.linkUnit then \\\
                local gID = aPoint.linkUnit\\\
                local resolvedID = cloneZones.resolveUnitID(gID, rawData, dataTable, \\\"linkUnit\\\")\\\
                aPoint.linkUnit = resolvedID\\\
                --trigger.action.outText(\\\"resolved link unit to \\\"..resolvedID .. \\\" for \\\" .. rawData.name, 30)\\\
            end\\\
            \\\
            -- iterate all tasks assigned to point\\\
            local task = aPoint.task\\\
            if task and task.params and task.params.tasks then\\\
                local tasks = task.params.tasks \\\
                for idy, taskData in pairs(tasks) do\\\
                    -- resolve group references in TASKS\\\
                    if taskData.id and taskData.params and taskData.params.groupId\\\
                    then \\\
                        -- we resolve group reference \\\
                        local gID = taskData.params.groupId\\\
                        local resolvedID = cloneZones.resolveGroupID(gID, rawData, dataTable, taskData.id)\\\
                        taskData.params.groupId = resolvedID\\\
                        \\\
                    end\\\
                    \\\
                    -- resolve unit references in TASKS\\\
                    if taskData.id and taskData.params and taskData.params.unitId\\\
                    then \\\
                        -- we don't look for keywords, we simply resolve \\\
                        local uID = taskData.params.unitId \\\
                        local resolvedID = cloneZones.resolveUnitID(uID, rawData, dataTable, taskData.id)\\\
                        taskData.params.unitId = resolvedID\\\
                    end\\\
                    \\\
                    -- resolve unit references in ACTIONS\\\
                    if taskData.params and taskData.params.action and \\\
                    taskData.params.action.params and taskData.params.action.params.unitId then \\\
                        local uID = taskData.params.action.params.unitId \\\
                        local resolvedID = cloneZones.resolveUnitID(uID, rawData, dataTable, \\\"Action\\\")\\\
                        taskData.params.action.params.unitId = resolvedID\\\
                    end\\\
                end    \\\
            end\\\
        end\\\
    end \\\
end \\\
\\\
function cloneZones.resolveReferences(theZone, dataTable) \\\
    -- when an action refers to another group, we check if \\\
    -- the group referred to is also a clone, and update \\\
    -- the reference to the newest incardnation \\\
    \\\
    for idx, rawData in pairs(dataTable) do \\\
        -- resolve references in waypoints\\\
        cloneZones.resolveWPReferences(rawData, theZone, dataTable)\\\
    end\\\
end\\\
\\\
function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)\\\
    -- theZone is the cloner with the template\\\
    -- spawnZone is the spawner with settings \\\
    --if not spawnZone then spawnZone = theZone end \\\
    local newCenter = cfxZones.getPoint(spawnZone) \\\
    -- calculate zoneDelta, is added to all vectors \\\
    local zoneDelta = dcsCommon.vSub(newCenter, theZone.origin)\\\
    \\\
    local spawnedGroups = {}\\\
    local spawnedStatics = {}\\\
    local dataToSpawn = {}\\\
    \\\
    for idx, aGroupName in pairs(theZone.cloneNames) do \\\
        local rawData, cat, ctry = cfxMX.getGroupFromDCSbyName(aGroupName)\\\
        rawData.CZorigName = rawData.name -- save original group name\\\
        local origID = rawData.groupId -- save original group ID \\\
        rawData.CZorigID = origID \\\
        cloneZones.uniqueIDGroupData(rawData) -- assign unique ID we know \\\
        cloneZones.uniqueIDUnitData(rawData) -- assign unique ID for units -- saves old unitId as CZorigID\\\
        rawData.CZTargetID = rawData.groupId -- save \\\
        if rawData.name ~= aGroupName then \\\
            trigger.action.outText(\\\"Clone: FAILED name check\\\", 30)\\\
        end\\\
        \\\
        -- now use raw data to spawn and see if it works outabox\\\
        local theCat = cfxMX.catText2ID(cat)\\\
        rawData.CZtheCat = theCat -- save cat \\\
        \\\
        -- update their position if not spawning to exact same location \\\
        cloneZones.updateLocationsInGroupData(rawData, zoneDelta, spawnZone.moveRoute)\\\
        \\\
        -- apply turning \\\
        dcsCommon.rotateGroupData(rawData, spawnZone.turn, newCenter.x, newCenter.z)\\\
        \\\
        -- make sure unit and group names are unique \\\
        cloneZones.uniqueNameGroupData(rawData)\\\
        \\\
        -- see what country we spawn for\\\
        ctry = cloneZones.resolveOwnership(spawnZone, ctry)\\\
        rawData.CZctry = ctry -- save ctry \\\
        table.insert(dataToSpawn, rawData)\\\
    end \\\
    \\\
    -- now resolve references to other cloned units for all raw data\\\
    -- we must do this BEFORE we spawn\\\
    cloneZones.resolveReferences(theZone, dataToSpawn)\\\
    \\\
    -- now spawn all raw data \\\
    for idx, rawData in pairs (dataToSpawn) do \\\
        -- now spawn and save to clones\\\
        local theGroup = coalition.addGroup(rawData.CZctry, rawData.CZtheCat, rawData)\\\
        table.insert(spawnedGroups, theGroup)\\\
        \\\
        --trigger.action.outText(\\\"spawned group \\\" .. rawData.name .. \\\"consisting of\\\", 30)\\\
        \\\
        -- update groupXlate table \\\
        local newGroupID = theGroup:getID() -- new ID assigned by DCS\\\
        local origID = rawData.CZorigID -- before we materialized\\\
        cloneZones.groupXlate[origID] = newGroupID\\\
        -- now also save all units for references     \\\
        -- and verify assigned vs target ID \\\
        for idx, aUnit in pairs(rawData.units) do \\\
            -- access the proposed name \\\
            local uName = aUnit.name \\\
            local gUnit = Unit.getByName(uName)\\\
            if gUnit then \\\
                -- unit exists. compare planned and assigned ID\\\
                local uID = tonumber(gUnit:getID())\\\
                if uID == aUnit.CZTargetID then \\\
                    --trigger.action.outText(\\\"unit \\\" .. uName .. \\\"#\\\"..uID, 30)\\\
                    -- all good \\\
                else \\\
                    trigger.action.outText(\\\"clnZ: post-clone verification failed for unit <\\\" .. uName .. \\\">: ÎD mismatch: \\\" .. uID .. \\\" -- \\\" .. aUnit.CZTargetID, 30)\\\
                end \\\
                cloneZones.unitXlate[aUnit.CZorigID] = uID \\\
            else \\\
                trigger.action.outText(\\\"clnZ: post-clone verifiaction failed for unit <\\\" .. uName .. \\\">: not found\\\", 30) \\\
            end \\\
        end\\\
        \\\
        -- check if our assigned ID matches the handed out by \\\
        -- DCS\\\
        if newGroupID == rawData.CZTargetID then \\\
            -- we are good\\\
        else \\\
            trigger.action.outText(\\\"clnZ: MISMATCH \\\" .. rawData.name .. \\\" target ID \\\" .. rawData.CZTargetID .. \\\" does not match \\\" .. newGroupID, 30)\\\
        end \\\
\\\
        cloneZones.invokeCallbacks(theZone, \\\"did spawn group\\\", theGroup)\\\
    end\\\
\\\
    -- static spawns \\\
    for idx, aStaticName in pairs(theZone.staticNames) do \\\
        local rawData, cat, ctry, parent = cfxMX.getStaticFromDCSbyName(aStaticName) -- returns a UNIT data block\\\
        \\\
        if not rawData then\\\
            trigger.action.outText(\\\"Static Clone: no such group <\\\"..aStaticName .. \\\">\\\", 30)            \\\
        elseif rawData.name == aStaticName then \\\
            -- all good\\\
        else \\\
            trigger.action.outText(\\\"Static Clone: FAILED name check for <\\\" .. aStaticName .. \\\">\\\", 30)\\\
        end\\\
        local origID = rawData.unitId -- save original unit ID\\\
        rawData.CZorigID = origID \\\
                \\\
        -- now use raw data to spawn and see if it works outabox\\\
        --local theCat = cfxMX.catText2ID(cat) -- will be \\\"static\\\"\\\
        \\\
        -- move origin \\\
        rawData.x = rawData.x + zoneDelta.x \\\
        rawData.y = rawData.y + zoneDelta.z -- !!!\\\
    \\\
        -- apply turning \\\
        dcsCommon.rotateUnitData(rawData, spawnZone.turn, newCenter.x, newCenter.z)\\\
        \\\
        -- make sure static name is unique and remember original \\\
        rawData.name = dcsCommon.uuid(rawData.name)\\\
        rawData.unitId = cloneZones.uniqueID()  \\\
        rawData.CZTargetID = rawData.unitId \\\
        \\\
        -- see what country we spawn for\\\
        ctry = cloneZones.resolveOwnership(spawnZone, ctry)\\\
        \\\
        -- handle linkUnit if provided  \\\
        if rawData.linkUnit then \\\
            --trigger.action.outText(\\\"has link to \\\" .. rawData.linkUnit, 30)\\\
            local lU = cloneZones.resolveStaticLinkUnit(rawData.linkUnit)\\\
            --trigger.action.outText(\\\"resolved to \\\" .. lU, 30)\\\
            rawData.linkUnit = lU \\\
            if not rawData.offsets then \\\
                rawData.offsets = {}\\\
                rawData.offsets.angle = 0\\\
                rawData.offsets.x = 0\\\
                rawData.offsets.y = 0\\\
                --trigger.action.outText(\\\"clnZ: link required offset for \\\" .. rawData.name, 30)\\\
            end \\\
            rawData.offsets.y = rawData.offsets.y - zoneDelta.z \\\
            rawData.offsets.x = rawData.offsets.x - zoneDelta.x \\\
            rawData.offsets.angle = rawData.offsets.angle + spawnZone.turn\\\
            rawData.linkOffset = true \\\
--            trigger.action.outText(\\\"zone deltas are \\\" .. zoneDelta.x .. \\\", \\\" .. zoneDelta.y, 30)\\\
        end\\\
        \\\
        local theStatic = coalition.addStaticObject(ctry, rawData)\\\
        local newStaticID = tonumber(theStatic:getID()) \\\
        table.insert(spawnedStatics, theStatic)\\\
        -- we don't mix groups with units, so no lookup tables for \\\
        -- statics \\\
        if newStaticID == rawData.CZTargetID then \\\
--            trigger.action.outText(\\\"Static ID OK: \\\" .. newStaticID  .. \\\" for \\\" .. rawData.name, 30)\\\
        else \\\
            trigger.action.outText(\\\"Static ID mismatch: \\\" .. newStaticID .. \\\" vs (target) \\\" .. rawData.CZTargetID .. \\\" for \\\" .. rawData.name, 30)\\\
        end\\\
        cloneZones.unitXlate[origID] = newStaticID -- same as units \\\
        \\\
        cloneZones.invokeCallbacks(theZone, \\\"did spawn static\\\", theStatic)\\\
        --]]--\\\
        if cloneZones.verbose then \\\
            trigger.action.outText(\\\"Static spawn: spawned \\\" .. aStaticName, 30)\\\
        end \\\
    end    \\\
    local args = {}\\\
    args.groups = spawnedGroups\\\
    args.statics = spawnedStatics\\\
    cloneZones.invokeCallbacks(theZone, \\\"spawned\\\", args)\\\
    return spawnedGroups, spawnedStatics \\\
end\\\
\\\
function cloneZones.spawnWithCloner(theZone) \\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++clnZ: nil zone on spawnWithCloner\\\", 30)\\\
        return \\\
    end\\\
    if not theZone.cloner then \\\
        trigger.action.outText(\\\"+++clnZ: spawnWithCloner invoked with non-cloner <\\\" .. theZone.name .. \\\">\\\", 30)\\\
        return \\\
    end \\\
    \\\
    -- force spawn with this spawner \\\
    local templateZone = theZone\\\
    if theZone.source then \\\
        -- we use a different zone for templates\\\
        -- souce can be a comma separated list\\\
        local templateName = theZone.source\\\
        if dcsCommon.containsString(templateName, \\\",\\\") then \\\
            local allNames = templateName \\\
            local templates = dcsCommon.splitString(templateName, \\\",\\\")\\\
            templateName = dcsCommon.pickRandom(templates)\\\
            templateName = dcsCommon.trim(templateName) \\\
            if cloneZones.verbose then \\\
                trigger.action.outText(\\\"+++clnZ: picked random template <\\\" .. templateName ..\\\"> for from <\\\" .. allNames .. \\\"> for cloner \\\" .. theZone.name, 30)\\\
            end \\\
        end\\\
        \\\
        local newTemplate = cloneZones.getCloneZoneByName(templateName)\\\
        if not newTemplate then \\\
            if cloneZones.verbose then \\\
                trigger.action.outText(\\\"+++clnZ: no clone source with name <\\\" .. templateName ..\\\"> for cloner \\\" .. theZone.name, 30)\\\
            end  \\\
            return \\\
        end\\\
        templateZone = newTemplate \\\
    end\\\
    \\\
    -- make sure our template is filled \\\
    if not templateZone.cloneNames then \\\
        if cloneZones.verbose then \\\
            trigger.action.outText(\\\"+++clnZ: clone source template <\\\".. templateZone.name .. \\\"> for clone zone <\\\" .. theZone.name ..\\\"> is empty\\\", 30)\\\
        end \\\
        return \\\
    end\\\
\\\
    -- pre-Wipe?\\\
    if theZone.preWipe then \\\
        cloneZones.despawnAll(theZone)\\\
        cloneZones.invokeCallbacks(theZone, \\\"wiped\\\", {})\\\
    end\\\
    \\\
\\\
    local theClones, theStatics = cloneZones.spawnWithTemplateForZone(templateZone, theZone)\\\
    -- reset hasClones so we know our spawns are full and we can \\\
    -- detect complete destruction\\\
    if (theClones and #theClones > 0) or \\\
       (theStatics and #theStatics > 0)\\\
    then \\\
        theZone.hasClones = true \\\
        theZone.mySpawns = theClones \\\
        theZone.myStatics = theStatics \\\
    else \\\
        theZone.hasClones = false \\\
        theZone.mySpawns = {}\\\
        theZone.myStatics = {}\\\
    end\\\
end\\\
\\\
function cloneZones.countLiveUnits(theZone)\\\
    if not theZone then return 0 end \\\
    local count = 0\\\
    -- count units \\\
    if theZone.mySpawns then \\\
        for idx, aGroup in pairs(theZone.mySpawns) do \\\
            if aGroup:isExist() then \\\
                local allUnits = aGroup:getUnits()\\\
                for idy, aUnit in pairs(allUnits) do \\\
                    if aUnit:isExist() and aUnit:getLife() >= 1 then \\\
                        count = count + 1\\\
                    end\\\
                end\\\
            end\\\
        end\\\
    end\\\
    \\\
    -- count statics \\\
    if theZone.myStatics then \\\
        for idx, aStatic in pairs(theZone.myStatics) do \\\
            if aStatic:isExist() and aStatic:getLife() >= 1 then \\\
                count = count + 1\\\
            end\\\
        end\\\
    end\\\
    return count \\\
end\\\
\\\
function cloneZones.hasLiveUnits(theZone)\\\
    if not theZone then return 0 end \\\
    if theZone.mySpawns then \\\
        for idx, aGroup in pairs(theZone.mySpawns) do \\\
            if aGroup:isExist() then \\\
                local allUnits = aGroup:getUnits()\\\
                for idy, aUnit in pairs(allUnits) do \\\
                    if aUnit:isExist() and aUnit:getLife() >= 1 then \\\
                        return true\\\
                    end\\\
                end\\\
            end\\\
        end\\\
    end \\\
    \\\
    if theZone.myStatics then \\\
        for idx, aStatic in pairs(theZone.myStatics) do \\\
            if aStatic:isExist() and aStatic.getLife() >= 1 then \\\
                return true \\\
            end \\\
        end\\\
    end\\\
    \\\
    return false\\\
end\\\
\\\
-- old code, deprecated\\\
--[[--\\\
function cloneZones.pollFlag(flagNum, method)\\\
    -- we currently ignore method \\\
    local num = trigger.misc.getUserFlag(flagNum)\\\
    trigger.action.setUserFlag(flagNum, num+1)\\\
end\\\
--]]--\\\
--\\\
-- UPDATE\\\
--\\\
function cloneZones.update()\\\
    timer.scheduleFunction(cloneZones.update, {}, timer.getTime() + 1)\\\
    \\\
    for idx, aZone in pairs(cloneZones.cloners) do\\\
        -- see if deSpawn was pulled. Must run before spawn\\\
        if aZone.deSpawnFlag then \\\
            local currTriggerVal = cfxZones.getFlagValue(aZone.deSpawnFlag, aZone) -- trigger.misc.getUserFlag(aZone.deSpawnFlag)\\\
            if currTriggerVal ~= aZone.lastDeSpawnValue then \\\
                if cloneZones.verbose then \\\
                    trigger.action.outText(\\\"+++clnZ: DEspawn triggered for <\\\" .. aZone.name .. \\\">\\\", 30)\\\
                end \\\
                cloneZones.despawnAll(aZone)\\\
                aZone.lastDeSpawnValue = currTriggerVal\\\
            end\\\
        end\\\
        \\\
        -- see if we got spawn? command\\\
        if aZone.spawnFlag then \\\
            local currTriggerVal = cfxZones.getFlagValue(aZone.spawnFlag, aZone) -- trigger.misc.getUserFlag(aZone.spawnFlag)\\\
            if currTriggerVal ~= aZone.lastSpawnValue\\\
            then \\\
                if cloneZones.verbose then \\\
                    trigger.action.outText(\\\"+++clnZ: spawn triggered for <\\\" .. aZone.name .. \\\">\\\", 30)\\\
                end \\\
                cloneZones.spawnWithCloner(aZone)\\\
                aZone.lastSpawnValue = currTriggerVal\\\
            end\\\
        end\\\
        \\\
        -- empty handling \\\
        local isEmpty = cloneZones.countLiveUnits(aZone) < 1 and aZone.hasClones        \\\
        if isEmpty then \\\
            -- see if we need to bang a flag \\\
            if aZone.emptyFlag then \\\
                --cloneZones.pollFlag(aZone.emptyFlag)\\\
                cfxZones.pollFlag(aZone.emptyFlag, 'inc', aZone)\\\
            end \\\
            \\\
            if aZone.emptyBangFlag then \\\
                cfxZones.pollFlag(aZone.emptyBangFlag, aZone.method, aZone)\\\
                if cloneZones.verbose then \\\
                    trigger.action.outText(\\\"+++clnZ: bang! on \\\" .. aZone.emptyBangFlag, 30)\\\
                end\\\
            end\\\
            -- invoke callbacks \\\
            cloneZones.invokeCallbacks(aZone, \\\"empty\\\", {}) \\\
            \\\
            -- prevent isEmpty next pass\\\
            aZone.hasClones = false \\\
        end\\\
        \\\
    end\\\
end\\\
\\\
function cloneZones.onStart()\\\
    --trigger.action.outText(\\\"+++clnZ: Enter atStart\\\", 30)\\\
    for idx, theZone in pairs(cloneZones.cloners) do \\\
        if theZone.onStart then \\\
            if cloneZones.verbose then \\\
                trigger.action.outText(\\\"+++clnZ: atStart will spawn for <\\\"..theZone.name .. \\\">\\\", 30)\\\
            end\\\
            cloneZones.spawnWithCloner(theZone) \\\
            \\\
        end \\\
    end\\\
end\\\
\\\
--\\\
-- START \\\
--\\\
function cloneZones.readConfigZone()\\\
    local theZone = cfxZones.getZoneByName(\\\"cloneZonesConfig\\\") \\\
    if not theZone then \\\
        if cloneZones.verbose then \\\
            trigger.action.outText(\\\"+++clnZ: NO config zone!\\\", 30)\\\
        end \\\
        return \\\
    end \\\
    \\\
    cloneZones.verbose = cfxZones.getBoolFromZoneProperty(theZone, \\\"verbose\\\", false)\\\
    \\\
    if cloneZones.verbose then \\\
        trigger.action.outText(\\\"+++clnZ: read config\\\", 30)\\\
    end \\\
end\\\
\\\
function cloneZones.start()\\\
    -- lib check\\\
    if not dcsCommon.libCheck then \\\
        trigger.action.outText(\\\"cfx Clone Zones requires dcsCommon\\\", 30)\\\
        return false \\\
    end \\\
    if not dcsCommon.libCheck(\\\"cfx Clone Zones\\\", \\\
        cloneZones.requiredLibs) then\\\
        return false \\\
    end\\\
    \\\
    -- read config \\\
    cloneZones.readConfigZone()\\\
    \\\
    -- process cloner Zones \\\
    local attrZones = cfxZones.getZonesWithAttributeNamed(\\\"cloner\\\")\\\
    \\\
    -- now create an rnd gen for each one and add them\\\
    -- to our watchlist \\\
    for k, aZone in pairs(attrZones) do \\\
        cloneZones.createClonerWithZone(aZone) -- process attribute and add to zone\\\
        cloneZones.addCloneZone(aZone) -- remember it so we can smoke it\\\
    end\\\
    \\\
    -- run through onStart \\\
    cloneZones.onStart() \\\
    \\\
    -- start update \\\
    cloneZones.update()\\\
    \\\
    trigger.action.outText(\\\"cfx Clone Zones v\\\" .. cloneZones.version .. \\\" started.\\\", 30)\\\
    return true \\\
end\\\
\\\
\\\
-- let's go!\\\
if not cloneZones.start() then \\\
    trigger.action.outText(\\\"cf/x Clone Zones aborted: missing libraries\\\", 30)\\\
    cloneZones = nil \\\
end\\\
\\\
--[[-- callback testing \\\
czcb = {}\\\
function czcb.callback(theZone, reason, args)\\\
    trigger.action.outText(\\\"clone CB: \\\" .. theZone.name .. \\\" with \\\" .. reason, 30)\\\
end\\\
cloneZones.addCallback(czcb.callback)\\\
--]]--\\\
\\\
--[[--\\\
    to resolve tasks \\\
\\\
    - AFAC \\\
        - FAC Assign group \\\
    - set freq for unit \\\
--]]--\");a_do_script(\"messenger = {}\\\
messenger.version = \\\"1.1.0\\\"\\\
messenger.verbose = false \\\
messenger.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- always\\\
    \\\"cfxZones\\\", -- Zones, of course \\\
}\\\
messenger.messengers = {} \\\
--[[--\\\
    Version History\\\
    1.0.0 - initial version \\\
    1.0.1 - messageOut? synonym\\\
          - spelling types in about \\\
    1.1.0 - DML flag support \\\
          - clearScreen option\\\
          - inValue?\\\
          - message preprocessor \\\
    \\\
--]]--\\\
\\\
function messenger.addMessenger(theZone)\\\
    table.insert(messenger.messengers, theZone)\\\
end\\\
\\\
function messenger.getMessengerByName(aName) \\\
    for idx, aZone in pairs(messenger.messengers) do \\\
        if aName == aZone.name then return aZone end \\\
    end\\\
    if messenger.verbose then \\\
        trigger.action.outText(\\\"+++msgr: no messenger with name <\\\" .. aName ..\\\">\\\", 30)\\\
    end \\\
    \\\
    return nil \\\
end\\\
\\\
--\\\
-- read attributes\\\
--\\\
function messenger.createMessengerDownWithZone(theZone)\\\
    -- start val - a range\\\
    theZone.message = cfxZones.getStringFromZoneProperty(theZone, \\\"message\\\", \\\"\\\") \\\
\\\
    theZone.spaceBefore = cfxZones.getBoolFromZoneProperty(theZone, \\\"spaceBefore\\\", false)\\\
    theZone.spaceAfter = cfxZones.getBoolFromZoneProperty(theZone, \\\"spaceAfter\\\", false)\\\
\\\
    theZone.soundFile = cfxZones.getStringFromZoneProperty(theZone, \\\"soundFile\\\", \\\"<none>\\\") \\\
\\\
    theZone.clearScreen = cfxZones.getBoolFromZoneProperty(theZone, \\\"clearScreen\\\", false)\\\
    \\\
    -- alternate version: messages: list of messages, need string parser first\\\
    \\\
    theZone.duration = cfxZones.getNumberFromZoneProperty(theZone, \\\"duration\\\", 30)\\\
    \\\
    -- trigger flag f? in? messageOut?\\\
    if cfxZones.hasProperty(theZone, \\\"f?\\\") then \\\
        theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"f?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    -- can also use in? for counting. we always use triggerMessagerFlag \\\
    if cfxZones.hasProperty(theZone, \\\"in?\\\") then \\\
        theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"in?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"messageOut?\\\") then \\\
        theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"messageOut?\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if theZone.triggerMessagerFlag then \\\
        theZone.lastMessageTriggerValue = cfxZones.getFlagValue(theZone.triggerMessagerFlag, theZone)-- trigger.misc.getUserFlag(theZone.triggerMessagerFlag) -- save last value\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"coalition\\\") then \\\
        theZone.coalition = cfxZones.getCoalitionFromZoneProperty(theZone, \\\"coalition\\\", 0)\\\
    end \\\
    \\\
    -- flag whose value can be read \\\
    if cfxZones.hasProperty(theZone, \\\"messageValue?\\\") then \\\
        theZone.messageValue = cfxZones.getStringFromZoneProperty(theZone, \\\"messageValue?\\\", \\\"<none>\\\") \\\
    end\\\
    \\\
end\\\
\\\
--\\\
-- Update \\\
--\\\
function messenger.getMessage(theZone)\\\
    local msg = theZone.message\\\
    -- see if it has a \\\"$val\\\" in there \\\
    local zName = theZone.name \\\
    if not zName then zName = \\\"<strange!>\\\" end \\\
    local zVal = \\\"<n/a>\\\"\\\
    if theZone.messageValue then \\\
        zVal = cfxZones.getFlagValue(theZone.messageValue, theZone)\\\
        zVal = tostring(zVal)\\\
        if not zVal then zVal = \\\"<err>\\\" end \\\
    end \\\
    \\\
    \\\
    -- replace *zone and *value wildcards \\\
    msg = string.gsub(msg, \\\"*name\\\", zName)\\\
    msg = string.gsub(msg, \\\"*value\\\", zVal)\\\
    \\\
    return msg \\\
end\\\
\\\
function messenger.isTriggered(theZone)\\\
    -- this module has triggered \\\
    local fileName = \\\"l10n/DEFAULT/\\\" .. theZone.soundFile\\\
    local msg = messenger.getMessage(theZone)\\\
    \\\
    if theZone.spaceBefore then msg = \\\"\\\\n\\\"..msg end \\\
    if theZone.spaceAfter then msg = msg .. \\\"\\\\n\\\" end \\\
    \\\
    if theZone.coalition then \\\
        trigger.action.outTextForCoalition(theZone.coalition, msg, theZone.duration, theZone.clearScreen)\\\
        trigger.action.outSoundForCoalition(theZone.coalition, fileName)\\\
    else \\\
        -- out to all \\\
        trigger.action.outText(msg, theZone.duration, theZone.clearScreen)\\\
        trigger.action.outSound(fileName)\\\
    end\\\
end\\\
\\\
function messenger.update()\\\
    -- call me in a second to poll triggers\\\
    timer.scheduleFunction(messenger.update, {}, timer.getTime() + 1)\\\
        \\\
    for idx, aZone in pairs(messenger.messengers) do\\\
        -- make sure to re-start before reading time limit\\\
        if aZone.triggerMessagerFlag then \\\
            local currTriggerVal = cfxZones.getFlagValue(aZone.triggerMessagerFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerMessagerFlag)\\\
            if currTriggerVal ~= aZone.lastMessageTriggerValue\\\
            then \\\
                if messenger.verbose then \\\
                    trigger.action.outText(\\\"+++msgr: triggered on in?\\\", 30)\\\
                end\\\
                messenger.isTriggered(aZone)\\\
                aZone.lastMessageTriggerValue = cfxZones.getFlagValue(aZone.triggerMessagerFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerMessagerFlag) -- save last value\\\
            end\\\
        end\\\
    end\\\
end\\\
\\\
--\\\
-- Config & Start\\\
--\\\
function messenger.readConfigZone()\\\
    local theZone = cfxZones.getZoneByName(\\\"messengerConfig\\\") \\\
    if not theZone then \\\
        if messenger.verbose then \\\
            trigger.action.outText(\\\"+++msgr: NO config zone!\\\", 30)\\\
        end \\\
        return \\\
    end \\\
    \\\
    messenger.verbose = cfxZones.getBoolFromZoneProperty(theZone, \\\"verbose\\\", false)\\\
    \\\
    if messenger.verbose then \\\
        trigger.action.outText(\\\"+++msgr: read config\\\", 30)\\\
    end \\\
end\\\
\\\
function messenger.start()\\\
    -- lib check\\\
    if not dcsCommon.libCheck then \\\
        trigger.action.outText(\\\"cfx Messenger requires dcsCommon\\\", 30)\\\
        return false \\\
    end \\\
    if not dcsCommon.libCheck(\\\"cfx Messenger\\\", messenger.requiredLibs) then\\\
        return false \\\
    end\\\
    \\\
    -- read config \\\
    messenger.readConfigZone()\\\
    \\\
    -- process cloner Zones \\\
    local attrZones = cfxZones.getZonesWithAttributeNamed(\\\"messenger\\\")\\\
    for k, aZone in pairs(attrZones) do \\\
        messenger.createMessengerDownWithZone(aZone) -- process attributes\\\
        messenger.addMessenger(aZone) -- add to list\\\
    end\\\
    \\\
    -- start update \\\
    messenger.update()\\\
    \\\
    trigger.action.outText(\\\"cfx Messenger v\\\" .. messenger.version .. \\\" started.\\\", 30)\\\
    return true \\\
end\\\
\\\
-- let's go!\\\
if not messenger.start() then \\\
    trigger.action.outText(\\\"cfx Messenger aborted: missing libraries\\\", 30)\\\
    messenger = nil \\\
end\\\
\\\
--[[--\\\
Wildcard extension: \\\
  messageValue supports multiple flags like 1-3, *hi ther, *bingo and then *value[name] returns that value     \\\
--]]--\");a_do_script(\"countDown = {}\\\
countDown.version = \\\"1.2.1\\\"\\\
countDown.verbose = true \\\
countDown.ups = 1 \\\
countDown.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- always\\\
    \\\"cfxZones\\\", -- Zones, of course \\\
}\\\
\\\
--[[--\\\
    count down on flags to generate new signal on out \\\
    Copyright (c) 2022 by Christian Franz and cf/x AG\\\
    \\\
    Version History\\\
    1.0.0 - initial version \\\
    1.1.0 - Lua interface: callbacks \\\
          - corrected verbose (erroneously always suppressed)\\\
          - triggerFlag --> triggerCountFlag \\\
    1.1.1 - corrected bug in invokeCallback \\\
    1.2.0 - DML Flags \\\
          - counterOut!\\\
          - ups config \\\
    1.2.1 - disableCounter?\\\
    \\\
--]]--\\\
\\\
countDown.counters = {}\\\
countDown.callbacks = {}\\\
\\\
--\\\
-- add/remove zones\\\
--\\\
function countDown.addCountDown(theZone)\\\
    table.insert(countDown.counters, theZone)\\\
end\\\
\\\
function countDown.getCountDownZoneByName(aName) \\\
    for idx, aZone in pairs(countDown.counters) do \\\
        if aName == aZone.name then return aZone end \\\
    end\\\
    if countDown.verbose then \\\
        trigger.action.outText(\\\"+++cntD: no count down with name <\\\" .. aName ..\\\">\\\", 30)\\\
    end \\\
    \\\
    return nil \\\
end\\\
\\\
\\\
--\\\
-- callbacks \\\
--\\\
function countDown.addCallback(theCallback)\\\
    if not theCallback then return end \\\
    table.insert(countDown.callbacks, theCallback)\\\
end\\\
\\\
function countDown.invokeCallbacks(theZone, val, tminus, zero, belowZero, looping)\\\
    if not val then val = 1 end \\\
    if not tminus then tminus = false end \\\
    if not zero then zero = false end \\\
    if not belowZero then belowZero = false end \\\
    \\\
    -- invoke anyone who wants to know that a group \\\
    -- of people was rescued.\\\
    for idx, cb in pairs(countDown.callbacks) do \\\
        cb(theZone, val, tminus, zero, belowZero, looping)\\\
    end\\\
end\\\
--\\\
-- read attributes\\\
--\\\
function countDown.createCountDownWithZone(theZone)\\\
    -- start val - a range\\\
    theZone.startMinVal, theZone.startMaxVal = cfxZones.getPositiveRangeFromZoneProperty(theZone, \\\"countDown\\\", 1) -- we know this exists\\\
    theZone.currVal = dcsCommon.randomBetween(theZone.startMinVal, theZone.startMaxVal)\\\
    \\\
    if countDown.verbose then \\\
        trigger.action.outText(\\\"+++cntD: initing count down <\\\" .. theZone.name .. \\\"> with \\\" .. theZone.currVal, 30)\\\
    end\\\
    \\\
    \\\
    -- loop \\\
    theZone.loop = cfxZones.getBoolFromZoneProperty(theZone, \\\"loop\\\", false)\\\
\\\
    -- extend after zero\\\
    theZone.belowZero = cfxZones.getBoolFromZoneProperty(theZone, \\\"belowZero\\\", false)\\\
    \\\
    -- method \\\
    theZone.method = cfxZones.getStringFromZoneProperty(theZone, \\\"method\\\", \\\"flip\\\")\\\
    \\\
    -- trigger flag \\\"count\\\" / \\\"start?\\\"\\\
    if cfxZones.hasProperty(theZone, \\\"count?\\\") then \\\
        theZone.triggerCountFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"count?\\\", \\\"<none>\\\")\\\
    end\\\
\\\
    \\\
    -- can also use in? for counting. we always use triggerCountFlag \\\
    if cfxZones.hasProperty(theZone, \\\"in?\\\") then \\\
        theZone.triggerCountFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"in?\\\", \\\"<none>\\\")\\\
    end\\\
    \\\
    if theZone.triggerCountFlag then \\\
        theZone.lastCountTriggerValue = cfxZones.getFlagValue(theZone.triggerCountFlag, theZone) -- trigger.misc.getUserFlag(theZone.triggerCountFlag) -- save last value\\\
    end\\\
    \\\
    -- zero! bang \\\
    if cfxZones.hasProperty(theZone, \\\"zero!\\\") then \\\
        theZone.zeroFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"zero!\\\", \\\"<none>\\\")\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"out!\\\") then \\\
        theZone.zeroFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"out!\\\", \\\"<none>\\\")\\\
    end\\\
    \\\
    -- TMinus! bang \\\
    if cfxZones.hasProperty(theZone, \\\"tMinus!\\\") then \\\
        theZone.tMinusFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"tMinus!\\\", \\\"<none>\\\")\\\
    end\\\
    \\\
    -- counterOut val \\\
    if cfxZones.hasProperty(theZone, \\\"counterOut!\\\") then \\\
        theZone.counterOut = cfxZones.getStringFromZoneProperty(theZone, \\\"counterOut!\\\", \\\"<none>\\\")\\\
    end\\\
    \\\
    -- disableFlag \\\
    theZone.counterDisabled = false \\\
    if cfxZones.hasProperty(theZone, \\\"disableCounter?\\\") then \\\
        theZone.disableCounterFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"disableCounter?\\\", \\\"<none>\\\")\\\
        theZone.disableCounterFlagVal = cfxZones.getFlagValue(theZone.disableCounterFlag, theZone)\\\
    end\\\
end\\\
\\\
--\\\
-- Update \\\
--\\\
function countDown.isTriggered(theZone)\\\
    -- this module has triggered \\\
    local val = theZone.currVal - 1 -- decrease counter \\\
    if countDown.verbose then \\\
        trigger.action.outText(\\\"+++cntD: enter triggered: val now: \\\" .. val, 30)\\\
    end\\\
    local tMinus = false \\\
    local zero = false \\\
    local belowZero = false \\\
    local looping = false \\\
    \\\
    if theZone.counterOut then \\\
        cfxZones.setFlagValue(theZone.counterOut, val, theZone)\\\
    end\\\
    \\\
    if val > 0 then \\\
        tMinus = true \\\
        -- see if we need to bang Tminus \\\
        if theZone.tMinusFlag then \\\
            if countDown.verbose then \\\
                trigger.action.outText(\\\"+++cntD: TMINUTS\\\", 30)\\\
            end\\\
            cfxZones.pollFlag(theZone.tMinusFlag, theZone.method, theZone)\\\
        end\\\
        \\\
    elseif val == 0 then \\\
        -- reached zero \\\
        zero = true \\\
        if theZone.zeroFlag then \\\
            if countDown.verbose then \\\
                trigger.action.outText(\\\"+++cntD: ZERO\\\", 30)\\\
            end\\\
            cfxZones.pollFlag(theZone.zeroFlag, theZone.method, theZone)\\\
        end\\\
        \\\
        if theZone.loop then \\\
            -- restart time\\\
            looping = true \\\
            if countDown.verbose then \\\
                trigger.action.outText(\\\"+++cntD: Looping\\\", 30)\\\
            end\\\
            val = dcsCommon.randomBetween(theZone.startMinVal, theZone.startMaxVal)\\\
        end \\\
        \\\
    else \\\
        -- below zero\\\
        belowZero = true \\\
        if theZone.belowZero and theZone.zeroFlag then\\\
            if countDown.verbose then \\\
                trigger.action.outText(\\\"+++cntD: Below Zero\\\", 30)\\\
            end\\\
            cfxZones.pollFlag(theZone.zeroFlag, theZone.method, theZone)\\\
        end \\\
        \\\
    end\\\
    \\\
    -- callbacks \\\
    countDown.invokeCallbacks(theZone, val, tMinus, zero, belowZero, looping)\\\
    \\\
    -- update & return \\\
    theZone.currVal = val \\\
    \\\
end\\\
\\\
function countDown.update()\\\
    -- call me in a second/ups to poll triggers\\\
    timer.scheduleFunction(countDown.update, {}, timer.getTime() + 1/countDown.ups)\\\
        \\\
    for idx, aZone in pairs(countDown.counters) do\\\
        -- make sure to re-start before reading time limit\\\
        if aZone.triggerCountFlag and not aZone.counterDisabled then \\\
            local currTriggerVal = cfxZones.getFlagValue(aZone.triggerCountFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerCountFlag)\\\
            if currTriggerVal ~= aZone.lastCountTriggerValue\\\
            then \\\
                if countDown.verbose then \\\
                    trigger.action.outText(\\\"+++cntD: triggered on in?\\\", 30)\\\
                end\\\
                countDown.isTriggered(aZone)\\\
                aZone.lastCountTriggerValue = cfxZones.getFlagValue(aZone.triggerCountFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerCountFlag) -- save last value\\\
            end\\\
        end\\\
        \\\
        if aZone.disableCounterFlag then \\\
            local currVal = cfxZones.getFlagValue(aZone.disableCounterFlag, aZone)\\\
            if currVal ~= aZone.disableCounterFlagVal then \\\
                if countDown.verbose then \\\
                    trigger.action.outText(\\\"+++cntD: disabling counter \\\" .. aZone.name, 30)\\\
                end\\\
                aZone.counterDisabled = true \\\
            end\\\
        end\\\
    end\\\
end\\\
\\\
--\\\
-- Config & Start\\\
--\\\
function countDown.readConfigZone()\\\
    local theZone = cfxZones.getZoneByName(\\\"countDownConfig\\\") \\\
    if not theZone then \\\
        if countDown.verbose then \\\
            trigger.action.outText(\\\"+++cntD: NO config zone!\\\", 30)\\\
        end \\\
        return \\\
    end \\\
    \\\
    countDown.ups = cfxZones.getNumberFromZoneProperty(theZone, \\\"ups\\\", 1)\\\
    -- slowest is once avery 1000 seconds = 17 minutes, doesn't make much sense slower than 1/second anyway \\\
    \\\
    if countDown.ups < 0.001 then countDown.ups = 0.001 end \\\
    \\\
    countDown.verbose = cfxZones.getBoolFromZoneProperty(theZone, \\\"verbose\\\", false)\\\
    \\\
    if countDown.verbose then \\\
        trigger.action.outText(\\\"+++cntD: read config\\\", 30)\\\
    end \\\
end\\\
\\\
function countDown.start()\\\
    -- lib check\\\
    if not dcsCommon.libCheck then \\\
        trigger.action.outText(\\\"cfx Count Down requires dcsCommon\\\", 30)\\\
        return false \\\
    end \\\
    if not dcsCommon.libCheck(\\\"cfx Count Down\\\", countDown.requiredLibs) then\\\
        return false \\\
    end\\\
    \\\
    -- read config \\\
    countDown.readConfigZone()\\\
    \\\
    -- process cloner Zones \\\
    local attrZones = cfxZones.getZonesWithAttributeNamed(\\\"countDown\\\")\\\
    for k, aZone in pairs(attrZones) do \\\
        countDown.createCountDownWithZone(aZone) -- process attributes\\\
        countDown.addCountDown(aZone) -- add to list\\\
    end\\\
    \\\
    \\\
    -- start update \\\
    countDown.update()\\\
    \\\
    trigger.action.outText(\\\"cfx Count Down v\\\" .. countDown.version .. \\\" started.\\\", 30)\\\
    return true \\\
end\\\
\\\
-- let's go!\\\
if not countDown.start() then \\\
    trigger.action.outText(\\\"cfx Count Down aborted: missing libraries\\\", 30)\\\
    countDown = nil \\\
end\\\
\\\
-- additions: range for start value to randomize \");a_do_script(\"unitZone={}\\\
unitZone.version = \\\"1.0.0\\\"\\\
unitZone.verbose = false \\\
unitZone.ups = 1 \\\
unitZone.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- always\\\
    \\\"cfxZones\\\", -- Zones, of course \\\
}\\\
unitZone.unitZones = {}\\\
\\\
function unitZone.addUnitZone(theZone)\\\
    table.insert(unitZone.unitZones, theZone)\\\
end\\\
\\\
function unitZone.getUnitZoneByName(aName) \\\
    for idx, aZone in pairs(unitZone.unitZones) do \\\
        if aName == aZone.name then return aZone end \\\
    end\\\
    if unitZone.verbose then \\\
        trigger.action.outText(\\\"+++uZne: no unitZone with name <\\\" .. aName ..\\\">\\\", 30)\\\
    end \\\
    \\\
    return nil \\\
end\\\
\\\
function unitZone.string2cat(filterString)\\\
\\\
    if not filterString then return 2 end -- default ground \\\
    filterString = filterString:lower()\\\
    filterString = dcsCommon.trim(filterString)\\\
\\\
    local catNum = tonumber(filterString)\\\
    if catNum then \\\
        if catNum < 0 then catNum = 0 end \\\
        if catNum > 4 then catNum = 4 end \\\
        return catNum \\\
    end\\\
    \\\
    catNum = 2 -- ground default \\\
    if dcsCommon.stringStartsWith(filterString, \\\"grou\\\") then catNum = 2 end \\\
    if dcsCommon.stringStartsWith(filterString, \\\"air\\\") then catNum = 0 end\\\
    if dcsCommon.stringStartsWith(filterString, \\\"hel\\\") then catNum = 1 end\\\
    if dcsCommon.stringStartsWith(filterString, \\\"shi\\\") then catNum = 3 end\\\
    if dcsCommon.stringStartsWith(filterString, \\\"trai\\\") then catNum = 4 end\\\
\\\
    return catNum\\\
end\\\
\\\
function unitZone.createUnitZone(theZone)\\\
    -- start val - a range\\\
    theZone.lookFor = cfxZones.getStringFromZoneProperty(theZone, \\\"lookFor\\\", \\\"cfx no unit supplied\\\") \\\
    if dcsCommon.stringEndsWith(theZone.lookFor, \\\"*\\\") then \\\
        theZone.lookForBeginsWith = true \\\
        theZone.lookFor = dcsCommon.removeEnding(theZone.lookFor, \\\"*\\\") \\\
    end\\\
    \\\
    theZone.matching = cfxZones.getStringFromZoneProperty(theZone, \\\"matching\\\", \\\"group\\\") -- group, player [, name, type]\\\
    theZone.matching = dcsCommon.trim(theZone.matching:lower())\\\
    if theZone.matching == \\\"groups\\\" then theZone.matching = \\\"group\\\" end -- some simplification \\\
    if theZone.matching == \\\"players\\\" then theZone.matching = \\\"player\\\" end -- some simplification \\\
\\\
    theZone.coalition = cfxZones.getCoalitionFromZoneProperty(theZone, \\\"coalition\\\", 0) -- 0 = all\\\
\\\
    theZone.enterZone = cfxZones.getStringFromZoneProperty(theZone, \\\"enterZone!\\\", \\\"<none>\\\")\\\
    theZone.exitZone = cfxZones.getStringFromZoneProperty(theZone, \\\"exitZone!\\\", \\\"<none>\\\")    \\\
    theZone.changeZone = cfxZones.getStringFromZoneProperty(theZone, \\\"changeZone!\\\", \\\"<none>\\\")\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"filterFor\\\") then \\\
        local filterString = cfxZones.getStringFromZoneProperty(theZone, \\\"filterFor\\\", \\\"1\\\") -- ground \\\
        theZone.filterFor = unitZone.string2cat(filterString)\\\
        if unitZone.verbose then \\\
            trigger.action.outText(\\\"+++uZne: filtering \\\" .. theZone.filterFor .. \\\" in \\\" .. theZone.name, 30)\\\
        end \\\
    end    \\\
    \\\
    -- now get initial zone status ?\\\
    theZone.lastStatus = unitZone.checkZoneStatus(theZone)\\\
    \\\
    trigger.action.outText(\\\"unit zone \\\" .. theZone.name, 30)\\\
end\\\
\\\
\\\
--\\\
-- process zone \\\
--\\\
\\\
function unitZone.collectGroups(theZone)\\\
    local collector = {}\\\
    if theZone.matching == \\\"player\\\" then \\\
        -- collect all players matching coalition\\\
        if theZone.coalition == 1 or theZone.coalition == 0 then \\\
            local allPlayers = coalition.getPlayers(1)\\\
            for idx, pUnit in pairs(allPlayers) do \\\
                table.insert(collector, pUnit)\\\
            end\\\
        end \\\
        if theZone.coalition == 2 or theZone.coalition == 0 then \\\
            local allPlayers = coalition.getPlayers(2)\\\
            for idx, pUnit in pairs(allPlayers) do \\\
                table.insert(collector, pUnit)\\\
            end\\\
        end\\\
    elseif theZone.matching == \\\"group\\\" then \\\
        if theZone.coalition == 1 or theZone.coalition == 0 then \\\
            local allGroups = coalition.getGroups(1, theZone.filterFor)\\\
\\\
            for idx, pUnit in pairs(allGroups) do \\\
                table.insert(collector, pUnit)\\\
            end\\\
        end \\\
        if theZone.coalition == 2 or theZone.coalition == 0 then \\\
            local allGroups = coalition.getGroups(2, theZone.filterFor)\\\
\\\
            for idx, pUnit in pairs(allGroups) do \\\
                table.insert(collector, pUnit)\\\
            end\\\
        end\\\
    else \\\
        trigger.action.outText(\\\"+++uZne: unknown matching: \\\" .. theZone.matching, 30)\\\
        return {}\\\
    end\\\
    \\\
    return collector\\\
end\\\
\\\
function unitZone.checkZoneStatus(theZone)\\\
    -- returns true (at least one unit found in zone)\\\
    -- or false (no unit found in zone)\\\
    \\\
    -- collect all groups to inspect \\\
    local theGroups = unitZone.collectGroups(theZone)\\\
    local lookFor = theZone.lookFor\\\
    -- now see if the groups match name and then check inside status for each \\\
    local playerCheck = theZone.matching == \\\"player\\\"\\\
    if playerCheck then \\\
        -- we check the names for players only \\\
        for idx, pUnit in pairs(theGroups) do \\\
            local puName=pUnit:getName()\\\
            local hasMatch = false \\\
            if theZone.lookForBeginsWith then \\\
                hasMatch = dcsCommon.stringStartsWith(puName, lookFor)\\\
            else \\\
                hasMatch = puName == lookFor \\\
            end\\\
            if hasMatch then \\\
                if cfxZones.unitInZone(pUnit, theZone) then \\\
                    return true\\\
                end\\\
            end\\\
        end \\\
        \\\
    else \\\
        -- we perform group cehck \\\
        for idx, aGroup in pairs(theGroups) do \\\
            local gName=aGroup:getName()\\\
            local hasMatch = false \\\
            if theZone.lookForBeginsWith then \\\
                hasMatch = dcsCommon.stringStartsWith(gName, lookFor)\\\
            else \\\
                hasMatch = gName == lookFor \\\
            end\\\
            if hasMatch and aGroup:isExist() then \\\
                -- check all living units in zone \\\
                local gUnits = aGroup:getUnits()\\\
                for idy, aUnit in pairs (gUnits) do\\\
                    --trigger.action.outText(\\\"trying \\\" .. gName,10)\\\
                    if cfxZones.unitInZone(aUnit, theZone) then \\\
                        return true\\\
                    end\\\
                end\\\
            end\\\
        end\\\
    end\\\
    return false \\\
end\\\
\\\
--\\\
-- update \\\
--\\\
function unitZone.bangState(theZone, newState)\\\
    cfxZones.pollFlag(theZone.changeZone, \\\"inc\\\", theZone)\\\
            \\\
    if newState then \\\
        cfxZones.pollFlag(theZone.enterZone, \\\"inc\\\", theZone)\\\
    else \\\
        cfxZones.pollFlag(theZone.exitZone, \\\"inc\\\", theZone)\\\
    end\\\
end\\\
\\\
function unitZone.update()\\\
    -- call me in a second to poll triggers\\\
    timer.scheduleFunction(unitZone.update, {}, timer.getTime() + 1/unitZone.ups)\\\
        \\\
    for idx, aZone in pairs(unitZone.unitZones) do\\\
        -- scan all zones \\\
        local newState = unitZone.checkZoneStatus(aZone)\\\
\\\
        if newState ~= aZone.lastStatus then \\\
            -- bang on change! \\\
            unitZone.bangState(aZone, newState)\\\
            aZone.lastStatus = newState \\\
        end\\\
    end\\\
end\\\
\\\
--\\\
-- Config & Start\\\
--\\\
function unitZone.readConfigZone()\\\
    local theZone = cfxZones.getZoneByName(\\\"unitZoneConfig\\\") \\\
    if not theZone then \\\
        if unitZone.verbose then \\\
            trigger.action.outText(\\\"+++uZne: NO config zone!\\\", 30)\\\
        end \\\
        return \\\
    end \\\
    \\\
    unitZone.verbose = cfxZones.getBoolFromZoneProperty(theZone, \\\"verbose\\\", false)\\\
    \\\
    unitZone.ups = cfxZones.getNumberFromZoneProperty(theZone, \\\"ups\\\", 1)\\\
    \\\
    if unitZone.verbose then \\\
        trigger.action.outText(\\\"+++uZne: read config\\\", 30)\\\
    end \\\
end\\\
\\\
function unitZone.start()\\\
    -- lib check\\\
    if not dcsCommon.libCheck then \\\
        trigger.action.outText(\\\"cfx Unit Zone requires dcsCommon\\\", 30)\\\
        return false \\\
    end \\\
    if not dcsCommon.libCheck(\\\"cfx Unit Zone\\\", unitZone.requiredLibs) then\\\
        return false \\\
    end\\\
    \\\
    -- read config \\\
    unitZone.readConfigZone()\\\
    \\\
    -- process cloner Zones \\\
    local attrZones = cfxZones.getZonesWithAttributeNamed(\\\"unitZone\\\")\\\
    for k, aZone in pairs(attrZones) do \\\
        unitZone.createUnitZone(aZone) -- process attributes\\\
        unitZone.addUnitZone(aZone) -- add to list\\\
    end\\\
    \\\
    -- start update \\\
    unitZone.update()\\\
    \\\
    trigger.action.outText(\\\"cfx Unit Zone v\\\" .. unitZone.version .. \\\" started.\\\", 30)\\\
    return true \\\
end\\\
\\\
-- let's go!\\\
if not unitZone.start() then \\\
    trigger.action.outText(\\\"cfx Unit Zone aborted: missing libraries\\\", 30)\\\
    unitZone = nil \\\
end\\\
\\\
--ToDo: add 'neutral' support and add 'both' option \\\
--ToDo: add API \");a_do_script(\"cfxSSBClient = {}\\\
cfxSSBClient.version = \\\"2.0.2\\\"\\\
cfxSSBClient.verbose = false \\\
cfxSSBClient.singleUse = false -- set to true to block crashed planes\\\
-- NOTE: singleUse (true) requires SSB to disable immediate respawn after kick\\\
cfxSSBClient.reUseAfter = -1 -- seconds for re-use delay\\\
  -- only when singleUse is in effect. -1 means never \\\
  \\\
cfxSSBClient.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- always\\\
    \\\"cfxGroups\\\", -- for slot access\\\
    \\\"cfxZones\\\", -- Zones, of course \\\
}\\\
\\\
--[[--\\\
Version History\\\
  1.0.0 - initial version\\\
  1.1.0 - detect airfield by action and location, not group name\\\
  1.1.1 - performance tuning. only read player groups once \\\
        - and remove in-air-start groups from scan. this requires\\\
        - ssb (server) be not modified    \\\
  1.2.0 - API to close airfields: invoke openAirfieldNamed() \\\
          and closeAirfieldNamed() with name as string (exact match required)\\\
          to block an airfield for any player aircraft.\\\
          Works for FARPS as well \\\
          API to associate a player group with any airfied's status (nil for unbind):\\\
          cfxSSBClient.bindGroupToAirfield(group, airfieldName)\\\
          API shortcut to unbind groups: cfxSSBClient.unbindGroup(group) \\\
          verbose messages now identify better: \\\"+++SSB:\\\"\\\
          keepInAirGroups option \\\
  2.0.0 - include single-use ability: crashed airplanes are blocked from further use\\\
        - single-use can be turned off \\\
        - getPlayerGroupForGroupNamed()\\\
        - split setSlotAccess to single accessor \\\
          and interator\\\
        - reUseAfter option for single-use  \\\
        - dcsCommon, cfxZones import\\\
  2.0.1 - stricter verbosity: moved more comments to verbose only \\\
  2.0.2 - health check code (initial) \\\
        - added verbosity\\\
    \\\
WHAT IT IS\\\
SSB Client is a small script that forms the client-side counterpart to\\\
Ciribob's simple slot block. It will block slots for all client airframes\\\
that are on an airfield that does not belong to the faction that currently\\\
owns the airfield. \\\
\\\
REQUIRES CIRIBOB's SIMPLE SLOT BLOCK (SSB) TO RUN ON THE SERVER\\\
\\\
If run without SSB, your planes will not be blocked.\\\
\\\
In order to work, a plane that should be blocked when the airfield or \\\
FARP doesn't belong to the player's faction, the group's first unit\\\
must be within 3000 meters of the airfield and on the ground. \\\
Previous versions of this script relied on group names. No longer.\\\
\\\
\\\
WARNING:\\\
If you modified ssb's flag values, this script will not work \\\
\\\
YOU DO NOT NEED TO ACTIVATE SBB, THIS SCRIPT DOES SO AUTOMAGICALLY\\\
\\\
\\\
--]]--\\\
\\\
-- below value for enabled MUST BE THE SAME AS THE VALUE OF THE SAME NAME \\\
-- IN SSB. DEFAULT IS ZERO, AND THIS WILL WORK\\\
\\\
cfxSSBClient.enabledFlagValue = 0 -- DO NOT CHANGE, MUST MATCH SSB \\\
cfxSSBClient.disabledFlagValue = cfxSSBClient.enabledFlagValue + 100 -- DO NOT CHANGE\\\
cfxSSBClient.allowNeutralFields = false -- set to FALSE if players can't spawn on neutral airfields \\\
cfxSSBClient.maxAirfieldRange = 3000 -- meters to airfield before group is no longer associated with airfield \\\
-- actions to home in on when a player plane is detected and a slot may \\\
-- be blocked. Currently, homing in on airfield, but not fly over \\\
cfxSSBClient.slotActions = {\\\
    \\\"From Runway\\\",\\\
    \\\"From Parking Area\\\",\\\
    \\\"From Parking Area Hot\\\",\\\
    \\\"From Ground Area\\\",\\\
    \\\"From Ground Area Hot\\\",\\\
}\\\
cfxSSBClient.keepInAirGroups = false -- if false we only look at planes starting on the ground \\\
-- setting this to true only makes sense if you plan to bind in-air starts to airfields \\\
\\\
cfxSSBClient.playerGroups = {}\\\
cfxSSBClient.closedAirfields = {} -- list that closes airfields for any aircrafts\\\
cfxSSBClient.playerPlanes = {} -- names of units that a player is flying\\\
cfxSSBClient.crashedGroups = {} -- names of groups to block after crash of their player-flown plane \\\
\\\
\\\
function cfxSSBClient.closeAirfieldNamed(name)\\\
    if not name then return end \\\
    cfxSSBClient.closedAirfields[name] = true \\\
    cfxSSBClient.setSlotAccessByAirfieldOwner()\\\
    if cfxSSBClient.verbose then \\\
        trigger.action.outText(\\\"+++SSB: Airfield \\\" .. name .. \\\" now closed\\\", 30) \\\
    end\\\
end\\\
\\\
function cfxSSBClient.openAirFieldNamed(name)\\\
    cfxSSBClient.closedAirfields[name] = nil \\\
    cfxSSBClient.setSlotAccessByAirfieldOwner()\\\
    if cfxSSBClient.verbose then \\\
        trigger.action.outText(\\\"+++SSB: Airfield \\\" .. name .. \\\" just opened\\\", 30) \\\
    end\\\
end\\\
\\\
function cfxSSBClient.unbindGroup(groupName)\\\
    cfxSSBClient.bindGroupToAirfield(groupName, nil)\\\
end\\\
\\\
function cfxSSBClient.bindGroupToAirfield(groupName, airfieldName)\\\
    if not groupName then return end \\\
    local airfield = nil\\\
    if airfieldName then airfield = Airbase.getByName(airfieldName) end \\\
    for idx, theGroup in pairs(cfxSSBClient.playerGroups) do\\\
        if theGroup.name == groupName then \\\
            if cfxSSBClient.verbose then\\\
                local newBind = \\\"NIL\\\"\\\
                if airfield then newBind = airfieldName end \\\
                trigger.action.outText(\\\"+++SSB: Group \\\" .. theGroup.name .. \\\" changed binding to \\\" .. newBind, 30) \\\
            end\\\
            theGroup.airfield = airfield\\\
            return\\\
        end\\\
    end\\\
    if not airfieldName then airfieldName = \\\"<NIL>\\\" end \\\
    trigger.action.outText(\\\"+++SSB: Binding Group \\\" .. groupName .. \\\" to \\\" .. airfieldName .. \\\" failed.\\\", 30) \\\
end\\\
\\\
\\\
function cfxSSBClient.getClosestAirbaseTo(thePoint)\\\
    local delta = math.huge\\\
    local allYourBase = world.getAirbases() -- get em all\\\
    local closestBase = nil \\\
    for idx, aBase in pairs(allYourBase) do\\\
        -- iterate them all \\\
        local abPoint = aBase:getPoint()\\\
        newDelta = dcsCommon.dist(thePoint, {x=abPoint.x, y = 0, z=abPoint.z})\\\
        if newDelta < delta then \\\
            delta = newDelta\\\
            closestBase = aBase\\\
        end\\\
    end\\\
    return closestBase, delta \\\
end\\\
\\\
function cfxSSBClient.setSlotAccessForGroup(theGroup)\\\
    if not theGroup then return end \\\
    -- WARNING: theGroup is cfxGroup record  \\\
    local theName = theGroup.name \\\
    local theMatchingAirfield = theGroup.airfield \\\
    -- airfield was attached at startup to group \\\
    if cfxSSBClient.singleUse and cfxSSBClient.crashedGroups[theName] then \\\
       -- we don't check, as we know it's blocked after crash \\\
       -- and leave it as it is. Nothing to do at all now\\\
           \\\
    elseif theMatchingAirfield ~= nil then \\\
        -- we have found a plane that is tied to an airfield \\\
        -- so this group will receive a block/unblock\\\
        -- we always set all block/unblock every time\\\
        -- note: since caching, above guard not needed\\\
        local airFieldSide = theMatchingAirfield:getCoalition()\\\
        local groupCoalition = theGroup.coaNum\\\
        local blockState = cfxSSBClient.enabledFlagValue -- we default to ALLOW the block\\\
        local comment = \\\"available\\\"\\\
            \\\
        -- see if airfield is closed \\\
        local afName = theMatchingAirfield:getName()\\\
        if cfxSSBClient.closedAirfields[afName] then \\\
            -- airfield is closed. no take-offs \\\
            blockState = cfxSSBClient.disabledFlagValue\\\
            comment = \\\"!closed airfield!\\\"\\\
        end\\\
            \\\
        -- on top of that, check coalitions\\\
        if groupCoalition ~= airFieldSide then \\\
            -- we have a problem. sides don't match \\\
            if airFieldSide == 3 \\\
            or (cfxSSBClient.allowNeutralFields and airFieldSide == 0)\\\
            then \\\
                -- all is well, airfield is contested or neutral and \\\
                -- we allow this plane to spawn here\\\
            else \\\
                -- DISALLOWED!!!!\\\
                blockState = cfxSSBClient.disabledFlagValue\\\
                comment = \\\"!!!BLOCKED!!!\\\"\\\
            end\\\
        end \\\
        -- set the ssb flag for this group so the server can see it\\\
        trigger.action.setUserFlag(theName, blockState)\\\
        if cfxSSBClient.verbose then \\\
            trigger.action.outText(\\\"+++SSB: group \\\".. theName .. \\\": \\\" .. comment, 30)\\\
        end \\\
    else \\\
        if cfxSSBClient.verbose then \\\
            trigger.action.outText(\\\"+++SSB: group \\\".. theName .. \\\" no bound airfield: available\\\", 30)\\\
        end\\\
    end\\\
end\\\
\\\
function cfxSSBClient.getPlayerGroupForGroupNamed(aName)\\\
    local pGroups = cfxSSBClient.playerGroups\\\
    for idx, theGroup in pairs(pGroups) do\\\
        if theGroup.name == aName then return theGroup end \\\
    end\\\
    return nil \\\
end\\\
\\\
function cfxSSBClient.setSlotAccessByAirfieldOwner()\\\
    -- get all groups that have a player-controlled aircraft\\\
    -- now uses cached, reduced set of player planes\\\
    local pGroups = cfxSSBClient.playerGroups -- cfxGroups.getPlayerGroup() -- we want the group.name attribute\\\
    for idx, theGroup in pairs(pGroups) do\\\
        cfxSSBClient.setSlotAccessForGroup(theGroup)\\\
    end\\\
\\\
end\\\
\\\
function cfxSSBClient.reOpenSlotForGroupNamed(args)\\\
    -- this is merely the timer shell for opening the crashed slot\\\
    gName = args[1]\\\
    cfxSSBClient.openSlotForCrashedGroupNamed(gName)\\\
end\\\
\\\
function cfxSSBClient.openSlotForCrashedGroupNamed(gName)\\\
    if not gName then return end\\\
    local pGroup = cfxSSBClient.getPlayerGroupForGroupNamed(gName)\\\
    if not pGroup then return end \\\
    cfxSSBClient.crashedGroups[gName] = nil -- set to nil to forget this happened \\\
    cfxSSBClient.setSlotAccessForGroup(pGroup) -- set by current occupation status \\\
    if cfxSSBClient.verbose then \\\
        trigger.action.outText(\\\"+++SSBC:SU: re-opened slot for group <\\\" .. gName .. \\\">\\\", 30)\\\
    end \\\
end\\\
\\\
function cfxSSBClient:onEvent(event) \\\
    if event.id == 21 then -- S_EVENT_PLAYER_LEAVE_UNIT\\\
        if cfxSSBClient.verbose then \\\
            trigger.action.outText(\\\"+++SSB: Player leave unit\\\", 30)\\\
        end\\\
        local theUnit = event.initiator\\\
        if not theUnit then\\\
            if cfxSSBClient.verbose then\\\
                trigger.action.outText(\\\"+++SSB: No unit left, abort\\\", 30)\\\
            end\\\
            return \\\
        end \\\
        local curH = theUnit:getLife()\\\
        local maxH = theUnit:getLife0()\\\
        if cfxSSBClient.verbose then\\\
            trigger.action.outText(\\\"+++SSB: Health check: \\\" .. curH .. \\\" of \\\" .. maxH, 30)\\\
        end\\\
        return \\\
    end\\\
    \\\
    if event.id == 10 then -- S_EVENT_BASE_CAPTURED\\\
        if cfxSSBClient.verbose then \\\
            trigger.action.outText(\\\"+++SSB: CAPTURE EVENT -- RESETTING SLOTS\\\", 30)\\\
        end\\\
        cfxSSBClient.setSlotAccessByAirfieldOwner()\\\
    end\\\
\\\
-- write down player names and planes\\\
    if event.id == 15 then\\\
        --trigger.action.outText(\\\"+++SSBC:SU: enter event 15\\\", 30)\\\
        if not event.initiator then return end \\\
        local theUnit = event.initiator -- we know this exists\\\
        local uName = theUnit:getName()\\\
        if not uName then return end \\\
        -- player entered unit\\\
        local playerName = theUnit:getPlayerName()\\\
        if not playerName then \\\
            return -- NPC plane\\\
        end \\\
        -- remember this unit as player controlled plane\\\
        -- because player and plane can easily disconnect\\\
        cfxSSBClient.playerPlanes[uName] = playerName\\\
        if cfxSSBClient.verbose then \\\
            trigger.action.outText(\\\"+++SSBC:SU: noted \\\" .. playerName .. \\\" piloting player unit \\\" .. uName, 30)\\\
        end \\\
        return \\\
    end\\\
    \\\
\\\
    if cfxSSBClient.singleUse and event.id == 5 then -- crash\\\
        if not event.initiator then return end \\\
        local theUnit = event.initiator \\\
        local uName = theUnit:getName()\\\
        if not uName then return end\\\
        local theGroup = theUnit:getGroup()\\\
        if not theGroup then return end \\\
        -- see if a player plane\\\
        local thePilot = cfxSSBClient.playerPlanes[uName]\\\
        if not thePilot then \\\
            -- ignore. not a player plane\\\
            if cfxSSBClient.verbose then \\\
                trigger.action.outText(\\\"+++SSBC:SU: ignored crash for NPC unit <\\\" .. uName .. \\\">\\\", 30)\\\
            end \\\
            return \\\
        end\\\
        -- if we get here, a player-owned plane has crashed \\\
        local gName = theGroup:getName()\\\
        if not gName then return end \\\
        \\\
        -- block this slot. \\\
        trigger.action.setUserFlag(gName, cfxSSBClient.disabledFlagValue)\\\
        \\\
        -- remember this plane to not re-enable if \\\
        -- airfield changes hands later \\\
        cfxSSBClient.crashedGroups[gName] = thePilot -- set to crash pilot \\\
        trigger.action.outText(\\\"+++SSBC:SU: Blocked slot for group <\\\" .. gName .. \\\">\\\", 30)\\\
        \\\
        if cfxSSBClient.reUseAfter > 0 then \\\
            -- schedule re-opening this slot in <x> seconds\\\
            timer.scheduleFunction(\\\
                cfxSSBClient.reOpenSlotForGroupNamed, \\\
                {gName}, \\\
                timer.getTime() + cfxSSBClient.reUseAfter\\\
                )\\\
        end\\\
    end\\\
end\\\
\\\
function cfxSSBClient.update()\\\
    -- first, re-schedule me in one minute \\\
    timer.scheduleFunction(cfxSSBClient.update, {}, timer.getTime() + 60)\\\
    \\\
    -- now establish all slot blocks \\\
    cfxSSBClient.setSlotAccessByAirfieldOwner()\\\
end\\\
\\\
-- pre-process static player data to minimize \\\
-- processor load on checks\\\
function cfxSSBClient.processPlayerData()\\\
    cfxSSBClient.playerGroups = cfxGroups.getPlayerGroup()\\\
    local pGroups = cfxSSBClient.playerGroups\\\
    local filteredPlayers = {}\\\
    for idx, theGroup in pairs(pGroups) do\\\
        if theGroup.airfield ~= nil or cfxSSBClient.keepInAirGroups or \\\
        cfxSSBClient.singleUse then \\\
            -- only transfer groups that have airfields (or also keepInAirGroups or when single-use)\\\
            -- attached. Ignore the rest as they are \\\
            -- always fine\\\
            table.insert(filteredPlayers, theGroup)\\\
        end\\\
    end\\\
    cfxSSBClient.playerGroups = filteredPlayers\\\
end\\\
\\\
-- add airfield information to each player group\\\
function cfxSSBClient.processGroupData()\\\
    local pGroups = cfxGroups.getPlayerGroup() -- we want the group.name attribute\\\
    for idx, theGroup in pairs(pGroups) do\\\
        -- we always use the first player's plane as referenced\\\
        local playerData = theGroup.playerUnits[1]\\\
        local theAirfield = nil\\\
        local delta = -1\\\
        local action = playerData.action \\\
        if not action then action = \\\"<NIL>\\\" end \\\
        -- see if the data has any of the slot-interesting actions\\\
        if dcsCommon.arrayContainsString(cfxSSBClient.slotActions, action ) then \\\
            -- yes, fetch the closest airfield \\\
            theAirfield, delta = cfxSSBClient.getClosestAirbaseTo(playerData.point)\\\
            local afName = theAirfield:getName()\\\
            if cfxSSBClient.verbose then \\\
                trigger.action.outText(\\\"+++SSB: group: \\\" .. theGroup.name .. \\\" closest to AF \\\" .. afName .. \\\": \\\" .. delta .. \\\"m\\\" , 30)\\\
            end \\\
            if delta > cfxSSBClient.maxAirfieldRange then \\\
                -- forget airfield\\\
                 theAirfield = nil\\\
                if cfxSSBClient.verbose then \\\
                    trigger.action.outText(\\\"+++SSB: group: \\\" .. theGroup.name .. \\\" unlinked - too far from airfield\\\" , 30)\\\
                end \\\
            end\\\
            theGroup.airfield = theAirfield\\\
        else \\\
            if cfxSSBClient.verbose then \\\
                trigger.action.outText(\\\"+++SSB: group: \\\" .. theGroup.name .. \\\" start option \\\" .. action .. \\\" does not concern SSB\\\", 30)\\\
            end \\\
        end\\\
    end\\\
end\\\
\\\
--\\\
-- read config zone\\\
--\\\
function cfxSSBClient.readConfigZone()\\\
    -- note: must match exactly!!!!\\\
    local theZone = cfxZones.getZoneByName(\\\"SSBClientConfig\\\") \\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++SSBC: no config zone!\\\", 30) \\\
        return \\\
    end \\\
    \\\
    trigger.action.outText(\\\"+++SSBC: found config zone!\\\", 30) \\\
    \\\
    cfxSSBClient.verbose = cfxZones.getBoolFromZoneProperty(theZone, \\\"verbose\\\", false)\\\
    \\\
    -- single-use\\\
    cfxSSBClient.singleUse = cfxZones.getBoolFromZoneProperty(theZone, \\\"singleUse\\\", false) -- use airframes only once? respawn after kick must be disabled in ssb\\\
    cfxSSBClient.reUseAfter = cfxZones.getNumberFromZoneProperty(theZone, \\\"reUseAfter\\\", -1)\\\
    \\\
    -- airfield availability \\\
    cfxSSBClient.allowNeutralFields = cfxZones.getBoolFromZoneProperty(theZone, \\\"allowNeutralFields\\\", false)\\\
    \\\
    cfxSSBClient.maxAirfieldRange = cfxZones.getNumberFromZoneProperty(theZone, \\\"maxAirfieldRange\\\", 3000) -- meters, to find attached airfield\\\
\\\
    -- optimization \\\
    \\\
    cfxSSBClient.keepInAirGroups = cfxZones.getBoolFromZoneProperty(theZone, \\\"keepInAirGroups\\\", false)\\\
    \\\
    -- SSB direct control. \\\
    -- USE ONLY WHEN YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\\\
    \\\
    cfxSSBClient.enabledFlagValue = cfxZones.getNumberFromZoneProperty(theZone, \\\"enabledFlagValue\\\", 0)\\\
    \\\
    cfxSSBClient.disabledFlagValue = cfxZones.getNumberFromZoneProperty(theZone, \\\"disabledFlagValue\\\", cfxSSBClient.enabledFlagValue + 100)\\\
end\\\
\\\
--\\\
-- start\\\
--\\\
function cfxSSBClient.start()\\\
    -- verify modules loaded \\\
    if not dcsCommon.libCheck(\\\"cfx SSB Client\\\", \\\
        cfxSSBClient.requiredLibs) then\\\
        return false \\\
    end\\\
    \\\
    -- read config zone if present \\\
    cfxSSBClient.readConfigZone()\\\
    \\\
    -- install callback for events in DCS\\\
    world.addEventHandler(cfxSSBClient)\\\
    \\\
    -- process group data to attach airfields \\\
    cfxSSBClient.processGroupData()\\\
    \\\
    -- process player data to minimize effort and build cache\\\
    -- into cfxSSBClient.playerGroups\\\
    cfxSSBClient.processPlayerData()\\\
    \\\
    -- install a timed update just to make sure\\\
    -- and start NOW\\\
    timer.scheduleFunction(cfxSSBClient.update, {}, timer.getTime() + 1)\\\
     \\\
    -- now turn on ssb \\\
    trigger.action.setUserFlag(\\\"SSB\\\",100)\\\
    \\\
    -- say hi!\\\
    trigger.action.outText(\\\"cfxSSBClient v\\\".. cfxSSBClient.version .. \\\" running, SBB enabled\\\", 30)\\\
    \\\
    --cfxSSBClient.allYourBase()\\\
    \\\
    return true \\\
end\\\
\\\
if not cfxSSBClient.start() then \\\
    trigger.action.outText(\\\"cfxSSBClient v\\\".. cfxSSBClient.version .. \\\" FAILED loading.\\\", 30)\\\
    cfxSSBClient = nil\\\
end\\\
\\\
--[[--\\\
  possible improvements: \\\
    - use explicitBlockList that with API. planes on that list are always blocked. Use this for special effects, such as allowing a slot only to open from scripts, e.g. when a condition is met like money or goals reached\\\
   \\\
-]]--\");",
            [2] = "a_do_script(\"nameStats = {}\\\
nameStats.version = \\\"1.1.1\\\"\\\
--[[--\\\
  package that allows generic and global access to data, stored by \\\
  name and path. Can be used to manage score, cargo, statistics etc.\\\
  provides its own root by default, but modules can provide their own \\\
  private roots to be managed the same way.\\\
  \\\
  Uses a path metaphor to access fine grained levels\\\
  \\\
    version history \\\
    1.0.0 - initial release \\\
    1.1.0 - added table to leaf for more general \\\
          - added ability to use arbitrary roots\\\
          - setValue \\\
          - reset\\\
          - getAllPathes\\\
    1.1.1 - simplified strings to a single string \\\
          - left old logic intact for log extensions\\\
          - setString()\\\
    \\\
--]]--\\\
-- statistics container. everything is in here\\\
 \\\
nameStats.stats = {}\\\
\\\
--[[--\\\
    to access data, there are the following principles:\\\
    - name: uniquely defines a branch where all data for this name \\\
            is stored. MANDATORY, MUST NEVER BE nil\\\
            this is usually a unit's name \\\
    - path: in each branch you can have a path (string) to the data \\\
            to more precisely define. for example, you can have separate \\\
            paths 'score' and 'weight' under the same name \\\
            There currently is no logic attached to a path except that\\\
            it must be unique inside the same branch\\\
            OPTIONAL. if omittted, a default data set is returned\\\
    - rootNode: OPTIONAL storage (table) you can pass to create your own \\\
            pricate storage space that can't be accessed unless the \\\
            invoking method also passes the same rootNode \\\
    \\\
    Data \\\
        Data is stored in a \\\"leaf node\\\" that has three properties\\\
        - value: a numerical value that can be set and changed\\\
        - string: a strings that can be set and added to \\\
        - table: a table that you can treat as you like and that     \\\
                 is never looked into nor changed by this module \\\
                 \\\
--]]--\\\
\\\
function nameStats.getAllNames(theRootNode) -- root node is optional\\\
    if not theRootNode then theRootNode = nameStats.stats end  \\\
    local allNames = {}\\\
    for name, entry in pairs(theRootNode) do \\\
        table.insert(allNames, name)\\\
    end\\\
    return allNames\\\
end\\\
\\\
function nameStats.getAllPathes(name, theRootNode)\\\
    if not theRootNode then theRootNode = nameStats.stats end \\\
    local allPathes = {}\\\
    local theEntry = theRootNode[name]\\\
    if not theEntry then \\\
        return allPathes \\\
    end\\\
    \\\
    for pathName, data in pairs(theEntry.data) do \\\
        table.insert(allPathes, pathName)\\\
    end\\\
    \\\
    return allPathes\\\
end\\\
\\\
-- change the numerical value by delta. use negative numbers to decrease\\\
function nameStats.changeValue(name, delta, path, rootNode)\\\
    if not name then return nil end \\\
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\\\
    theLeaf.value = theLeaf.value + delta\\\
    return theLeaf.value \\\
end\\\
\\\
-- set to a specific value \\\
function nameStats.setValue(name, newVal, path, rootNode)\\\
    if not name then return nil end \\\
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\\\
    theLeaf.value = newVal\\\
    return theLeaf.value \\\
end\\\
\\\
-- add a string to the log\\\
function nameStats.addString(name, aString, path, rootNode)\\\
    if not name then return nil end \\\
    if not aString then return nil end \\\
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\\\
    --table.insert(theLeaf.strings, aString)\\\
    theLeaf.strings = theLeaf.strings .. aString\\\
--    return aString\\\
end\\\
\\\
-- reset the log\\\
function nameStats.removeAllString(name, path, rootNode)\\\
    if not name then return nil end \\\
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\\\
--    theLeaf.strings = {}\\\
    theLeaf.strings = \\\"\\\"\\\
end\\\
\\\
function nameStats.setString(name, aString, path, rootNode)\\\
    if not name then return nil end \\\
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\\\
    theLeaf.strings = aString\\\
end\\\
\\\
-- set the table variable\\\
function nameStats.setTable(name, path, aTable, rootNode)\\\
    if not name then return end \\\
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\\\
    theLeaf.theTable = aTable\\\
end\\\
\\\
-- get the numerical value associated with name, path \\\
function nameStats.getValue(name, path, rootNode) -- allocate if not exist\\\
    if not name then return nil end \\\
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\\\
    return theLeaf.value\\\
end\\\
\\\
-- get the log associated with name, path \\\
function nameStats.getStrings(name, path, rootNode)\\\
    if not name then return nil end \\\
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\\\
    return theLeaf.strings\\\
end\\\
\\\
-- alias for compatibility reasons\\\
function nameStats.getString(name, path, rootNode)\\\
    return nameStats.getStrings(name, path, rootNode)\\\
end\\\
\\\
-- get the table stored under name, path.\\\
function nameStats.getTable(name, path, rootNode)\\\
    if not name then return nil end \\\
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\\\
    return theLeaf.theTable\\\
end\\\
\\\
-- reset whatever is stored under name, path\\\
-- WARNING: passing nil path will entirely reset the whole name \\\
function nameStats.reset(name, path, rootNode)\\\
    if not name then return nil end \\\
    if not rootNode then rootNode = nameStats.stats end \\\
    local theEntry = rootNode[name]\\\
    if not theEntry then \\\
        -- does not yet exist, create a root entry\\\
        theEntry = nameStats.createRoot(name)\\\
        rootNode[name] = theEntry\\\
        nameStats.getLeaf(name, path, rootNode) -- will alloc an empty leaf\\\
        return -- done\\\
    end\\\
    if not path then -- will delete everything!!!\\\
        theEntry = nameStats.createRoot(name)\\\
        rootNode[name] = theEntry\\\
        return  \\\
    end \\\
    -- create new leaf and replace existing\\\
    theLeaf = nameStats.createLeaf()\\\
    theEntry.data[path] = theLeaf\\\
        \\\
end\\\
\\\
--\\\
--\\\
-- private function \\\
--\\\
--\\\
function nameStats.getLeaf(name, path, rootNode) \\\
    if not name then return nil end \\\
    if not rootNode then rootNode = nameStats.stats end \\\
    -- will allocate if not existlocal theEntry = nameStats.stats[name]\\\
    local theEntry = rootNode[name]\\\
    if not theEntry then \\\
        -- does not yet exist, create a root entry\\\
        theEntry = nameStats.createRoot(name)\\\
        rootNode[name] = theEntry\\\
    end\\\
    -- from here on, the entry exists \\\
    if not path then return theEntry.defaultLeaf end \\\
    \\\
    -- access via path \\\
    local theLeaf = theEntry.data[path]\\\
    if not theLeaf then \\\
        theLeaf = nameStats.createLeaf()\\\
        theEntry.data[path] = theLeaf\\\
    end\\\
    return theLeaf\\\
end\\\
\\\
function nameStats.createLeaf()\\\
    local theLeaf = {}\\\
    theLeaf.value = 0\\\
    theLeaf.strings = \\\"\\\"\\\
    theLeaf.log = {} -- was strings\\\
    theLeaf.theTable = {}\\\
    return theLeaf\\\
end\\\
\\\
-- for each entry in stats, this is the root container\\\
function nameStats.createRoot(name)\\\
    local theRoot = {} -- all nodes are in here\\\
    theRoot.name = name \\\
    theRoot.data = {} -- dict by path for leafs\\\
    theRoot.defaultLeaf = nameStats.createLeaf()\\\
    return theRoot\\\
end\\\
\\\
-- say hi!\\\
trigger.action.outText(\\\"cf/x NameStats v\\\" .. nameStats.version .. \\\" loaded\\\", 30)\\\
\");a_do_script(\"cargoSuper = {}\\\
cargoSuper.version = \\\"1.1.1\\\"\\\
--[[--\\\
version history\\\
    1.0.0 - initial version\\\
    1.1.0 - removeMassObjectFrom supports name directly for mass object \\\
          - cargoSuper tracks all mass objects \\\
          - deleteMassObject() \\\
          - removeMassObjectFrom supports forget option\\\
          - createMassObject supports auto-gen UUID name \\\
          - removeAllMassForCargo renamed to removeAllMassForCategory\\\
          - category default \\\"cSup!DefCat\\\"\\\
          - getAllCategoriesFor alias for getAllCargos \\\
          - getManifestForCategory alias for getManifestFor\\\
          - removeAllMassFor()\\\
    1.1.1 - deleteMassObject corrected index bug \\\
    \\\
CargoSuper manages weigth for a logical named unit. Weight can be added \\\
to arbitrary categories like 'passengers', 'cargo' or \\\"whatever\\\". In order \\\
to add weight to a unit, first create a massObject through createMassObject\\\
and then add that mass object to the unit via addMassTo, with a category name\\\
you can get access to massobjects via getMassObjects  \\\
When done, you can remove the mass object via removeMassObject or \\\
removeAll\\\
\\\
To get a unit's total weight, use getTotalMass() \\\
\\\
IMPORTANT:\\\
This module does ***N*O*T*** call  trigger.action.setUnitInternalCargo\\\
you must do that yourself\\\
\\\
--]]--\\\
cargoSuper.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- common is of course needed for everything\\\
                 -- pretty stupid to check for this since we \\\
                 -- need common to invoke the check, but anyway\\\
    \\\"nameStats\\\", -- generic data module for weight \\\
}\\\
\\\
cargoSuper.cargos = {}\\\
cargoSuper.massObjects = {}\\\
\\\
-- create a massObject. reference object can be used to store \\\
-- anything that links an associated object:getSampleRate()\\\
-- massName can be anything but must be unique as it is used to store. pass nil for UUID-created name \\\
function cargoSuper.createMassObject(massInKg, massName, referenceObject)\\\
    local theObject = {}\\\
    theObject.mass = massInKg\\\
    theObject.name = massName \\\
    theObject.ref = referenceObject\\\
    \\\
    if not massName then \\\
        massName = dcsCommon.uuid(\\\"cSup!N\\\")\\\
    end\\\
    \\\
    local existingMO = cargoSuper.massObjects[massName]\\\
    if existingMO then \\\
        trigger.action.outText(\\\"+++cSuper: WARNING - \\\" .. massName .. \\\" exists already, overwritten!\\\", 30)\\\
    end\\\
    cargoSuper.massObjects[massName] = theObject\\\
    return theObject\\\
end \\\
\\\
function cargoSuper.deleteMassObject(massObject) \\\
    if not massObject then return end \\\
    local theName = \\\"\\\" \\\
    if type(massObject) == \\\"string\\\" then \\\
        theName = massObject \\\
    else \\\
        theName = massObject.name \\\
    end \\\
    cargoSuper.massObjects[theName] = nil -- 1.1.1 corrected to theName from massName \\\
end\\\
\\\
function cargoSuper.addMassObjectTo(name, category, theMassObject)\\\
    if not theMassObject then return end\\\
    if not category then category = \\\"cSup!DefCat\\\" end \\\
    -- use nameStats to access private data table\\\
    local theMassTable = nameStats.getTable(name, category, cargoSuper.cargos)\\\
    theMassTable[theMassObject.name] = theMassObject\\\
end\\\
\\\
function cargoSuper.removeMassObjectFrom(name, category, theMassObject, forget)\\\
    if not theMassObject then return end\\\
    if not category then category = \\\"cSup!DefCat\\\" end \\\
    if not forget then forget = true end \\\
    -- use nameStats to access private data table\\\
    -- return the data table stored under category. category *can* be nil \\\
    -- v1.0.1 can also provide mass object name \\\
    -- instead of mass object itself. no check!!\\\
    local moName = \\\"\\\"\\\
    if type(theMassObject) == \\\"string\\\" then\\\
        moName = theMassObject\\\
    else \\\
        moName = theMassObject.name \\\
    end\\\
    local theMassTable = nameStats.getTable(name, category, cargoSuper.cargos)\\\
    theMassTable[moName] = nil\\\
    if forget then \\\
        cargoSuper.deleteMassObject(theMassObject)\\\
    end\\\
end\\\
\\\
-- DO NOT PUBLISH. Provided only for backwards compatibility\\\
function cargoSuper.removeAllMassForCargo(name, catergory)\\\
    if not category then category = \\\"cSup!DefCat\\\" end \\\
    nameStats.reset(name, category, cargoSuper.cargos)\\\
end\\\
\\\
-- alias for removeAllMassForCargo\\\
function cargoSuper.removeAllMassForCategory(name, catergory)\\\
    cargoSuper.removeAllMassForCargo(name, catergory)\\\
end\\\
\\\
function cargoSuper.removeAllMassFor(name)\\\
    if not name then return end \\\
    local categories = nameStats.getAllPathes(name, cargoSuper.cargos)\\\
    for idx, cat in pairs(categories) do\\\
        cargoSuper.removeAllMassForCategory(name, cat)\\\
    end\\\
end\\\
\\\
-- returns all cargo categories for name \\\
-- DO NOT PUBLISH. BAD NAMING\\\
function cargoSuper.getAllCargosFor(name)\\\
    local categories = nameStats.getAllPathes(name, cargoSuper.cargos)\\\
    return categories\\\
end\\\
\\\
-- alias for badly named method above\\\
function cargoSuper.getAllCategoriesFor(name)\\\
    cargoSuper.getAllCargosFor(name)\\\
end\\\
\\\
-- return all mass objects that are in name, category as table\\\
-- that can be accessed as *array*\\\
-- DO NOT PUBLISH. NAMING IS BAD\\\
function cargoSuper.getManifestFor(name, category)\\\
    if not category then category = \\\"cSup!DefCat\\\" end \\\
    local theMassTable = nameStats.getTable(name, category, cargoSuper.cargos)\\\
    return dcsCommon.enumerateTable(theMassTable)\\\
end\\\
\\\
-- alias for badly named method above\\\
function cargoSuper.getManifestForCategory(name, category)\\\
    cargoSuper.getManifestFor(name, category)\\\
end\\\
\\\
function getManifestTextFor(name, category, includeTotal)\\\
    if not category then category = \\\"cSup!DefCat\\\" end \\\
    local theMassTable = cargoSuper.getManifestFor(name, category)\\\
    local desc = \\\"\\\"\\\
    local totalMass = 0\\\
    local isFirst = true\\\
    for idx, massObject in pairs(theMassTable) do \\\
        if not isFirst then \\\
            desc = desc .. \\\"\\\\n\\\"\\\
        end\\\
        totalMass = totalMass + massObject.mass\\\
        desc = desc .. massObject.name .. \\\" (\\\" .. massObject.mass .. \\\"kg)\\\"\\\
        isFirst = false\\\
    end    \\\
    if includeTotal and (isFirst == false) then \\\
        -- we only do this if we have at least one (isFirst is false)\\\
        desc = desc .. \\\"\\\\nTotal Weight: \\\" .. totalMass .. \\\"kg\\\"\\\
    end\\\
    return desc\\\
end\\\
\\\
function cargoSuper.calculateTotalMassForCategory(name, category)\\\
    if not category then category = \\\"cSup!DefCat\\\" end \\\
    theMasses = cargoSuper.getManifestFor(name, category)\\\
    local totalMass = 0\\\
    for massName, massObject in pairs(theMasses) do\\\
        totalMass = totalMass + massObject.mass\\\
    end\\\
    return totalMass\\\
end\\\
\\\
function cargoSuper.calculateTotalMassFor(name)\\\
    local allCategories = cargoSuper.getAllCargosFor(name)\\\
    local totalMass = 0\\\
    for idx, category in pairs(allCategories) do \\\
        totalMass = totalMass + cargoSuper.calculateTotalMassForCategory(name, category)\\\
    end    \\\
    return totalMass\\\
end\\\
\\\
function cargoSuper.start()\\\
    -- make sure we have loaded all relevant libraries \\\
    if not dcsCommon.libCheck(\\\"cfx CargoSuper\\\", cargoSuper.requiredLibs) then \\\
        trigger.action.outText(\\\"cf/x CargoSuper aborted: missing libraries\\\", 30)\\\
        return false \\\
    end\\\
    \\\
    trigger.action.outText(\\\"cf/x CargoSuper v\\\" .. cargoSuper.version .. \\\" loaded\\\", 30)\\\
    return true \\\
    \\\
end\\\
\\\
-- go go go \\\
if not cargoSuper.start() then \\\
    cargoSuper = nil\\\
end\");a_do_script(\"-- cfxCommander - issue dcs commands to groups etc\\\
--\\\
-- supports scheduling\\\
-- *** EXTENDS ZONES: 'pathing' attribute \\\
--\\\
cfxCommander = {}\\\
cfxCommander.version = \\\"1.1.2\\\"\\\
--[[-- VERSION HISTORY\\\
 - 1.0.5 - createWPListForGroupToPointViaRoads: detect no road found \\\
 - 1.0.6 - build in more group checks in assign wp list \\\
         - added sanity checks for doScheduledTask\\\
         - assignWPListToGroup now can schedule tasks \\\
         - makeGroupGoThere supports scheduling\\\
         - makeGroupGoTherePreferringRoads supports scheduling \\\
         - scheduleTaskForGroup supports immediate execution\\\
         - makeGroupHalt\\\
 - 1.0.7 - warning if road shorter than direct\\\
         - forceOffRoad option\\\
         - noRoadsAtAll option \\\
 - 1.1.0 - load libs \\\
         - pathing zones. Currently only supports \\\
         - offroad to override road-usage\\\
         - pathing zones are overridden by noRoadsAtAll\\\
         - CommanderConfig zones \\\
 - 1.1.1 - default pathing for pathing zone is normal, not offroad \\\
 - 1.1.2 - makeGroupTransmit \\\
         - makeGroupStopTransmitting\\\
         - verbose check before path warning\\\
         - added delay defaulting for most scheduling functions \\\
--]]--\\\
\\\
cfxCommander.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- common is of course needed for everything\\\
    \\\"cfxZones\\\", -- zones management for pathing zones \\\
}\\\
\\\
cfxCommander.verbose = false \\\
cfxCommander.forceOffRoad = true -- if true, vehicles path follow roads, but may drive offroad (they follow vertex points from path but not the road as they are still commanded 'offroad')\\\
cfxCommander.noRoadsAtAll = true  -- if true, always go direct, overrides forceOffRoad when true. Always a two-point path. Here, there, bang! \\\
cfxCommander.pathZones = {} -- zones that can override road settings\\\
\\\
--\\\
-- path zone\\\
--\\\
function cfxCommander.processPathingZone(aZone) -- process attribute and add to zone\\\
    local pathing = cfxZones.getStringFromZoneProperty(aZone, \\\"pathing\\\", \\\"normal\\\") -- must be \\\"offroad\\\" to force offroad\\\
    pathing = pathing:lower()\\\
    -- currently no validation of attribute \\\
    aZone.pathing = pathing\\\
end \\\
\\\
function cfxCommander.addPathingZone(aZone)\\\
    table.insert(cfxCommander.pathZones, aZone)\\\
end \\\
\\\
function cfxCommander.hasPathZoneFor(here, there)\\\
    for idx, aZone in pairs(cfxCommander.pathZones) do \\\
        if cfxZones.pointInZone(here, aZone) then return aZone end \\\
        if cfxZones.pointInZone(there, aZone) then return aZone end\\\
    end\\\
    return nil\\\
end\\\
\\\
--\\\
-- Config Zone Reading if present \\\
--\\\
function cfxCommander.readConfigZone()\\\
    -- note: must match exactly!!!!\\\
    local theZone = cfxZones.getZoneByName(\\\"CommanderConfig\\\") \\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++cmdr: no config zone!\\\", 30) \\\
        return \\\
    end \\\
    \\\
    trigger.action.outText(\\\"+++cmdr: found config zone!\\\", 30) \\\
    \\\
    cfxCommander.verbose = cfxZones.getBoolFromZoneProperty(theZone, \\\"verbose\\\", false)\\\
    cfxCommander.forceOffRoad = cfxZones.getBoolFromZoneProperty(theZone, \\\"forceOffRoad\\\", false) -- if true, vehicles path follow roads, but may drive offroad\\\
    cfxCommander.noRoadsAtAll = cfxZones.getBoolFromZoneProperty(theZone, \\\"noRoadsAtAll\\\", false)\\\
\\\
end\\\
\\\
--\\\
-- Options are key, value pairs. Scheduler when you are creating groups\\\
-- \\\
\\\
function cfxCommander.doOption(data) \\\
    if cfxCommander.verbose then \\\
        trigger.action.outText(\\\"Commander: setting option \\\" .. data.key .. \\\" --> \\\" .. data.value, 30)\\\
    end\\\
\\\
    local theController = data.group:getController()\\\
    theController:setOption(data.key, data.value)\\\
end\\\
\\\
function cfxCommander.scheduleOptionForGroup(group, key, value, delay) \\\
    local data = {}\\\
    if not delay then delay = 0.1 end \\\
    data.group = group\\\
    data.key = key\\\
    data.value = value \\\
    timer.scheduleFunction(cfxCommander.doOption, data, timer.getTime() + delay)\\\
end\\\
\\\
--\\\
-- performCommand is a special version of issuing a command\\\
-- that can be easily schduled by pushing the commandData on \\\
-- the stack with scheduling it \\\
-- group or name must be filled to get the group,\\\
-- and the command table is what is going to be passed to the setCommand\\\
-- commands are given in an array, so you can stack commands \\\
function cfxCommander.performCommands(commandData)\\\
    -- see if we have a group\\\
    if not commandData.group then \\\
        commandData.group = Group.getByName(commandData.name) -- better be inited!\\\
    end\\\
    -- get the AI\\\
    local theController = commandData.group:getController()\\\
    for i=1, #commandData.commands do\\\
        if cfxCommander.verbose then \\\
            trigger.action.outText(\\\"Commander: performing \\\" .. commandData.commands[i].id, 30)\\\
        end\\\
        theController:setCommand(commandData.commands[i])\\\
    end\\\
    \\\
    return nil -- a timer called us, so we return no desire to be rescheduled\\\
end\\\
\\\
function cfxCommander.scheduleCommands(data, delay)\\\
    if not delay then delay = 1 end \\\
    timer.scheduleFunction(cfxCommander.performCommands, data, timer.getTime() + delay)\\\
end\\\
\\\
function cfxCommander.scheduleSingleCommand(group, command, delay) \\\
    if not delay then delay = 1 end \\\
    local data = createCommandDataTableFor(group)\\\
    cfxCommander.addCommand(data, command)\\\
    cfxCommander.scheduleCommands(data, delay)\\\
end\\\
\\\
\\\
function cfxCommander.createCommandDataTableFor(group, name)\\\
    local cD = {}\\\
    if not group then \\\
        cD.name = name\\\
    else\\\
        cD.group = group\\\
    end\\\
    cD.commands={}\\\
    return cD\\\
end\\\
\\\
function cfxCommander.addCommand(theCD, theCommand)\\\
    if not theCD then return end \\\
    if not theCommand then return end \\\
    \\\
    table.insert(theCD.commands, theCommand)\\\
end\\\
\\\
function cfxCommander.createSetFrequencyCommand(freq, modulator)\\\
    local theCmd = {}\\\
    if not freq then freq = 100 end \\\
    if not modulator then modulator = 0 end -- AM = 0, default\\\
    theCmd.id = 'SetFrequency'\\\
    theCmd.params = {}\\\
    theCmd.params.frequency = freq * 10000 -- 88 --> 880000. 124 --> 1.24 MHz\\\
    theCmd.params.modulation = modulator\\\
    return theCmd\\\
end\\\
\\\
-- oneShot is optional. if present and anything but false, will cause message to \\\
-- me sent only once, no loops\\\
function cfxCommander.createTransmissionCommand(filename, oneShot)\\\
    local looping = true\\\
    if not filename then filename = \\\"dummy\\\" end \\\
    if oneShot then looping = false end\\\
    local theCmd = {}\\\
    theCmd.id = 'TransmitMessage'\\\
    theCmd.params = {}\\\
    theCmd.params.loop = looping\\\
    theCmd.params.file = \\\"l10n/DEFAULT/\\\" .. filename -- need to prepend the resource string\\\
    return theCmd\\\
end\\\
\\\
function cfxCommander.createStopTransmissionCommand()\\\
    local theCmd = {}\\\
    theCmd.id = 'stopTransmission'\\\
    theCmd.params = {}\\\
    return theCmd\\\
end\\\
\\\
--\\\
-- tasks\\\
-- \\\
\\\
function cfxCommander.doScheduledTask(data) \\\
    if cfxCommander.verbose then \\\
        trigger.action.outText(\\\"Commander: setting task \\\" .. data.task.id .. \\\" for group \\\" .. data.group:getName(), 30)\\\
    end\\\
    local theGroup = data.group \\\
    if not theGroup then return end \\\
    if not theGroup.isExist then return end\\\
    \\\
    local theController = theGroup:getController()\\\
    theController:pushTask(data.task)\\\
end\\\
\\\
function cfxCommander.scheduleTaskForGroup(group, task, delay)\\\
    if not delay then delay = 0 end \\\
    local data = {}\\\
    data.group = group\\\
    data.task = task\\\
    if delay < 0.001 then \\\
        cfxCommander.doScheduledTask(data) -- immediate execution\\\
        return \\\
    end\\\
    timer.scheduleFunction(cfxCommander.doScheduledTask, data, timer.getTime() + delay)\\\
end\\\
\\\
function cfxCommander.createAttackGroupCommand(theGroupToAttack)\\\
    local task = {}\\\
    task.id = 'AttackGroup'\\\
    task.params = {}\\\
    task.params.groupID = theGroupToAttack:getID()\\\
    return task\\\
end\\\
\\\
function cfxCommander.createEngageGroupCommand(theGroupToAttack)\\\
    local task = {}\\\
    task.id = 'EngageGroup'\\\
    task.params = {}\\\
    task.params.groupID = theGroupToAttack:getID()\\\
    return task\\\
end\\\
\\\
--\\\
-- waypoints, routes etc \\\
--\\\
\\\
-- basic waypoint is for ground units. point can be xyz or xy \\\
function cfxCommander.createBasicWaypoint(point, speed, formation)\\\
    local wp = {}\\\
    wp.x = point.x\\\
    -- support xyz and xy format\\\
    if point.z then \\\
        wp.y = point.z\\\
    else\\\
        wp.y = point.y\\\
    end\\\
    \\\
    if not speed then speed = 6 end -- 6 m/s = 20 kph\\\
    wp.speed = speed \\\
    \\\
    if cfxCommander.forceOffRoad then \\\
        formation = \\\"Off Road\\\"\\\
    end\\\
    \\\
    if not formation then formation = \\\"Off Road\\\" end\\\
    -- legal formations:\\\
    -- Off road\\\
    -- On Road -- second letter upper case?\\\
    -- Cone \\\
    -- Rank\\\
    -- Diamond\\\
    -- Vee\\\
    -- EchelonR\\\
    -- EchelonL\\\
    wp.action = formation -- silly name, but that's how ME does it\\\
    wp.type = 'Turning Point'\\\
    return wp\\\
\\\
end\\\
\\\
function cfxCommander.buildTaskFromWPList(wpList)\\\
    -- build the task that will make a group follow the WP list\\\
    -- we do this by creating a \\\"Mission\\\" task around the WP List\\\
    -- WP list is consumed by this action\\\
    local missionTask = {}\\\
    missionTask.id = \\\"Mission\\\"\\\
    missionTask.params = {}\\\
    missionTask.params.route = {}\\\
    missionTask.params.route.points=wpList\\\
    return missionTask\\\
end\\\
\\\
function cfxCommander.assignWPListToGroup(group, wpList, delay)\\\
    if not delay then delay = 0 end \\\
    if not group then return end \\\
    if type(group) == 'string' then -- group name, nice mist trick \\\
        group = Group.getByName(group)\\\
    end\\\
    if not group then return end \\\
    if not group:isExist() then return end \\\
    \\\
    local theTask = cfxCommander.buildTaskFromWPList(wpList)\\\
    local ctrl = group:getController()\\\
\\\
--[[--\\\
    if delay < 0.001 then -- immediate action\\\
        if ctrl then\\\
            ctrl:setTask(theTask)\\\
        end\\\
    else \\\
        -- delay execution of this command by the specified amount \\\
        -- of seconds \\\
        cfxCommander.scheduleTaskForGroup(group, theTask, delay)\\\
    end\\\
--]]--\\\
    cfxCommander.scheduleTaskForGroup(group, theTask, delay)\\\
end\\\
\\\
function cfxCommander.createWPListForGroupToPoint(group, point, speed, formation)\\\
    if type(group) == 'string' then -- group name\\\
        group = Group.getByName(group)\\\
    end\\\
\\\
    local wpList = {}\\\
    -- here we are, and we want to go there. In DCS, this means that\\\
    -- we need to create a wp list consisting of here and there\\\
    local here = dcsCommon.getGroupLocation(group)\\\
    local wpHere = cfxCommander.createBasicWaypoint(here, speed, formation)\\\
    local wpThere = cfxCommander.createBasicWaypoint(point, speed, formation)\\\
    wpList[1] = wpHere\\\
    wpList[2] = wpThere\\\
    return wpList\\\
end\\\
\\\
-- make a ground units group head to a waypoint by replacing the entire mission\\\
-- with a two-waypoint lsit from (here) to there at speed and formation. formation\\\
-- default is 'off road'\\\
function cfxCommander.makeGroupGoThere(group, there, speed, formation, delay)\\\
    if not delay then delay = 0 end \\\
    if type(group) == 'string' then -- group name\\\
        group = Group.getByName(group)\\\
    end\\\
    local wp = cfxCommander.createWPListForGroupToPoint(group, there, speed, formation)\\\
    \\\
    cfxCommander.assignWPListToGroup(group, wp, delay)\\\
end\\\
\\\
function cfxCommander.calculatePathLength(roadPoints)\\\
    local totalLen = 0\\\
    if #roadPoints < 2 then return 0 end\\\
    for i=1, #roadPoints-1 do\\\
        totalLen = totalLen + dcsCommon.dist(roadPoints[i], roadPoints[i+1])\\\
    end\\\
    return totalLen\\\
end\\\
\\\
-- make ground units go from here (group location) to there, using roads if possible\\\
function cfxCommander.createWPListForGroupToPointViaRoads(group, point, speed)\\\
    if type(group) == 'string' then -- group name\\\
        group = Group.getByName(group)\\\
    end\\\
\\\
    local wpList = {}\\\
    -- here we are, and we want to go there. In DCS, this means that\\\
    -- we need to create a wp list consisting of here and there\\\
    -- when going via roads, we add to more wayoints:\\\
    -- go on-roads and leaveRoads. \\\
    -- only if we can get these two additional points, we do that, else we \\\
    -- fall back to direct route \\\
    \\\
    local here = dcsCommon.getGroupLocation(group)\\\
\\\
    -- now generate a list of all points from here to there that uses roads\\\
    local rawRoadPoints = land.findPathOnRoads('roads', here.x, here.z, point.x, point.z)\\\
    -- this is the entire path. calculate the length and make \\\
    -- sure that path on-road isn't more than twice as long \\\
    -- that can happen if a bridge is out or we need to go around a hill\\\
    if not rawRoadPoints or #rawRoadPoints<3 then \\\
        trigger.action.outText(\\\"+++ no roads leading there. Taking direct approach\\\", 30)\\\
        return cfxCommander.createWPListForGroupToPoint(group, point, speed)\\\
    end\\\
    \\\
    local pathLength = cfxCommander.calculatePathLength(rawRoadPoints)\\\
    local direct = dcsCommon.dist(here, point)\\\
    if pathLength < direct and cfxCommander.verbose then \\\
        trigger.action.outText(\\\"+++dcsC: WARNING road path (\\\" .. pathLength .. \\\") shorter than direct route(\\\" .. direct .. \\\"), will not path correctly\\\", 30)\\\
    end\\\
    \\\
    if pathLength > (2 * direct) then \\\
        -- road takes too long, take direct approach\\\
        --trigger.action.outText(\\\"+++ road path (\\\" .. pathLength .. \\\") > twice direct route(\\\" .. direct .. \\\"), commencing direct off-road\\\", 30)\\\
        return cfxCommander.createWPListForGroupToPoint(group, point, speed)\\\
    end\\\
    \\\
    --trigger.action.outText(\\\"+++ \\\".. group:getName() .. \\\": choosing road path l=\\\" .. pathLength .. \\\" over direct route d=\\\" .. direct, 30)\\\
    \\\
    -- if we are here, the road trip is valid \\\
    for idx, wp in pairs(rawRoadPoints) do \\\
        -- createBasic... supports w.xy format\\\
        local theNewWP = cfxCommander.createBasicWaypoint(wp, speed, \\\"On Road\\\") -- force off road for better compatibility?\\\
        table.insert(wpList, theNewWP)\\\
    end\\\
    \\\
    \\\
    \\\
    -- now make first and last entry OFF Road\\\
    local wpc = wpList[1]\\\
    wpc.action = \\\"Off Road\\\"\\\
    wpc = wpList[#wpList]\\\
    wpc.action = \\\"Off Road\\\"\\\
\\\
    return wpList\\\
end\\\
\\\
function cfxCommander.makeGroupGoTherePreferringRoads(group, there, speed, delay)\\\
    if type(group) == 'string' then -- group name\\\
        group = Group.getByName(group)\\\
    end\\\
    if not delay then delay = 0 end \\\
\\\
\\\
    if cfxCommander.noRoadsAtAll then \\\
        -- we don't even follow roads, completely forced off\\\
        cfxCommander.makeGroupGoThere(group, there, speed, \\\"Off Road\\\", delay)\\\
        return \\\
    end\\\
\\\
    -- see if we have an override situation \\\
    -- for one of the two points where a pathing Zone \\\
    -- overrides the roads setting \\\
    if #cfxCommander.pathZones > 0 then  \\\
        local here = dcsCommon.getGroupLocation(group)\\\
        local oRide = cfxCommander.hasPathZoneFor(here, there)\\\
        if oRide and oRide.pathing == \\\"offroad\\\" then \\\
            -- yup, override road preference\\\
            cfxCommander.makeGroupGoThere(group, there, speed, \\\"Off Road\\\", delay)\\\
            --trigger.action.outText(\\\"pathing: override offroad\\\")\\\
            return \\\
        end\\\
    end\\\
\\\
    -- viaRoads will only use roads if the road trip isn't more than twice \\\
    -- as long as the direct route \\\
    local wp = cfxCommander.createWPListForGroupToPointViaRoads(group, there, speed)\\\
    cfxCommander.assignWPListToGroup(group, wp, delay)\\\
end\\\
\\\
\\\
function cfxCommander.makeGroupHalt(group, delay)\\\
    if not group then return end \\\
    if not group:isExist() then return end \\\
    if not delay then delay = 0 end \\\
    local theTask = {id = 'Hold', params = {}}\\\
    cfxCommander.scheduleTaskForGroup(group, theTask, delay)\\\
end\\\
\\\
function cfxCommander.makeGroupTransmit(group, tenKHz, filename, oneShot, delay)\\\
    if not group then return end \\\
    if not tenKHz then tenKHz = 20 end -- default to 200KHz\\\
    if not delay then delay = 1.0 end \\\
    if not filename then return end \\\
    if not oneShot then oneShot = false end \\\
    \\\
    -- now build the transmission command\\\
    local theCommands = cfxCommander.createCommandDataTableFor(group)\\\
    local cmd = cfxCommander.createSetFrequencyCommand(tenKHz) -- freq in 10000 Hz\\\
    cfxCommander.addCommand(theCommands, cmd)\\\
    cmd = cfxCommander.createTransmissionCommand(filename, oneShot)\\\
    cfxCommander.addCommand(theCommands, cmd)\\\
    cfxCommander.scheduleCommands(theCommands, delay)\\\
end \\\
\\\
function cfxCommander.makeGroupStopTransmitting(group, delay)\\\
    if not delay then delay = 1 end \\\
    if not group then return end \\\
    local theCommands = cfxCommander.createCommandDataTableFor(group)\\\
    local cmd = cfxCommander.createStopTransmissionCommand()\\\
    cfxCommander.addCommand(theCommands, cmd)\\\
    cfxCommander.scheduleCommands(theCommands, delay)\\\
end\\\
\\\
\\\
function cfxCommander.start()\\\
    -- make sure we have loaded all relevant libraries \\\
    if not dcsCommon.libCheck(\\\"cfx Commander\\\", cfxCommander.requiredLibs) then \\\
        trigger.action.outText(\\\"cf/x Commander aborted: missing libraries\\\", 30)\\\
        return false \\\
    end\\\
    \\\
    -- identify and process all 'pathing' zones\\\
    local pathZones = cfxZones.getZonesWithAttributeNamed(\\\"pathing\\\")\\\
    \\\
    -- now create a spawner for all, add them to the spawner updater, and spawn for all zones that are not\\\
    -- paused \\\
    for k, aZone in pairs(pathZones) do \\\
        cfxCommander.processPathingZone(aZone) -- process attribute and add to zone\\\
        cfxCommander.addPathingZone(aZone) -- remember it so we can smoke it\\\
    end\\\
    \\\
    -- read config overides \\\
    cfxCommander.readConfigZone()\\\
    \\\
    return true\\\
end\\\
\\\
if cfxCommander.start() then \\\
    trigger.action.outText(\\\"cfxCommander v\\\" .. cfxCommander.version .. \\\" loaded\\\", 30)\\\
else \\\
    trigger.action.outText(\\\"+++cfxCommander load FAILED\\\", 30)\\\
    cfxCommander = nil\\\
end\\\
\\\
--[[-- known issues\\\
\\\
- troops remain motionless until all are repaired or produced after cature\\\
- long roads / roads not taken in persia \\\
- all troops red and blue become motionless when one zone is occupied\\\
- after capture, the troop capturing remains, all others can go on. one will always remain there \\\
- rethink the factor to add to road, and simply add 100m \\\
\\\
 TODO: break long distances into smaller paths, and gravitate towards pathing zones if they have a 'gravitate' or similar attribute \\\
--]]--\\\
\");a_do_script(\"csarManager = {}\\\
csarManager.version = \\\"2.0.3\\\"\\\
--[[-- VERSION HISTORY\\\
 - 1.0.0 initial version \\\
 - 1.0.1 - smoke optional \\\
         - airframeCrashed method for airframe manager \\\
         - removed '(downed )' when re-picked up \\\
         - fixed oclock\\\
 - 1.0.2 - hover retrieval \\\
 - 1.0.3 - corrected a bug in oclock during hovering \\\
 - 1.0.4 - now correctly allocates pilot to coalition via dcscommon.coalition2county\\\
 - 1.1.0 - pilot adds weight to unit \\\
         - module check \\\
 - 2.0.0 - weight managed via cargoSuper\\\
 - 2.0.1 - getCSARBaseforZone()\\\
         - check if zone landed in has owner attribute \\\
           to provide compatibility with owned zones, \\\
           FARPZones etc that keep zone.owner up to date \\\
 - 2.0.2 - use parametric csarManager.hoverAlt\\\
         - use hoverDuration\\\
 - 2.0.3 - corrected bug in hoverDuration\\\
 - 2.0.4 - guard in createCSARMission for cfxCommander \\\
 \\\
--]]--\\\
-- modules that need to be loaded BEFORE I run \\\
csarManager.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- common is of course needed for everything\\\
    \\\"cfxZones\\\", -- zones management foc CSAR and CSAR Mission zones\\\
    \\\"cfxPlayer\\\", -- player monitoring and group monitoring \\\
    \\\"nameStats\\\", -- generic data module for weight \\\
    \\\"cargoSuper\\\",\\\
--    \\\"cfxCommander\\\", -- needed if you want to hand-create CSAR missions\\\
}\\\
\\\
-- *** DOES NOT EXTEND ZONES *** BUT USES OWN STRUCT \\\
\\\
--[[--\\\
    CSAR MANAGER\\\
    ============\\\
\\\
 This module can create and manage CSAR missions, i.e. \\\
 create a unit on the ground, mark it on the map, handle\\\
 if the unit is killed, create enemies in the vicinity \\\
 \\\
 It will install a menu in any troop helicopter as\\\
 determined by dcsCommon.isTroopCarrier() with the \\\
 option to list available csar mission. for each created mission\\\
 it will give range and frequency for ADF\\\
 When a helicopter is in range, it will set smoke to better \\\
 visually identify the location. \\\
 \\\
 When the helicopter lands close enough to a downed pilot,\\\
 the pilot is picket up automatically. Their weight is added\\\
 to the unit, so it may overload!\\\
 \\\
 When the helicopter than lands in a CSARBASE Zone, the mission is \\\
 a success and a success callback is invoked automatically for \\\
 all picked up groups. All zones that have the CSARBASE property are\\\
 CSAR Bases, but their coalition must be either neutral or match the \\\
 one of the unit that landed\\\
 \\\
 On start, it scans all zones for a CSAR property, and creates\\\
 a CSAR mission with data taken from the properties in the \\\
 zone so you can easily create CSAR missions in ME\\\
 \\\
 WARNING: ASSUMES SINGLE UNIT PLAYER GROUPS\\\
 ==========================================\\\
\\\
 Main Interface\\\
 - createCSARMission(location, side, numCrew, mark, clearing, timeout)\\\
   creates a csar mission that can be tracked. \\\
   location is the position on the map\\\
   side is the side the unit is on (neutal is for any side)\\\
   numCrew the number of people (1-4)\\\
   mark true if marked on map \\\
   clearing will create a clearing \\\
   timeout - time in seconds until pilots die. timer stops on pickup\\\
   RETURNS true, \\\"ok\\\" --  false, \\\"fail reason\\\" (string)\\\
\\\
 - createCSARAdversaries(location, side, numEnemies, radius, maxRadius)\\\
   creates some random infantery randomized on a circle around the location \\\
   location - center, usually where the downed pilot is\\\
   side - side of the enemy red/blue\\\
   numEnemies - number of infantry \\\
   radius[, maxRadius] distance of the enemy troops\\\
\\\
 - in ME, create at least one zone with a property named \\\"CSARBASE\\\" for \\\
   each side that supports csar missions. This is where the players \\\
   can drop off pilots that they rescued. If you have no CSARBASE zone \\\
   defined, you'll receive a warning for that side when you attempt a \\\
   rescue\\\
   \\\
 - in ME you can place zones with a CSAR attribute that will generate \\\
   a scar mission. Further attributes are \\\"coalition\\\" (red/blue), \\\"name\\\" (any name you like) and \\\"freq\\\" (for elt ADR, leave empty for random)\\\
   \\\
   NOTE:\\\
     CSARBASE is compatible with the FARP Attribute of \\\
     FARP Zones \\\
     \\\
   \\\
--]]--\\\
--\\\
-- OPTIONS\\\
--\\\
csarManager.useSmoke = false -- smoke is a performance killer, so you can turn it off \\\
\\\
\\\
-- unitConfigs contain the config data for any helicopter\\\
-- currently in the game. The Array is indexed by unit name \\\
csarManager.unitConfigs = {}\\\
csarManager.myEvents = {3, 4, 5} -- 3 = take off, 4 = land, 5 = crash\\\
\\\
--\\\
-- CASR MISSION\\\
--\\\
csarManager.openMissions = {} -- all currently available missions\\\
csarManager.csarBases = {} -- all bases where we can drop off rescued pilots\\\
\\\
csarManager.missionID = 1 -- to create uuid\\\
csarManager.rescueRadius = 70 -- must land within 50m to rescue\\\
csarManager.hoverRadius = 30 -- must hover within 10m of unit \\\
csarManager.hoverAlt = 40 -- must hover below this alt \\\
csarManager.hoverDuration = 20 -- must hover for this duration\\\
csarManager.rescueTriggerRange = 2000 -- when the unit pops smoke and radios\\\
csarManager.beaconSound = \\\"Radio_beacon_of_distress_on_121,5_MHz.ogg\\\"\\\
csarManager.pilotWeight = 120 -- kg for the rescued person. added to the unit's weight\\\
--\\\
-- callbacks\\\
-- \\\
csarManager.csarCompleteCB = {}\\\
\\\
--\\\
-- CREATING A CSAR \\\
--\\\
function csarManager.createDownedPilot(theMission)\\\
    if not cfxCommander then \\\
        trigger.action.outText(\\\"+++CSAR: can't create mission, module cfxCommander is missing.\\\", 30)\\\
        return \\\
    end\\\
    \\\
    local aLocation = {}\\\
    local aHeading = 0 -- in rads\\\
    local newTargetZone = theMission.zone\\\
    aLocation, aHeading = dcsCommon.randomPointOnPerimeter(newTargetZone.radius / 2 + 3, newTargetZone.point.x, newTargetZone.point.z) \\\
\\\
    local theBoyGroup = dcsCommon.createSingleUnitGroup(theMission.name, \\\
                            \\\"Soldier M4 GRG\\\", -- \\\"Soldier M4 GRG\\\",\\\
                            aLocation.x, \\\
                            aLocation.z, \\\
                            -aHeading + 1.5) -- + 1.5 to turn inwards\\\
    \\\
    -- WARNING:\\\
    -- coalition.addGroup takes the COUNTRY of the group, and derives the \\\
    -- coalition from that. So if mission.sie is 0, we use UN, if it is 1 (red) it\\\
    -- is joint red, if 2 it is joint blue \\\
    local theSideCJTF = dcsCommon.coalition2county(theMission.side) -- get the correct county CJTF \\\
    theMission.group = coalition.addGroup(theSideCJTF, \\\
                                          Group.Category.GROUND, \\\
                                          theBoyGroup)\\\
    \\\
    if theBoyGroup then \\\
--        trigger.action.outText(\\\"+++csar: created csar!\\\", 30)\\\
    else \\\
        trigger.action.outText(\\\"+++csar: FAILED to create csar!\\\", 30)\\\
    end\\\
    \\\
    \\\
    -- we now use commands to send radio transmissions\\\
    local ADF = 20 + math.random(90)\\\
    if theMission.freq then ADF = theMission.freq else theMission.freq = ADF end \\\
    local theCommands = cfxCommander.createCommandDataTableFor(theMission.group)\\\
    local cmd = cfxCommander.createSetFrequencyCommand(ADF) -- freq in 10000 Hz\\\
    cfxCommander.addCommand(theCommands, cmd)\\\
    cmd = cfxCommander.createTransmissionCommand(csarManager.beaconSound)\\\
    cfxCommander.addCommand(theCommands, cmd)\\\
    cfxCommander.scheduleCommands(theCommands, 2) -- in 2 seconds, so unit has time to percolate through DCS\\\
end\\\
\\\
function csarManager.createCSARMissionData(point, theSide, freq, name, numCrew, timeLimit, mapMarker)\\\
    -- create a type \\\
    if not timeLimit then timeLimit = -1 end\\\
    if not point then return nil end \\\
    local newMission = {}\\\
    newMission.side = theSide\\\
    if dcsCommon.stringStartsWith(name, \\\"(downed) \\\") then \\\
        -- remove \\\"downed\\\" - it will be added again later\\\
        name = dcsCommon.removePrefix(name, \\\"(downed) \\\")\\\
    end\\\
    \\\
    newMission.name = \\\"(downed) \\\" .. name .. \\\"-\\\" .. csarManager.missionID -- make it uuid-capable\\\
    newMission.zone = cfxZones.createSimpleZone(newMission.name, point, csarManager.rescueRadius)\\\
    newMission.marker = mapMarker -- so it can be removed later\\\
    newMission.isHot = false -- creating adversaries will make it hot, or when units are near. maybe implement a search later?\\\
    -- detection and load stuff\\\
    newMission.lastSmokeTime = -1000 -- so it will smoke immediately \\\
    newMission.messagedUnits = {} -- so we remember whom the unit radioed\\\
    newMission.hoveringUnits = {} -- used when hovering \\\
    newMission.freq = freq -- if nil will make random \\\
            \\\
    -- allocate units\\\
    csarManager.createDownedPilot(newMission)\\\
    \\\
    -- update counter and return\\\
    csarManager.missionID = csarManager.missionID + 1\\\
    return newMission\\\
end\\\
\\\
function csarManager.addMission(theMission)\\\
    table.insert(csarManager.openMissions, theMission)\\\
end\\\
\\\
function csarManager.removeMission(theMission)\\\
    if not theMission then return end \\\
    local newMissions = {}\\\
    for idx, aMission in pairs (csarManager.openMissions) do\\\
        if aMission ~= theMission then \\\
            table.insert(newMissions, aMission)\\\
        else \\\
        end\\\
    end\\\
    csarManager.openMissions = newMissions -- this is the new batch\\\
end\\\
\\\
function csarManager.removeMissionForGroup(theDownedGroup)\\\
    if not theDownedGroup then return end \\\
    local newMissions = {}\\\
    for idx, aMission in pairs (csarManager.openMissions) do\\\
        if aMission.group ~= theDownedGroup then \\\
            table.insert(newMissions, aMission)\\\
        else \\\
        end\\\
    end\\\
    csarManager.openMissions = newMissions -- this is the new batch\\\
end\\\
--\\\
-- UNIT CONFIG \\\
--\\\
function csarManager.resetConfig(conf)\\\
    -- reset only ovberwrites mission-relevant data\\\
    conf.troopsOnBoard = {} -- number of rescued missions\\\
    local myName = conf.name\\\
    cargoSuper.removeAllMassForCargo(myName, \\\"Evacuees\\\") -- will allocate new empty table \\\
    conf.currentState = -1 -- indetermined, 0 = landed 1 = airborne\\\
    conf.timeStamp = timer.getTime()\\\
end\\\
\\\
function csarManager.createDefaultConfig(theUnit)\\\
    local conf = {}\\\
    conf.theUnit = theUnit \\\
    conf.name = theUnit:getName()\\\
    csarManager.resetConfig(conf)\\\
    --conf.unit = {} -- the unit this is linked to\\\
    conf.myMainMenu = nil -- this is the main menu for group\\\
    conf.myCommands = nil -- all commands in sub menu\\\
    conf.id = theUnit:getID()\\\
    return conf \\\
end\\\
\\\
\\\
function csarManager.getUnitConfig(theUnit) -- will create new config if not existing\\\
    if not theUnit then\\\
        trigger.action.outText(\\\"+++csar: nil unit in get config!\\\", 30)\\\
        return nil \\\
    end\\\
    local uName = theUnit:getName()\\\
    local c = csarManager.getConfigForUnitNamed(uName)\\\
    if not c then \\\
        c = csarManager.createDefaultConfig(theUnit)\\\
        csarManager.unitConfigs[uName] = c \\\
    end\\\
    return c \\\
end\\\
\\\
function csarManager.getConfigForUnitNamed(aName)\\\
    return csarManager.unitConfigs[aName]\\\
end\\\
\\\
\\\
function csarManager.removeConfigForUnitNamed(aName) \\\
    if not aName then return end \\\
    if csarManager.unitConfigs[aName] then csarManager.unitConfigs[aName] = nil end\\\
end\\\
\\\
--\\\
-- E V E N T   H A N D L I N G \\\
-- \\\
function csarManager.isInteresting(eventID) \\\
    -- return true if we are interested in this event, false else \\\
    for key, evType in pairs(csarManager.myEvents) do \\\
        if evType == eventID then return true end\\\
    end\\\
    return false \\\
end\\\
\\\
function csarManager.preProcessor(event)\\\
    -- make sure it has an initiator\\\
    if not event.initiator then return false end -- no initiator \\\
    local theUnit = event.initiator \\\
    local cat = theUnit:getCategory()\\\
    if cat ~= Unit.Category.HELICOPTER then \\\
        return false \\\
    end\\\
    \\\
    --trigger.action.outText(\\\"+++csar: event \\\" .. event.id .. \\\" for cat = \\\" .. cat .. \\\" (helicopter?)  unit \\\" .. theUnit:getName(), 30)\\\
    \\\
    if not cfxPlayer.isPlayerUnit(theUnit) then \\\
        --trigger.action.outText(\\\"+++csar: rejected event: \\\" .. theUnit:getName() .. \\\" not a player helo\\\", 30)\\\
        return false \\\
    end -- not a player unit\\\
    return csarManager.isInteresting(event.id) \\\
end\\\
\\\
function csarManager.postProcessor(event)\\\
    -- don't do anything for now\\\
end\\\
\\\
function csarManager.somethingHappened(event)\\\
    -- when this is invoked, the preprocessor guarantees that\\\
    -- it's an interesting event\\\
    -- unit is valid and player \\\
    -- airframe category is helicopter \\\
    local theUnit = event.initiator\\\
    local ID = event.id\\\
    \\\
    local myType = theUnit:getTypeName()\\\
--    trigger.action.outText(\\\"+++csar: event \\\" .. ID .. \\\" for player unit \\\" .. theUnit:getName() .. \\\" of type \\\" .. myType, 30)\\\
    \\\
    if ID == 4 then  -- landed\\\
        csarManager.heloLanded(theUnit)\\\
    end\\\
    \\\
    if ID == 3 then -- take off\\\
        csarManager.heloDeparted(theUnit)\\\
    end\\\
    \\\
    if ID == 5 then -- crash \\\
        csarManager.heloCrashed(theUnit)\\\
    end\\\
    \\\
    csarManager.setCommsMenu(theUnit)\\\
end\\\
\\\
--\\\
--\\\
-- CSAR LANDED\\\
--\\\
--\\\
\\\
function csarManager.successMission(who, where, theMission)\\\
    trigger.action.outTextForCoalition(theMission.side,\\\
        who .. \\\" successfully evacuated \\\" .. theMission.name .. \\\" to \\\" .. where .. \\\"!\\\", \\\
        30)\\\
    \\\
    -- now call callback for coalition side \\\
    -- callback has format callback(coalition, success true/false, numberSaved, descriptionText)\\\
    \\\
    for idx, callback in pairs(csarManager.csarCompleteCB) do \\\
        callback(theMission.side, true, 1, \\\"test\\\")\\\
    end\\\
    trigger.action.outSoundForCoalition(theMission.side, \\\"Quest Snare 3.wav\\\")\\\
end\\\
\\\
function csarManager.heloLanded(theUnit)\\\
    -- when we have landed, \\\
    if not dcsCommon.isTroopCarrier(theUnit) then return end\\\
    local conf = csarManager.getUnitConfig(theUnit)\\\
    conf.unit = theUnit\\\
    local theGroup = theUnit:getGroup()\\\
    conf.id = theGroup:getID()\\\
    --conf.id = theUnit:getID()\\\
    conf.currentState = 0\\\
    local thePoint = theUnit:getPoint()\\\
    local mySide = theUnit:getCoalition()\\\
    local myName = theUnit:getName()    \\\
\\\
    -- first, check if we have landed in a CSAR dropoff zone \\\
    -- if so, drop off all loaded csar troops and award the \\\
    -- points or airframes \\\
    local allEvacuees = cargoSuper.getManifestFor(myName, \\\"Evacuees\\\") -- returns unlinked array \\\
                                            \\\
    if #allEvacuees > 0 then -- wasif #conf.troopsOnBoard > 0 then\\\
        for idx, base in pairs(csarManager.csarBases) do\\\
            -- check if the attached zone has changed hands\\\
            -- this can happen if zone has its own owner \\\
            -- attribute and is conquered by another side \\\
            local currentBaseSide = base.side\\\
            \\\
            if base.zone.owner then \\\
                -- this zone is shared with capturable \\\
                -- zone extensions like owned zone, FARP etc.\\\
                -- use current owner\\\
                currentBaseSide = base.zone.owner \\\
--                trigger.action.outText(\\\"+++csar: overriding base.side with zone owner = \\\" .. currentBaseSide .. \\\" for csarB \\\" .. base.name .. \\\", requiring \\\" .. mySide .. \\\" or 0 to land\\\", 30)\\\
            else \\\
--                trigger.action.outText(\\\"+++csar: base \\\" .. base.name .. \\\" has no owner - proceeding with side = \\\" .. base.side .. \\\" looking for \\\" .. mySide, 30)\\\
            end\\\
            \\\
            if currentBaseSide == mySide or \\\
               currentBaseSide == 0 \\\
            then  -- can always land in neutral\\\
                if cfxZones.pointInZone(thePoint, base.zone) then \\\
                    for idx, msn in pairs(conf.troopsOnBoard) do \\\
                        -- each troopsOnboard is actually the \\\
                        -- csar mission that I picked up \\\
                        csarManager.successMission(myName, base.name, msn)\\\
                    end\\\
                    -- now use cargoSuper to retrieve all evacuees \\\
                    -- and deliver them to safety \\\
                    \\\
                    for idx, theMassObject in pairs(allEvacuees) do\\\
                        cargoSuper.removeMassObjectFrom(\\\
                                            myName, \\\
                                            \\\"Evacuees\\\", \\\
                                            theMassObject)\\\
                        msn = theMassObject.ref \\\
                        -- csarManager.successMission(myName, base.name, msn)\\\
                        -- to be done when we remove troopsOnBoard\\\
                    end                    \\\
                    -- reset weight \\\
                    local totalMass = cargoSuper.calculateTotalMassFor(myName)\\\
                    trigger.action.setUnitInternalCargo(myName, totalMass) -- super recalcs\\\
--                    trigger.action.outText(\\\"+++csar: delivered - set internal weight for \\\" .. myName .. \\\" to \\\" .. totalMass, 30)\\\
    \\\
--                    trigger.action.setUnitInternalCargo(myName, 10) -- 10 kg as empty \\\
                    conf.troopsOnBoard = {} -- empty out troops on board \\\
                    -- we do *not* return so we can pick up troops on \\\
                    -- a CSARBASE if they were dropped there\\\
                    \\\
                end\\\
            end -- my side?\\\
        end\\\
    end -- check only if I'm carrying evacuees\\\
\\\
    -- if not in a csar dropoff zone, check if we are \\\
    -- landed in a csar pickup zone, and start loading \\\
    \\\
    local pickups = {}\\\
    for idx, mission in pairs(csarManager.openMissions) do \\\
        if mySide == mission.side then \\\
            -- see if we are inside the mission's rescue range \\\
            local d = dcsCommon.distFlat(thePoint, mission.zone.point)\\\
            if d < csarManager.rescueRadius then \\\
                -- pick up this mission an remove it from the \\\
                table.insert(pickups, mission)\\\
            end\\\
        end\\\
    end\\\
    \\\
    -- now process the missions that I've picked up, transfer them to troopsOnBoard, and remove the dudes\\\
    local didPickup = false \\\
    for idx, theMission in pairs(pickups) do\\\
        trigger.action.outTextForCoalition(mySide,\\\
        myName .. \\\" is extracting \\\" .. theMission.name .. \\\"!\\\", \\\
        30)\\\
        didPickup = true;\\\
        \\\
        csarManager.removeMission(theMission)\\\
        table.insert(conf.troopsOnBoard, theMission)\\\
        theMission.group:destroy() -- will shut up radio as well\\\
        theMission.group = nil\\\
        -- now adapt for cargoSuper \\\
        theMassObject = cargoSuper.createMassObject(\\\
                csarManager.pilotWeight, \\\
                theMission.name, \\\
                theMission)\\\
        cargoSuper.addMassObjectTo(\\\
                myName, \\\
                \\\"Evacuees\\\", \\\
                theMassObject)\\\
    end\\\
    if didPickup then \\\
        trigger.action.outSoundForCoalition(mySide, \\\"Quest Snare 3.wav\\\")\\\
    end\\\
    -- reset unit's weight based on people on board\\\
    local totalMass = cargoSuper.calculateTotalMassFor(myName)\\\
    -- WAS: trigger.action.setUnitInternalCargo(myName, 10 + #conf.troopsOnBoard * csarManager.pilotWeight) -- 10 kg as empty + per-unit time people \\\
    trigger.action.setUnitInternalCargo(myName, totalMass) -- 10 kg as empty + per-unit time people \\\
--    trigger.action.outText(\\\"+++csar: set internal weight for \\\" .. myName .. \\\" to \\\" .. totalMass, 30)\\\
    \\\
end\\\
\\\
--\\\
--\\\
-- Helo took off\\\
--\\\
--\\\
function csarManager.heloDeparted(theUnit)\\\
    if not dcsCommon.isTroopCarrier(theUnit) then return end\\\
    -- if we have timed extractions (i.e. not instantaneous),\\\
    -- then we need to check if we take off after the timer runs out \\\
    \\\
    \\\
    -- when we take off, all that needs to be done is to change the state \\\
    -- to airborne, and then set the status flag \\\
    local conf = csarManager.getUnitConfig(theUnit)\\\
    conf.unit = theUnit\\\
    local theGroup = theUnit:getGroup()\\\
    conf.id = theGroup:getID()\\\
    conf.currentState = 1 -- in the air \\\
    \\\
    \\\
end\\\
\\\
--\\\
-- \\\
-- Helo Crashed \\\
--\\\
--\\\
\\\
function csarManager.heloCrashed(theUnit)\\\
    if not dcsCommon.isTroopCarrier(theUnit) then return end\\\
    -- problem: this isn't called on network games. \\\
    \\\
    -- clean up \\\
    local conf = csarManager.getUnitConfig(theUnit)\\\
    conf.unit = theUnit \\\
    local theGroup = theUnit:getGroup()\\\
    conf.id = theGroup:getID()\\\
    conf.currentState = -1 -- (we don't know)\\\
    --[[--\\\
    if #conf.troopsOnBoard > 0 then \\\
        -- this is where we can create a new CSAR mission\\\
        trigger.action.outSoundForCoalition(conf.id, theUnit:getName() .. \\\" crashed while evacuating \\\" .. #conf.troopsOnBoard .. \\\" pilots. Survivors possible.\\\", 30)\\\
        trigger.action.outSoundForCoalition(conf.id, \\\"Quest Snare 3.wav\\\")\\\
        for i=1, #conf.troopsOnBoard do \\\
            local msn = conf.troopsOnBoard[i] -- picked up unit(s)\\\
            local theRescuedPilot = msn.name \\\
            -- create x new missions in 50m radius\\\
            -- except for pilot, that will be called \\\
            -- from limitedAirframes\\\
            csarManager.createCSARforUnit(theUnit, theRescuedPilot, 50, true)\\\
        end\\\
    end\\\
    --]]--\\\
    conf.troopsOnBoard = {}\\\
    local myName = conf.name\\\
    cargoSuper.removeAllMassForCargo(myName, \\\"Evacuees\\\") -- will allocate new empty table \\\
    csarManager.removeComms(conf.unit)\\\
end\\\
\\\
function csarManager.airframeCrashed(theUnit)\\\
    -- called from airframe manager \\\
    if not dcsCommon.isTroopCarrier(theUnit) then return end\\\
    local conf = csarManager.getUnitConfig(theUnit)\\\
    conf.unit = theUnit \\\
    local theGroup = theUnit:getGroup()\\\
    conf.id = theGroup:getID()\\\
    -- may want to do something, for now just nothing\\\
    \\\
end\\\
\\\
function csarManager.airframeDitched(theUnit)\\\
    -- called from airframe manager \\\
    if not dcsCommon.isTroopCarrier(theUnit) then return end\\\
    \\\
    local conf = csarManager.getUnitConfig(theUnit)\\\
    conf.unit = theUnit \\\
    local theGroup = theUnit:getGroup()\\\
    conf.id = theGroup:getID()\\\
    local theSide = theUnit:getCoalition()\\\
    if #conf.troopsOnBoard > 0 then \\\
        -- this is where we can create a new CSAR mission\\\
        trigger.action.outTextForCoalition(theSide, theUnit:getName() .. \\\" abandoned while evacuating \\\" .. #conf.troopsOnBoard .. \\\" pilots. There many be survivors.\\\", 30)\\\
--        trigger.action.outSoundForCoalition(conf.id, \\\"Quest Snare 3.wav\\\")\\\
        for i=1, #conf.troopsOnBoard do \\\
            local msn = conf.troopsOnBoard[i] -- picked up unit(s)\\\
            local theRescuedPilot = msn.name \\\
            -- create x new missions in 50m radius\\\
            -- except for pilot, that will be called \\\
            -- from limitedAirframes\\\
            csarManager.createCSARforUnit(theUnit, theRescuedPilot, 50, true)\\\
        end\\\
    end\\\
    -- NYI: re-populate from cargo \\\
    local myName = conf.name\\\
    cargoSuper.removeAllMassForCargo(myName, \\\"Evacuees\\\") -- will allocate new empty table \\\
end\\\
\\\
--\\\
--\\\
-- M E N U   H A N D L I N G   &   R E S P O N S E \\\
-- \\\
-- \\\
function csarManager.clearCommsSubmenus(conf)\\\
    if conf.myCommands then \\\
        for i=1, #conf.myCommands do\\\
            missionCommands.removeItemForGroup(conf.id, conf.myCommands[i])\\\
        end\\\
    end\\\
    conf.myCommands = {}\\\
end\\\
\\\
function csarManager.removeCommsFromConfig(conf)\\\
    csarManager.clearCommsSubmenus(conf)\\\
    \\\
    if conf.myMainMenu then \\\
        missionCommands.removeItemForGroup(conf.id, conf.myMainMenu) \\\
        conf.myMainMenu = nil\\\
    end\\\
end\\\
\\\
function csarManager.removeComms(theUnit)\\\
    if not theUnit then return end\\\
    if not theUnit:isExist() then return end \\\
    \\\
    local group = theUnit:getGroup() \\\
    local id = group:getID()\\\
    local conf = csarManager.getUnitConfig(theUnit)\\\
    conf.id = id\\\
    conf.unit = theUnit \\\
    \\\
    csarManager.removeCommsFromConfig(conf)\\\
end\\\
\\\
\\\
function csarManager.setCommsMenu(theUnit)\\\
    if not theUnit then return end\\\
    if not theUnit:isExist() then return end \\\
    \\\
    -- we only add this menu to helicopter troop carriers\\\
    -- will also filter out all non-helicopters as nice side effect\\\
    if not dcsCommon.isTroopCarrier(theUnit) then return end\\\
    \\\
    local group = theUnit:getGroup() \\\
    local id = group:getID()\\\
    local conf = csarManager.getUnitConfig(theUnit) -- will allocate if new. This is important since a group event can call this as well\\\
    conf.id = id; -- we do this ALWAYS to it is current even after a crash \\\
    conf.unit = theUnit -- link back\\\
    \\\
    -- reset all coms now\\\
    csarManager.removeCommsFromConfig(conf)\\\
    \\\
    -- ok, first, if we don't have an F-10 menu, create one \\\
    conf.myMainMenu = missionCommands.addSubMenuForGroup(id, 'CSAR Missions') \\\
    \\\
    -- now we have a menu without submenus. \\\
    -- add our own submenus\\\
    local commandTxt = \\\"List active CSAR requests\\\"\\\
    local theCommand =  missionCommands.addCommandForGroup(\\\
                conf.id, \\\
                commandTxt,\\\
                conf.myMainMenu,\\\
                csarManager.redirectListCSARRequests, \\\
                {conf, \\\"hi there\\\"}\\\
                )\\\
    table.insert(conf.myCommands, theCommand)\\\
    commandTxt = \\\"Status of rescued crew aboard\\\"\\\
    theCommand =  missionCommands.addCommandForGroup(\\\
                conf.id, \\\
                commandTxt,\\\
                conf.myMainMenu,\\\
                csarManager.redirectStatusCarrying, \\\
                {conf, \\\"hi there\\\"}\\\
                )\\\
    table.insert(conf.myCommands, theCommand)\\\
    \\\
    commandTxt = \\\"Unload one evacuee here (rescue later)\\\"\\\
    theCommand =  missionCommands.addCommandForGroup(\\\
                conf.id, \\\
                commandTxt,\\\
                conf.myMainMenu,\\\
                csarManager.redirectUnloadOne, \\\
                {conf, \\\"unload one\\\"}\\\
                )\\\
    table.insert(conf.myCommands, theCommand)\\\
end\\\
\\\
\\\
function csarManager.redirectListCSARRequests(args)\\\
    timer.scheduleFunction(csarManager.doListCSARRequests, args, timer.getTime() + 0.1)\\\
end\\\
\\\
function csarManager.doListCSARRequests(args) \\\
    local conf = args[1]\\\
    local param = args[2]\\\
    local theUnit = conf.unit \\\
    local point = theUnit:getPoint()\\\
    \\\
    --trigger.action.outText(\\\"+++csar: \\\".. theUnit:getName() ..\\\"  issued csar status request\\\", 30)\\\
    local report = \\\"\\\\nCrews requesting evacuation\\\\n\\\"\\\
    if #csarManager.openMissions < 1 then \\\
        report = report .. \\\"\\\\nNo requests, all crew are safe.\\\"\\\
    else \\\
        -- iterate through all troops onboard to get their status\\\
        for idx, mission in pairs(csarManager.openMissions) do \\\
            local d = dcsCommon.distFlat(point, mission.zone.point) * 0.000539957\\\
            d = math.floor(d * 10) / 10\\\
            local b = dcsCommon.bearingInDegreesFromAtoB(point, mission.zone.point)\\\
            local status = \\\"alive\\\"\\\
            report = report .. \\\"\\\\n\\\".. mission.name .. \\\", bearing \\\" .. b .. \\\", \\\" ..d ..\\\"nm, \\\" .. \\\" ADF \\\" .. mission.freq .. \\\"0 kHz - \\\" .. status \\\
        end\\\
    end\\\
    \\\
    if #csarManager.csarBases < 1 then \\\
        report = report .. \\\"\\\\n\\\\nWARNING: NO CSAR BASES TO DELIVER EVACUEES\\\"\\\
    end\\\
    \\\
    report = report .. \\\"\\\\n\\\"\\\
    \\\
    trigger.action.outTextForGroup(conf.id, report, 30)\\\
    trigger.action.outSoundForGroup(conf.id, \\\"Quest Snare 3.wav\\\")\\\
end\\\
\\\
function csarManager.redirectStatusCarrying(args)\\\
    timer.scheduleFunction(csarManager.doStatusCarrying, args, timer.getTime() + 0.1)\\\
end\\\
\\\
function csarManager.doStatusCarrying(args) \\\
    local conf = args[1]\\\
    local param = args[2]\\\
    local theUnit = conf.unit \\\
    \\\
    --trigger.action.outText(\\\"+++csar: \\\".. theUnit:getName() ..\\\"  wants to know how their rescued troops are doing\\\", 30)\\\
    \\\
    -- build status report\\\
    local report = \\\"\\\\nCrew Rescue Status:\\\\n\\\"\\\
    if #conf.troopsOnBoard < 1 then \\\
        report = report .. \\\"\\\\nWe have no evacuees on board\\\"\\\
    else \\\
        -- iterate through all troops onboard to get their status\\\
        for i=1, #conf.troopsOnBoard do \\\
            local evacMission = conf.troopsOnBoard[i]\\\
            report = report .. \\\"\\\\n\\\".. i .. \\\") \\\" .. evacMission.name \\\
            report = report .. \\\" is stable\\\" -- or 'beat up, but will live'\\\
        end\\\
        \\\
        report = report .. \\\"\\\\n\\\\nTotal added weigth: \\\" .. 10 + #conf.troopsOnBoard * csarManager.pilotWeight .. \\\"kg\\\" \\\
    end\\\
    \\\
    \\\
    report = report .. \\\"\\\\n\\\"\\\
    \\\
    trigger.action.outTextForGroup(conf.id, report, 30)\\\
    trigger.action.outSoundForGroup(conf.id, \\\"Quest Snare 3.wav\\\")\\\
end\\\
\\\
function csarManager.redirectUnloadOne(args)\\\
    timer.scheduleFunction(csarManager.unloadOne, args, timer.getTime() + 0.1)\\\
end\\\
\\\
function csarManager.unloadOne(args)\\\
    local conf = args[1]\\\
    local param = args[2]\\\
    local theUnit = conf.unit \\\
    local myName = theUnit:getName() \\\
    \\\
    local report = \\\"NYI: unload one\\\"\\\
    \\\
    if theUnit:inAir() then \\\
        report = \\\"STRONGLY recommend we land first, Sir!\\\"\\\
        trigger.action.outTextForGroup(conf.id, report, 30)\\\
        trigger.action.outSoundForGroup(conf.id, \\\"Quest Snare 3.wav\\\")\\\
        return \\\
    end\\\
    \\\
    if #conf.troopsOnBoard < 1 then\\\
        report = \\\"No evacuees on board.\\\"\\\
        trigger.action.outTextForGroup(conf.id, report, 30)\\\
        trigger.action.outSoundForGroup(conf.id, \\\"Quest Snare 3.wav\\\")\\\
        \\\
    else \\\
        -- simulate a crash but for one unit \\\
        local theSide = theUnit:getCoalition()\\\
        -- this is where we can create a new CSAR mission\\\
        i= #conf.troopsOnBoard \\\
        local msn = conf.troopsOnBoard[i] -- picked up unit(s)\\\
        local theRescuedPilot = msn.name \\\
        -- create a new missions in 50m radius\\\
        csarManager.createCSARforUnit(theUnit, theRescuedPilot, 50, true)\\\
        conf.troopsOnBoard[i] = nil -- remove this mission\\\
        trigger.action.outTextForCoalition(theSide, myName .. \\\" has aborted evacuating \\\" .. msn.name .. \\\". New CSAR available.\\\", 30)\\\
        trigger.action.outSoundForCoalition(theSide, \\\"Quest Snare 3.wav\\\")\\\
        \\\
        -- recalc weight\\\
        trigger.action.setUnitInternalCargo(myName, 10 + #conf.troopsOnBoard * csarManager.pilotWeight) -- 10 kg as empty + per-unit time people \\\
    end\\\
    \\\
end\\\
--\\\
-- Player event callbacks\\\
--\\\
function csarManager.playerChangeEvent(evType, description, player, data)\\\
    if evType == \\\"newGroup\\\" then \\\
        local theUnit = data.primeUnit\\\
        if not dcsCommon.isTroopCarrier(theUnit) then return end \\\
        \\\
        csarManager.setCommsMenu(theUnit) -- allocates new config\\\
--        trigger.action.outText(\\\"+++csar: added \\\" .. theUnit:getName() .. \\\" to comms menu\\\", 30)\\\
        return \\\
    end\\\
    \\\
    if evType == \\\"removeGroup\\\" then \\\
--        trigger.action.outText(\\\"+++csar: a group disappeared\\\", 30)\\\
        local conf = csarManager.getConfigForUnitNamed(data.primeUnitName)\\\
        if conf then \\\
            csarManager.removeCommsFromConfig(conf)\\\
        end\\\
        return\\\
    end\\\
    \\\
    if evType == \\\"leave\\\" then \\\
        local conf = csarManager.getConfigForUnitNamed(player.unitName)\\\
        if conf then \\\
            csarManager.resetConfig(conf)\\\
        end\\\
    end\\\
    \\\
    if evType == \\\"unit\\\" then \\\
        -- player changed units. almost never in MP, but possible in solo\\\
        -- because of 1 seconds timing loop \\\
        -- will result in a new group appearing and a group disappearing, so we are good,\\\
        -- except we need to reset the conf so no troops are carried any longer\\\
        local conf = csarManager.getConfigForUnitNamed(data.oldUnitName) \\\
        if conf then \\\
            csarManager.resetConfig(conf)\\\
        end\\\
    end\\\
end\\\
\\\
--\\\
-- CSAR Bases\\\
--\\\
-- properties: \\\
--  - zone : the zone \\\
--  - side : coalition \\\
--  - name : name of base, can be overriden with property\\\
\\\
function csarManager.addCSARBase(aZone)\\\
    local csarBase = {}\\\
    csarBase.zone = aZone \\\
    local bName = cfxZones.getStringFromZoneProperty(aZone, \\\"CSARBASE\\\", \\\"XXX\\\")\\\
    if bName == \\\"XXX\\\" then bName = aZone.name end \\\
    csarBase.name =  cfxZones.getStringFromZoneProperty(aZone, \\\"name\\\", bName) \\\
    \\\
    -- read further properties like facilities that may \\\
    -- need to be matched \\\
    csarBase.side = cfxZones.getCoalitionFromZoneProperty(aZone, \\\"coalition\\\", 0) \\\
    \\\
    table.insert(csarManager.csarBases, csarBase)\\\
--    trigger.action.outText(\\\"+++csar: found base \\\" .. csarBase.name .. \\\" for side \\\" .. csarBase.side, 30)    \\\
end\\\
\\\
function csarManager.getCSARBaseforZone(aZone)\\\
    for idx, aCsarBase in pairs(csarManager.csarBases) do \\\
        if aCsarBase.zone == aZone then \\\
            return aCsarBase \\\
        end\\\
    end\\\
    return nil\\\
end\\\
\\\
--\\\
--\\\
-- U P D A T E \\\
-- ===========\\\
-- \\\
-- \\\
\\\
\\\
--\\\
-- updateCSARMissions: make sure evacuees are still alive \\\
--\\\
function csarManager.updateCSARMissions()\\\
    local newMissions = {}\\\
    for idx, aMission in pairs (csarManager.openMissions) do\\\
        local stillAlive = dcsCommon.isGroupAlive(aMission.group)\\\
        -- now check if a timer was running to rescue this group\\\
        -- if dead, set stillAlive to false \\\
        if stillAlive then \\\
            table.insert(newMissions, aMission)\\\
        else \\\
            local msg = aMission.name .. \\\" confirmed KIA, repeat KIA. Abort CSAR.\\\"    \\\
            trigger.action.outTextForCoalition(aMission.side, msg, 30)\\\
            trigger.action.outSoundForCoalition(aMission.side, \\\"Quest Snare 3.wav\\\")\\\
        end\\\
    end\\\
    csarManager.openMissions = newMissions -- this is the new batch\\\
end\\\
\\\
function csarManager.update() -- every second\\\
    -- schedule next invocation\\\
    timer.scheduleFunction(csarManager.update, {}, timer.getTime() + 1)\\\
\\\
    -- first, check the health of all csar misions and update the table of live units\\\
    csarManager.updateCSARMissions()\\\
\\\
    -- now scan through all helo groups and see if they are close to a \\\
    -- CSAR zone and initiate the help sequence \\\
    local allPlayerGroups = cfxPlayerGroups -- cfxPlayerGroups is a global, don't fuck with it! \\\
    -- contains per group a player record, use prime unit to access player's unit \\\
    for gname, pgroup in pairs(allPlayerGroups) do \\\
        local aUnit = pgroup.primeUnit --        get prime unit of that group\\\
        if aUnit:isExist() and aUnit:inAir() then -- exists and is flying \\\
            local uPoint = aUnit:getPoint()\\\
            local uName = aUnit:getName()\\\
            local uGroup = aUnit:getGroup()\\\
            local uID = uGroup:getID()\\\
            local uSide = aUnit:getCoalition()\\\
            local agl = dcsCommon.getUnitAGL(aUnit)\\\
            if dcsCommon.isTroopCarrier(aUnit) then \\\
                -- scan through all available csar missions to see if we are close \\\
                -- enough to trigger comms \\\
                for idx, csarMission in pairs (csarManager.openMissions) do\\\
                    -- check if we are inside trigger range on the same side\\\
                    local d = dcsCommon.distFlat(uPoint, csarMission.zone.point)\\\
                    if (uSide == csarMission.side) and (d < csarManager.rescueTriggerRange) then \\\
                        -- we are in trigger distance. if we did not notify before\\\
                        -- do it now \\\
                        if not dcsCommon.arrayContainsString(csarMission.messagedUnits, uName) then \\\
                            -- radio this unit with oclock and tell it they are in 2k range \\\
                            -- also note if LZ is hot \\\
                            local ownHeading = dcsCommon.getUnitHeadingDegrees(aUnit)\\\
                            local oclock = dcsCommon.clockPositionOfARelativeToB(csarMission.zone.point, uPoint, ownHeading) .. \\\" o'clock\\\"\\\
                            local msg = \\\"\\\\n\\\" .. uName ..\\\", \\\" .. csarMission.name .. \\\". We can hear you, check your \\\" .. oclock \\\
                            if csarManager.useSmoke then msg = msg .. \\\" - popping smoke\\\" end\\\
                            msg = msg .. \\\".\\\"\\\
                            if csarMission.isHot then \\\
                                msg = msg .. \\\" Be advised: LZ is hot.\\\"\\\
                            end\\\
                            msg = msg .. \\\"\\\\n\\\"\\\
                            trigger.action.outTextForGroup(uID, msg, 30)\\\
                            trigger.action.outSoundForGroup(uID, \\\"Quest Snare 3.wav\\\")\\\
                            table.insert(csarMission.messagedUnits, uName) -- remember that we messaged them so we don't do again\\\
                        end\\\
                        -- also pop smoke if not popped already, or more than 3 minutes ago\\\
                        if csarManager.useSmoke and  timer.getTime() - csarMission.lastSmokeTime > 179 then \\\
                            local smokePoint = cfxZones.createHeightCorrectedPoint(csarMission.zone.point)\\\
                            trigger.action.smoke(smokePoint, 4 )\\\
                        end\\\
                        \\\
                        -- now check if we are inside hover range and alt \\\
                        -- in order to simultate winch ops \\\
                        -- WARNING: WE ALWAYS ONLY CHECK A SINGLE UNIT - the first alive\\\
                        local evacuee = csarMission.group:getUnit(1)\\\
                        if evacuee then \\\
                            ep = evacuee:getPoint()\\\
                            d = dcsCommon.distFlat(uPoint, ep)\\\
                            d = math.floor(d * 10) / 10\\\
                            if d < csarManager.hoverRadius * 2 then\\\
                                local ownHeading = dcsCommon.getUnitHeadingDegrees(aUnit)\\\
                                local oclock = dcsCommon.clockPositionOfARelativeToB(ep, uPoint, ownHeading) .. \\\" o'clock\\\"\\\
                                -- log distance \\\
                                local hoverMsg = \\\"Closing on \\\" .. csarMission.name .. \\\", \\\" .. d * 3 .. \\\"ft on your \\\" .. oclock .. \\\" o'clock\\\"\\\
\\\
                                if d < csarManager.hoverRadius then \\\
                                    if (agl <= csarManager.hoverAlt) and (agl > 3) then \\\
                                        local hoverTime = csarMission.hoveringUnits[uName]\\\
                                        if not hoverTime then \\\
                                            -- create new entry\\\
                                            hoverTime = timer.getTime()\\\
                                            csarMission.hoveringUnits[uName] = timer.getTime() \\\
                                        end\\\
                                        hoverTime = timer.getTime() - hoverTime -- calculate number of seconds \\\
                                        remainder = math.floor(csarManager.hoverDuration - hoverTime)\\\
                                        if remainder < 1 then remainder = 1 end \\\
                                        hoverMsg = \\\"Steady... \\\" .. d * 3 .. \\\"ft to your \\\" .. oclock .. \\\" o'clock, winching... (\\\" .. remainder .. \\\")\\\" \\\
                                        if hoverTime > csarManager.hoverDuration then \\\
                                            -- we rescued the guy!\\\
                                            hoverMsg = \\\"We have \\\" .. csarMission.name .. \\\" safely on board!\\\"\\\
                                            local conf = csarManager.getUnitConfig(aUnit)\\\
                                            csarManager.removeMission(csarMission)\\\
                                            table.insert(conf.troopsOnBoard, csarMission)\\\
                                            csarMission.group:destroy() -- will shut up radio as well\\\
                                            csarMission.group = nil\\\
                                            trigger.action.outTextForGroup(uID, hoverMsg, 30, true)\\\
                                            trigger.action.outSoundForGroup(uID, \\\"Quest Snare 3.wav\\\")\\\
\\\
                                            return -- we only ever rescue one \\\
                                        end -- hovered long enough \\\
                                        trigger.action.outTextForGroup(uID, hoverMsg, 30, true)\\\
                                        return -- only ever one winch op\\\
                                    else -- too high for hover \\\
                                        hoverMsg = \\\"Evacuee \\\" .. d * 3 .. \\\"ft on your \\\" .. oclock .. \\\" o'clock; land or descend to between 10 and 90 AGL for winching\\\"\\\
                                        csarMission.hoveringUnits[uName] = nil -- reset timer \\\
                                    end\\\
                                else -- not inside hover dist\\\
                                    -- remove the hover indicator for this \\\
                                    csarMission.hoveringUnits[uName] = nil \\\
                                end \\\
                                trigger.action.outTextForGroup(uID, hoverMsg, 30, true)\\\
                                return -- only ever one winch op\\\
                            else \\\
                                -- remove the hover indicator for this unit\\\
                                csarMission.hoveringUnits[uName] = nil\\\
                            end -- inside 2 * hover dist?\\\
                            \\\
                        end -- has evacuee \\\
                    end -- if in range\\\
                end -- for all missions \\\
            end -- if troop carrier \\\
        end -- if exists \\\
    end -- for all players \\\
end\\\
\\\
--\\\
-- create a CSAR Mission for a unit \\\
-- \\\
function csarManager.createCSARforUnit(theUnit, pilotName, radius, silent)\\\
    if not silent then silent = false end \\\
    if not radius then radius = 1000 end \\\
    if not pilotName then pilotName = \\\"Eddie\\\" end \\\
    \\\
    local point = theUnit:getPoint()\\\
    local coal = theUnit:getCoalition() \\\
    \\\
    local csarPoint = dcsCommon.randomPointInCircle(radius, radius/2, point.x, point.z) \\\
    \\\
    -- check the ground- water will kill the pilot \\\
    csarPoint.y = csarPoint.z \\\
    local surf = land.getSurfaceType(csarPoint)\\\
    \\\
    if surf == 2 or surf == 3 then \\\
        if not silent then \\\
            trigger.action.outTextForCoalition(coal, \\\"Bad chute! Bad chute! \\\".. pilotName .. \\\" did not survive ejection out of their \\\" .. theUnit:getTypeName(), 30)\\\
            trigger.action.outSoundForGroup(coal, \\\"Quest Snare 3.wav\\\")\\\
        end\\\
        return \\\
    end\\\
    \\\
    csarPoint.y = land.getHeight(csarPoint)\\\
    \\\
    -- when we get here, the terrain is ok, so let's drop the pilot \\\
    local theMission = csarManager.createCSARMissionData(\\\
        csarPoint, \\\
        coal, \\\
        nil, \\\
        pilotName, \\\
        1, \\\
        nil, \\\
        nil)\\\
    csarManager.addMission(theMission)\\\
    if not silent then \\\
        trigger.action.outTextForCoalition(coal, \\\"MAYDAY MAYDAY MAYDAY! \\\".. pilotName .. \\\" in \\\" .. theUnit:getTypeName() .. \\\" ejected, report good chute. Prepare CSAR!\\\", 30)\\\
        trigger.action.outSoundForGroup(coal, \\\"Quest Snare 3.wav\\\")\\\
    end \\\
end\\\
\\\
\\\
\\\
--\\\
-- Init & Start \\\
--\\\
\\\
function csarManager.processCSARBASE()\\\
    local csarBases = cfxZones.zonesWithProperty(\\\"CSARBASE\\\")\\\
    \\\
    -- now add all zones to my zones table, and init additional info\\\
    -- from properties\\\
    for k, aZone in pairs(csarBases) do\\\
        csarManager.addCSARBase(aZone)\\\
    end\\\
end\\\
\\\
function csarManager.processCASRZones()\\\
    local csarBases = cfxZones.zonesWithProperty(\\\"CSAR\\\")\\\
    \\\
    -- now add all zones to my zones table, and init additional info\\\
    -- from properties\\\
    for k, aZone in pairs(csarBases) do\\\
        -- gather data, and then create a mission from this\\\
        local theSide = cfxZones.getCoalitionFromZoneProperty(aZone, \\\"coalition\\\", 0)\\\
        local name = cfxZones.getZoneProperty(aZone, \\\"name\\\")\\\
        local freq = cfxZones.getNumberFromZoneProperty(aZone, \\\"freq\\\", 0)\\\
        if freq == 0 then freq = nil end \\\
        local numCrew = 1 \\\
        local mapMarker = nil \\\
        local timeLimit = cfxZones.getNumberFromZoneProperty(aZone, \\\"timeLimit\\\", 0)\\\
        if timeLimit == 0 then timeLimit = nil else timeLimit = timeLimit * 60 end \\\
        \\\
        local theMission = csarManager.createCSARMissionData(aZone.point, \\\
            theSide, \\\
            freq, \\\
            name, \\\
            numCrew, \\\
            timeLimit, \\\
            mapMarker)\\\
        csarManager.addMission(theMission)\\\
    end\\\
end\\\
\\\
\\\
function csarManager.invokeCallbacks(theCoalition, success, numRescued, notes)\\\
    -- invoke anyone who wants to know that a group \\\
    -- of people was rescued.\\\
    for idx, cb in pairs(csarManager.csarCompleteCB) do \\\
        cb(theCoalition, success, numRescued, notes)\\\
    end\\\
end\\\
\\\
function csarManager.installCallback(theCB)\\\
    table.insert(csarManager.csarCompleteCB, theCB)\\\
end\\\
\\\
\\\
function csarManager.start()\\\
    -- make sure we have loaded all relevant libraries \\\
    if not dcsCommon.libCheck(\\\"cfx CSAR\\\", csarManager.requiredLibs) then \\\
        trigger.action.outText(\\\"cf/x CSAR aborted: missing libraries\\\", 30)\\\
        return false \\\
    end\\\
\\\
    -- install callbacks for helo-relevant events\\\
    dcsCommon.addEventHandler(csarManager.somethingHappened, csarManager.preProcessor, csarManager.postProcessor)\\\
\\\
    -- now iterate through all player groups and install the CSAR Menu\\\
    \\\
    local allPlayerGroups = cfxPlayerGroups -- cfxPlayerGroups is a global, don't fuck with it! \\\
    -- contains per group a player record, use prime unit to access player's unit \\\
    for gname, pgroup in pairs(allPlayerGroups) do \\\
        local aUnit = pgroup.primeUnit -- get prime unit of that group\\\
        csarManager.setCommsMenu(aUnit)\\\
    end\\\
    -- now install the new group notifier for new groups so we can remove and add CSAR menus \\\
    cfxPlayer.addMonitor(csarManager.playerChangeEvent)\\\
\\\
    -- now scan all zones that are CSAR drop-off for quick access\\\
    csarManager.processCSARBASE()\\\
    \\\
    -- now scan all zones to create ME-placed CSAR missions\\\
    -- and populate the available mission.\\\
    csarManager.processCASRZones()\\\
    \\\
    -- now call update so we can monitor progress of all helos, and alert them\\\
    -- when they are close to a CSAR\\\
    csarManager.update()\\\
\\\
    -- say hi!\\\
    trigger.action.outText(\\\"cf/x CSAR v\\\" .. csarManager.version .. \\\" started\\\", 30)\\\
    return true \\\
end\\\
\\\
-- let's get rolling\\\
if not csarManager.start() then \\\
    csarManager = nil\\\
end\\\
\\\
\\\
--[[--\\\
    improvements\\\
    - need to stay on ground for x seconds to load troops \\\
    - hot lz\\\
    - hover recover \\\
    - limit on troops aboard for transport\\\
    - delay for drop-off \\\
    \\\
    - csar when: always, only on eject, \\\
    \\\
    - repair o'clock \\\
    \\\
    - nearest csarBase\\\
    - red/blue csarbases \\\
    - weight \\\
    \\\
    - compatibility: side/owner - make sure it is compatible \\\
      with FARP, and landing on a FARP with opposition ownership \\\
      will not disembark\\\
    \\\
--]]--\");a_do_script(\"limitedAirframes = {}\\\
limitedAirframes.version = \\\"1.3.0\\\"\\\
limitedAirframes.enabled = true -- can be turned off\\\
limitedAirframes.userCanToggle = true -- F-10 menu?\\\
limitedAirframes.maxRed = -1 -- -1 == infinite\\\
limitedAirframes.maxBlue = 6 -- -1 = infinite\\\
limitedAirframes.redWinsFlag = \\\"999\\\"\\\
limitedAirframes.blueWinsFlag = \\\"998\\\" \\\
 \\\
limitedAirframes.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- common is of course needed for everything\\\
                 -- pretty stupid to check for this since we \\\
                 -- need common to invoke the check, but anyway\\\
    \\\"cfxZones\\\", -- Zones, of course for safe landings\\\
    \\\"cfxPlayer\\\", -- callbacks \\\
--    \\\"cfxGroundTroops\\\", -- generic data module for weight \\\
}\\\
\\\
--[[-- VERSION HISTORY\\\
 - 1.0.0 - initial version \\\
 - 1.0.1 - out text to coalition for switch\\\
         - less verbose\\\
         - win/lose sound by coalition\\\
 - 1.0.2 - corrected some to to-->for Groups typos\\\
 - 1.0.3 - renamed to 'pilot' instead of airframe:\\\
           pilotSafe attribute \\\
         - fixed MP bug, switched to EventMonII code\\\
 - 1.0.4 - added CSAR integration: create CSAR and callback\\\
         - safe ditch only at less than 7 kmh and 10m agl \\\
 - 1.0.5 - replaced 5 (crash) check for helos only \\\
 - 1.0.6 - changed alt and speed tests to inAir\\\
           reduced verbosity \\\
           made reporting of new units for coalition side only \\\
 - 1.0.7 - if unlimited pilots it says so when you return one \\\
           to base\\\
 - 1.0.8 - now can query remaining pilots \\\
 - 1.0.9 - better formatted remaining pilots \\\
 - 1.1.0 - module manager \\\
         - separated out settings \\\
         - hand change in pilotsafe zones that can be landed in \\\
 - 1.2.0 - limitedAirframesConfig zone \\\
 - 1.3.0 - added network dead override logic via unitFlownByPlayer\\\
 \\\
--]]--\\\
\\\
-- limitedAirframes manages the number of available player airframes\\\
-- per scenario and side. Each time a player crashes the plane\\\
-- outside of safe zones, the number is decreased for that side\\\
-- when the number reaches -1 or smaller, other side wins\\\
-- !!!Only affects player planes!!\\\
\\\
-- *** EXTENDS ZONES ***\\\
-- safe zones must have a property \\\"pilotSafe\\\"\\\
--   - pilotSafe - this is a zone to safely change airframes in\\\
--   - redSafe (optional, defaults to true)\\\
--   - blueSafe (optional, defaults to true)\\\
--     set to \\\"false\\\" or \\\"no\\\" to disallow that side to change \\\
--       airframes even when safer\\\
--   if zone can change ownership, player's coalition \\\
--   is checked against current zone ownership \\\
--   zone owner. \\\
\\\
-- when red wins due to blue frame loss, flag 999 is set to true\\\
-- when blue wins due to red frame loss, flag 998 is set to true\\\
-- set a mission trigger to end mission if you want to end mission\\\
-- or simply keep running, and a CHEATER! message will flash \\\
-- every time the losing side enters a new aircraft \\\
\\\
limitedAirframes.safeZones = {} -- safezones are zones where a crash or change plane does not\\\
-- these zones are created by adding an 'pilotSafe' attribute\\\
\\\
limitedAirframes.myEvents = {5, 9, 30, 6, 20, 21, 15 } -- 5 = crash, 9 - dead, 30 - unit lost, 6 - eject, 20 - enter unit, 21 - leave unit, 15 - birth\\\
\\\
-- guarantee a min of 2 seconds between events\\\
-- for this we save last event per player \\\
limitedAirframes.lastEvents = {}\\\
-- each time a plane crashes or is abandoned check \\\
-- that it's a player unit \\\
-- inside a crash free zone \\\
-- update the side's airframe credit \\\
\\\
limitedAirframes.currRed = 0\\\
limitedAirframes.currRed = 0\\\
\\\
-- we record all unit names that contain a player \\\
-- so that we can check against these when we receive\\\
-- an ejection event. We also keep a list of players\\\
-- for good measure and their status\\\
limitedAirframes.playerUnits = {}\\\
limitedAirframes.players = {}\\\
limitedAirframes.unitFlownByPlayer = {} -- to detect dead after \\\
        -- 21 (player left unit) we store on 15 (birth)\\\
        -- which unit a player occupies. if player \\\
        -- then levaes and dead has a mismatch, we resolve \\\
        -- by not calling dead. \\\
        -- works if eject does not call player left unit \\\
        -- unit[unitname] = playername. if nil, no longer \\\
        -- occupied by player.\\\
        \\\
limitedAirframes.theCommand = nil \\\
\\\
--\\\
-- READ CONFIG ZONE TO OVERRIDE SETTING\\\
--\\\
function limitedAirframes.readConfigZone()\\\
    -- note: must match exactly!!!!\\\
    local theZone = cfxZones.getZoneByName(\\\"limitedAirframesConfig\\\") \\\
    if not theZone then \\\
        trigger.action.outText(\\\"***LimA: NO config zone!\\\", 30) \\\
        return \\\
    end \\\
    \\\
    trigger.action.outText(\\\"LimA: found config zone!\\\", 30) \\\
    \\\
    -- ok, for each property, load it if it exists\\\
    if cfxZones.hasProperty(theZone, \\\"enabled\\\")  then \\\
        limitedAirframes.enabled = cfxZones.getBoolFromZoneProperty(theZone, \\\"enabled\\\", true)\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"userCanToggle\\\")  then \\\
        limitedAirframes.userCanToggle = cfxZones.getBoolFromZoneProperty(theZone, \\\"userCanToggle\\\", true)\\\
    end\\\
    \\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"maxRed\\\")  then \\\
        limitedAirframes.maxRed = cfxZones.getNumberFromZoneProperty(theZone, \\\"maxRed\\\", -1)\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"maxBlue\\\")  then \\\
        limitedAirframes.maxBlue = cfxZones.getNumberFromZoneProperty(theZone, \\\"maxBlue\\\", -1)\\\
    end\\\
    \\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"redWinsFlag\\\")  then \\\
        limitedAirframes.redWinsFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"redWinsFlag\\\", \\\"999\\\")\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"blueWinsFlag\\\")  then \\\
        limitedAirframes.blueWinsFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"blueWinsFlag\\\", \\\"998\\\")\\\
    end\\\
end\\\
\\\
--\\\
-- UNIT AND PLAYER HANDLING\\\
--\\\
function limitedAirframes.isKnownUnitName(uName)\\\
    if limitedAirframes.playerUnits[uName] then return true end\\\
    return false \\\
end\\\
\\\
function limitedAirframes.getKnownUnitPilotByUnitName(uName)\\\
    if limitedAirframes.isKnownUnitName(uName) then \\\
        return limitedAirframes.playerUnits[uName]\\\
    end\\\
    trigger.action.outText(\\\"+++lim: WARNING: \\\" .. uName .. \\\" is unknown!\\\", 30)\\\
    return \\\"***Error\\\"\\\
end\\\
\\\
function limitedAirframes.getKnownUnitPilotByUnit(theUnit)\\\
    return limitedAirframes.getKnownUnitPilotByUnitName(theUnit:getName())\\\
end\\\
\\\
-- addPlayerUnit adds a unit as a known player unit \\\
-- and also adds the player if unknown\\\
function limitedAirframes.addPlayerUnit(theUnit)\\\
    local theSide = theUnit:getCoalition()\\\
    local uName = theUnit:getName()\\\
    if not uName then uName = \\\"**XXXX**\\\" end \\\
    local pName = theUnit:getPlayerName()\\\
    if not pName then pName = \\\"**????**\\\" end \\\
    limitedAirframes.updatePlayer(pName, \\\"alive\\\")\\\
    \\\
    local desc = \\\"unit <\\\" .. uName .. \\\"> controlled by <\\\" .. pName .. \\\">\\\"\\\
    if not(limitedAirframes.isKnownUnitName(uName)) then \\\
        --desc = \\\"+++lim: added \\\".. desc .. \\\" to list of known player units\\\"\\\
    else \\\
        if limitedAirframes.playerUnits[uName] == pName then \\\
            desc = \\\"player unit <\\\".. uName .. \\\"> controlled by <\\\".. limitedAirframes.playerUnits[uName]..\\\"> re-seated\\\"\\\
        else \\\
            desc = \\\"Updated player unit <\\\".. uName .. \\\"> from <\\\".. limitedAirframes.playerUnits[uName]..\\\"> to <\\\" .. pName ..\\\">\\\"\\\
        end \\\
    end \\\
    limitedAirframes.playerUnits[uName] = pName \\\
    trigger.action.outTextForCoalition(theSide, desc, 30)\\\
end\\\
\\\
function limitedAirframes.killPlayer(pName)\\\
    limitedAirframes.updatePlayer(pName, \\\"dead\\\")\\\
    --trigger.action.outText(\\\"+++lim: PILOT LOST: \\\" .. pName .. \\\", NO CSAR\\\", 30)\\\
end\\\
\\\
function limitedAirframes.killPlayerInUnit(theUnit)\\\
    limitedAirframes.updatePlayerInUnit(theUnit, \\\"dead\\\")\\\
    --trigger.action.outText(\\\"+++lim: PILOT LOST, NO CSAR\\\", 30)\\\
end\\\
\\\
function limitedAirframes.updatePlayerInUnit(theUnit, status)\\\
    local uName = theUnit:getName()\\\
    if not limitedAirframes.isKnownUnitName(uName) then \\\
        trigger.action.outText(\\\"+++lim: WARNING: updatePlayerInUnit to \\\" .. status .. \\\" with unknown pilot for plane\\\", 30)\\\
        return \\\
    end\\\
    local pName = limitedAirframes.getKnownUnitPilotByUnitName(uName)\\\
    limitedAirframes.updatePlayer(pName, status)\\\
end\\\
\\\
function limitedAirframes.updatePlayer(pName, status)\\\
    if not pName then \\\
        trigger.action.outText(\\\"+++lim: WARNING - NIL pName in updatePlayer for status \\\" .. status, 30)\\\
        return\\\
    end \\\
    local desc = \\\"\\\"\\\
    if not limitedAirframes.players[pName] then \\\
        desc = \\\"+++lim: NEW player \\\" .. pName .. \\\": \\\" .. status\\\
    else \\\
        if limitedAirframes.players[pName] ~= status then \\\
            desc = \\\"+++lim: CHANGE player \\\" .. pName .. \\\" \\\" .. limitedAirframes.players[pName] .. \\\" -> \\\" .. status\\\
        else \\\
            desc = \\\"+++: player \\\" .. pName .. \\\" no change (\\\" .. status .. \\\")\\\"\\\
        end\\\
    end\\\
    \\\
    limitedAirframes.players[pName] = status \\\
    -- if desc then trigger.action.outText(desc, 30) end \\\
end\\\
\\\
function limitedAirframes.getStatusOfPlayerInUnit(theUnit)\\\
    local uName = theUnit:getName()\\\
    if not limitedAirframes.isKnownUnitName(uName) then \\\
        trigger.action.outText(\\\"+++lim: WARNING get player status for unknown pilot in plane \\\" .. uName, 30)\\\
        return nil\\\
    end\\\
    local pName = limitedAirframes.getKnownUnitPilotByUnitName(uName)\\\
    return limitedAirframes.getStatusOfPlayerNamed(pName)\\\
end\\\
\\\
function limitedAirframes.getStatusOfPlayerNamed(pName)\\\
    return limitedAirframes.players[pName]\\\
end\\\
\\\
--\\\
-- E V E N T   H A N D L I N G \\\
-- \\\
function limitedAirframes.XXXisKnownPlayerUnit(theUnit) \\\
    if not theUnit then return false end \\\
    local aName = theUnit:getName()\\\
    if limitedAirframes.playerUnitNames[aName] ~= nil then \\\
        return true\\\
    end\\\
    return false \\\
end\\\
\\\
function limitedAirframes.isInteresting(eventID) \\\
    -- return true if we are interested in this event, false else \\\
    for key, evType in pairs(limitedAirframes.myEvents) do \\\
        if evType == eventID then return true end\\\
    end\\\
    return false \\\
end\\\
\\\
function limitedAirframes.preProcessor(event)\\\
    -- make sure it has an initiator\\\
    if not event.initiator then return false end -- no initiator \\\
    local theUnit = event.initiator\\\
    local uName = theUnit:getName()\\\
    \\\
\\\
    if event.id == 6 then -- Eject, plane already divorced from player\\\
        if limitedAirframes.isKnownUnitName(uName) then \\\
            --trigger.action.outText(\\\"limAir: detected EJECT for player unit \\\" .. uName .. \\\" player \\\" .. limitedAirframes.getKnownUnitPilotByUnitName(uName), 30)\\\
            return true\\\
        end\\\
        return false -- no longer of interest \\\
    end\\\
    \\\
    if event.id == 5 then -- crash, plane no longer attached to player\\\
        \\\
        if limitedAirframes.isKnownUnitName(uName) then\\\
            --trigger.action.outText(\\\"limAir: detected CRASH for player unit \\\" .. uName .. \\\" player \\\" .. limitedAirframes.getKnownUnitPilotByUnitName(uName), 30)\\\
            return true\\\
        end\\\
        return false -- no longer of interest \\\
    end\\\
    \\\
    \\\
    if not cfxPlayer.isPlayerUnit(theUnit) then \\\
        -- not a player unit. Events 5 and 6 have been\\\
        -- handled before, so we can safely ignore\\\
        return false \\\
    end  \\\
\\\
    -- exclude all ground units\\\
    local theGroup = theUnit:getGroup() \\\
    local cat = theGroup:getCategory()\\\
    if cat == Group.Category.GROUND then \\\
        return false \\\
    end\\\
\\\
    -- only return true if defined as interesting \\\
    return limitedAirframes.isInteresting(event.id) \\\
end\\\
\\\
function limitedAirframes.postProcessor(event)\\\
    -- don't do anything\\\
end\\\
\\\
function limitedAirframes.somethingHappened(event)\\\
    -- when this is invoked, the preprocessor guarantees that\\\
    -- we have:\\\
    -- * an interesting event\\\
    -- * unit is valid and was a player's unit\\\
    \\\
    -- the events that are relevant for pilot loss are:\\\
    -- * player entered: set pilot 'alive' state, maybe add new \\\
    --   unit and pilot to db of players and units \\\
    -- * pilot died - decrease pilot count, set 'dead' state\\\
    -- * eject - decrease pilot count, 'MIA' state, csar possible\\\
    -- * player left - when pilot status 'alive' - check safe zone \\\
    --               - outside safe zone, csar possible, set 'MIA'\\\
    --               - when pilot anything but 'alive' - ignore\\\
    \\\
    if not event.initiator then \\\
        trigger.action.outText(\\\"limAir: ***WARNING: event (\\\" .. ID .. \\\"): no initiator, should not have been procced\\\", 30)\\\
        return \\\
    end\\\
    \\\
    local theUnit = event.initiator\\\
    local unitName = theUnit:getName()\\\
    local ID = event.id\\\
    local myType = theUnit:getTypeName()\\\
    \\\
    -- \\\"20\\\" event (player enter): always processed \\\
--[[--    if ID == 20 or ID == 15 then -- player entered unit\\\
        limitedAirframes.addPlayerUnit(theUnit) -- will also update player and player status to 'alive'\\\
        -- now procc a 'cheater' since we entered a new airframe/pilot\\\
        limitedAirframes.checkPlayerFrameAvailability(event)\\\
        return \\\
    end\\\
--]]--\\\
    \\\
    if ID == 20 then -- 20 ENTER UNIT\\\
        local pName = limitedAirframes.getKnownUnitPilotByUnit(theUnit)\\\
        if not pName then pName = \\\"***UNKNOWN***\\\" end \\\
        --trigger.action.outText(\\\"limAir: Received ENTER UNIT (20) for \\\" .. pName .. \\\" in \\\" .. unitName , 30)\\\
        return \\\
    end\\\
    \\\
    if ID == 15 then -- birth - this one is called in network, 20 is too unreliable\\\
        -- can set where birthed: runway, parking, air etc.\\\
        limitedAirframes.addPlayerUnit(theUnit) -- will also update player and player status to 'alive'\\\
        -- now procc a 'cheater' since we entered a new airframe/pilot\\\
        limitedAirframes.checkPlayerFrameAvailability(event)\\\
        local playerName = theUnit:getPlayerName()\\\
        limitedAirframes.unitFlownByPlayer[unitName] = playerName\\\
        -- TODO: make sure this is the ONLY plane the player\\\
        -- is registered under, and mark mismatches\\\
        trigger.action.outText(\\\"limAir: 15 -- player \\\" .. playerName .. \\\" now in \\\" .. unitName, 30)\\\
        return \\\
    end\\\
    \\\
    -- make sure unit's player pilot is known\\\
    if not limitedAirframes.getKnownUnitPilotByUnitName(unitName) then\\\
        trigger.action.outText(\\\"limAir: ***WARNING: Ignored player event (\\\" .. ID .. \\\"): unable to retrieve player name for \\\" .. unitName, 30)\\\
        return  -- plane no longer of interest cant retrieve pilot -- BUG!!!\\\
    end\\\
    \\\
    \\\
    -- event 6 - eject - plane divorced but player pilot is known\\\
    if ID == 6 then -- eject\\\
        limitedAirframes.pilotEjected(event)            \\\
        return\\\
    end\\\
    \\\
    -- event 5 - crash - plane divorced but player pilot is known \\\
    -- if pilot is still alive, this should now cause a pilot lost event if we are a helicopter \\\
    \\\
    if ID == 5 then -- crash\\\
        -- as of new processing, no longer relevant\\\
        -- limitedAirframes.airFrameCrashed(event) \\\
        -- helicopters do not call died when helo\\\
        -- crashes. so check if we are still seated=alive \\\
        -- and call pilot dead then \\\
        -- for some reason, pilot died also may not be called \\\
        -- so if pilot is still alive and not MIA, he's now dead.\\\
        -- forget the helo check, this now applies to all \\\
\\\
        \\\
        local pStatus = limitedAirframes.getStatusOfPlayerInUnit(theUnit)\\\
        if pStatus == \\\"alive\\\" then \\\
            -- this frame was carrrying a live player \\\
            limitedAirframes.pilotDied(theUnit)\\\
            return \\\
        else \\\
            trigger.action.outText(\\\"limAir: Crash of airframe detected - but player status wasn't alive (\\\" .. pStatus .. \\\")\\\", 30)\\\
            return \\\
        end \\\
    end \\\
\\\
-- removed dual 21 detection here \\\
    \\\
    if ID == 21 then \\\
        -- remove pilot name from unit name \\\
        limitedAirframes.unitFlownByPlayer[unitName] = nil\\\
        --trigger.action.outText(\\\"limAir: 21 -- unit \\\" .. unitName .. \\\" unoccupied\\\", 30)\\\
        \\\
        trigger.action.outText(\\\"limAir: 21 (player left) for unit \\\" .. unitName , 30)\\\
        -- player left unit. Happens twice\\\
        -- check if player alive, else we have a ditch.\\\
        limitedAirframes.handlePlayerLeftUnit(event)\\\
        return \\\
    end\\\
    \\\
    \\\
    if ID == 9 then -- died \\\
        --trigger.action.outText(\\\"limAir: 9 (PILOT DEAD) for unit \\\" .. unitName , 30)\\\
        local thePilot = limitedAirframes.unitFlownByPlayer[unitName]\\\
        if not thePilot then \\\
            trigger.action.outText(\\\"+++limAir: 9 O'RIDE -- unit \\\" .. unitName .. \\\" was legally vacated before!\\\", 30)\\\
            return \\\
        end\\\
        limitedAirframes.pilotDied(theUnit)\\\
        return \\\
    end\\\
    \\\
    if ID == 30 then -- unit lost\\\
        return \\\
    end\\\
    \\\
\\\
    \\\
    trigger.action.outText(\\\"limAir: WARNING unhandled: \\\" .. ID .. \\\" for player unit \\\" .. theUnit:getName() .. \\\" of type \\\" .. myType, 30)\\\
end\\\
\\\
--\\\
-- HANDLE VARIOUS SITUATIONS\\\
--\\\
\\\
function limitedAirframes.handlePlayerLeftUnit(event)\\\
    local theUnit = event.initiator\\\
    -- make sure the pilot is alive\\\
    if limitedAirframes.getStatusOfPlayerInUnit(theUnit) ~= \\\"alive\\\" then \\\
        -- was already handled. simply exit\\\
        local pName = limitedAirframes.getKnownUnitPilotByUnitName(theUnit:getName())\\\
        local pStatus = limitedAirframes.getStatusOfPlayerInUnit(theUnit)\\\
        -- player was already dead and has been accounted for \\\
        --trigger.action.outText(\\\"limAir: Change Plane for player <\\\" .. pName .. \\\"> with status <\\\" .. pStatus .. \\\"> procced.\\\", 30)\\\
        return \\\
    end\\\
    \\\
    -- check if the unit was inside a safe zone\\\
    -- if so, graceful exit \\\
    local uPos = theUnit:getPoint() \\\
    local meInside = cfxZones.getZonesContainingPoint(uPos, limitedAirframes.safeZones)\\\
    local mySide = theUnit:getCoalition()\\\
    --local speed = dcsCommon.getUnitSpeed(theUnit) -- this can cause problems with carriers, so check if below \\\
    --local agl = dcsCommon.getUnitAGL(theUnit) -- this will cause problems with FARP and carriers. \\\
    -- we now check the inAir \\\
    local isInAir = theUnit:inAir()\\\
    --trigger.action.outTextForCoalition(mySide, \\\"limAir: safe check for Pilot \\\" .. theUnit:getPlayerName() .. \\\": agl=\\\" .. agl .. \\\", speed = \\\" .. speed .. \\\", air status = \\\" .. dcsCommon.bool2YesNo(isInAir), 30)\\\
\\\
    for i=1, #meInside do \\\
        -- I'm inside all these zones. We look for the first\\\
        -- that saves me \\\
        local theSafeZone = meInside[i]\\\
        local isSafe = false\\\
        if mySide == 1 then \\\
            isSafe = theSafeZone.redSafe \\\
        elseif mySide == 2 then \\\
            isSafe = theSafeZone.blueSafe\\\
        else \\\
            isSafe = true \\\
        end\\\
        \\\
        if theSafeZone.owner then\\\
            -- owned zone. olny allow in neutral or owned by same side \\\
            isSafe = isSafe and (mySide == theSafeZone.owner or theSafeZone.owner == 0)\\\
            trigger.action.outText(\\\"+++: Lim - \\\" .. theSafeZone.name .. \\\" ownership: myside = \\\" .. mySide .. \\\" zone owner is \\\" .. theSafeZone.owner, 30)\\\
        else \\\
            -- trigger.action.outText(\\\"+++: Zone \\\" .. theSafeZone.name .. \\\" has no ownership, skipping check\\\", 30)\\\
        end\\\
        \\\
        -- check we are at rest below 10m height. agl may give \\\
        -- misreadings on carriers and FARPs, while speed may read\\\
        -- wrongly on carriers (tbd). we now use isInAir to determine if\\\
        -- we ditched while in flight \\\
        --if speed > 2 or agl > 10 then isSafe = false end \\\
        --if not isInAir then return false end -- why *not* isInAir??? \\\
        \\\
        -- for matter of fact, why did we return ANYTHING???\\\
        -- there may be a bug here \\\
        -- maybe it should be \\\"if isInAir then isSafe = false\\\"??\\\
        if isInAir then isSafe = false end \\\
        \\\
        if isSafe then \\\
            trigger.action.outTextForCoalition(mySide, \\\"limAir: Pilot \\\" .. theUnit:getPlayerName() .. \\\" left unit \\\" .. theUnit:getName() .. \\\" legally in zone \\\" .. theSafeZone.name, 30)\\\
            -- remove from known player planes\\\
            -- no more limitedAirframes.removePlayerUnit(theUnit)\\\
            return;\\\
        end\\\
    end\\\
    \\\
    -- ditched outside safe harbour\\\
    trigger.action.outTextForCoalition(mySide, \\\"Pilot \\\" .. theUnit:getPlayerName() .. \\\" DITCHED unit \\\" .. theUnit:getName() .. \\\" -- PILOT LOSS (MIA)\\\", 30)\\\
    limitedAirframes.pilotLost(theUnit)\\\
    if csarManager and csarManager.airframeDitched then \\\
        csarManager.airframeDitched(theUnit)\\\
    end\\\
    \\\
    limitedAirframes.updatePlayerInUnit(theUnit, \\\"MIA\\\") -- cosmetic only\\\
    limitedAirframes.createCSAR(theUnit)\\\
end\\\
\\\
\\\
\\\
function limitedAirframes.pilotEjected(event)\\\
    local theUnit = event.initiator\\\
    -- do we want to check location?\\\
    -- no. if the user ejects, plane is done for\\\
    local theSide = theUnit:getCoalition()\\\
    local pilot = limitedAirframes.getKnownUnitPilotByUnit(theUnit)\\\
    local uName = theUnit:getName()\\\
    trigger.action.outTextForCoalition(theSide, \\\"Pilot <\\\" .. pilot .. \\\"> ejected from \\\" .. uName .. \\\", now MIA\\\", 30)\\\
    \\\
    local hasLostTheWar = limitedAirframes.pilotLost(theUnit)\\\
    \\\
    limitedAirframes.updatePlayerInUnit(theUnit, \\\"MIA\\\") -- cosmetic only\\\
    -- create CSAR if applicable\\\
    if not hasLostTheWar then \\\
        limitedAirframes.createCSAR(theUnit)\\\
    end \\\
end\\\
\\\
function limitedAirframes.pilotDied(theUnit)\\\
    --limitedAirframes.killPlayerInUnit(theUnit)\\\
    local theSide = theUnit:getCoalition()\\\
    local pilot = limitedAirframes.getKnownUnitPilotByUnit(theUnit)\\\
    local uName = theUnit:getName()\\\
    trigger.action.outTextForCoalition(theSide, \\\"Pilot <\\\" .. pilot .. \\\"> is confirmed KIA while controlling \\\" .. uName, 30)\\\
    limitedAirframes.pilotLost(theUnit)\\\
end\\\
\\\
function limitedAirframes.pilotLost(theUnit)\\\
    -- returns true if lost the war \\\
    -- MUST NOT MESSAGE PILOT STATUS AS MIA CAN ALSO BE SET\\\
    -- first DELETE THE UNIT FROM player-owned unit table\\\
    -- so an empty crash after eject/death will not be counted as two losses\\\
    limitedAirframes.killPlayerInUnit(theUnit)\\\
\\\
    -- now see if we are enabled to limit airframes \\\
    if not limitedAirframes.enabled then return false end \\\
    \\\
    -- find out which side lost the airframe and message side\\\
    local theSide = theUnit:getCoalition()\\\
    local pilot = limitedAirframes.getKnownUnitPilotByUnit(theUnit)\\\
    local uName = theUnit:getName()\\\
    --trigger.action.outTextForCoalition(theSide, \\\"Pilot <\\\" .. pilot .. \\\"> is confirmed KIA while controlling \\\" .. uName, 30)\\\
    \\\
    if theSide == 1 then -- red \\\
        theOtherSide = 2 \\\
        if     limitedAirframes.maxRed < 0 then return false end -- disabled/infinite\\\
        \\\
        limitedAirframes.currRed = limitedAirframes.currRed - 1\\\
        \\\
        if limitedAirframes.currRed == 0 then\\\
            trigger.action.outTextForCoalition(theSide, \\\"\\\\nYou have lost almost all of your pilots.\\\\n\\\\nWARNING: Losing any more pilots WILL FAIL THE MISSION\\\\n\\\", 30)\\\
            trigger.action.outSoundForCoalition(theSide, \\\"Quest Snare 3.wav\\\")\\\
            return false  \\\
        end\\\
        \\\
        if limitedAirframes.currRed < 0 then \\\
            -- red have lost all airframes \\\
            trigger.action.outText(\\\"\\\\nREDFORCE has lost all of their pilots.\\\\n\\\\nBLUEFORCE WINS!\\\\n\\\", 30)\\\
            trigger.action.outSoundForCoalition(theSide, \\\"Death PIANO.wav\\\")\\\
            trigger.action.outSoundForCoalition(theOtherSide, \\\"Triumphant Victory.wav\\\")\\\
            trigger.action.setUserFlag(limitedAirframes.blueWinsFlag, 1 )\\\
            return true \\\
        end\\\
        \\\
        \\\
    elseif theSide == 2 then -- blue \\\
        theOtherSide = 1\\\
        if     limitedAirframes.maxBlue < 0 then return false end -- disabled/infinite\\\
        limitedAirframes.currBlue = limitedAirframes.currBlue - 1\\\
        if limitedAirframes.currBlue == 0 then\\\
            trigger.action.outTextForCoalition(theSide, \\\"\\\\nYou have lost almost all of your pilots.\\\\n\\\\nWARNING: Losing any more pilots WILL FAIL THE MISSION\\\\n\\\", 30)\\\
            trigger.action.outSoundForCoalition(theSide, \\\"Quest Snare 3.wav\\\")\\\
            return false \\\
        end\\\
        if limitedAirframes.currBlue < 0 then \\\
            -- red have lost all airframes \\\
            trigger.action.outText(\\\"\\\\nBLUEFORCE has lost all of their pilots.\\\\n\\\\nREDFORCE WINS!\\\\n\\\", 30)\\\
            trigger.action.setUserFlag(limitedAirframes.redWinsFlag, 1 )\\\
            trigger.action.outSoundForCoalition(theSide, \\\"Death PIANO.wav\\\")\\\
            trigger.action.outSoundForCoalition(theOtherSide, \\\"Triumphant Victory.wav\\\")\\\
            return true \\\
        end\\\
        trigger.action.outSoundForCoalition(theSide, \\\"Quest Snare 3.wav\\\")\\\
        trigger.action.outTextForCoalition(theSide, \\\"You have lost a pilot! Remaining: \\\" .. limitedAirframes.currBlue, 30)\\\
    end\\\
    return false \\\
end\\\
\\\
function limitedAirframes.checkPlayerFrameAvailability(event)\\\
    local theUnit = event.initiator\\\
    local theSide = theUnit:getCoalition()\\\
    if theSide == 1 then -- red \\\
        if     limitedAirframes.maxRed < 0 then return end -- disabled/infinite\\\
        if limitedAirframes.currRed < 0 then \\\
            -- red have lost all airframes \\\
            trigger.action.outText(\\\"\\\\nREDFORCE is a CHEATER!\\\\n\\\", 30)\\\
            return \\\
        end\\\
    elseif theSide == 2 then -- blue \\\
        if     limitedAirframes.maxBlue < 0 then return end -- disabled/infinite\\\
        if limitedAirframes.currBlue < 0 then \\\
            -- red have lost all airframes \\\
            trigger.action.outText(\\\"\\\\nBLUEFORCE is a CHEATER!\\\\n\\\", 30)\\\
            return \\\
        end\\\
    end\\\
end\\\
\\\
\\\
function limitedAirframes.createCSAR(theUnit)\\\
    -- only do this if we have installed CSAR Manager\\\
    if csarManager and csarManager.createCSARforUnit then \\\
        csarManager.createCSARforUnit(theUnit, \\\
            limitedAirframes.getKnownUnitPilotByUnit(theUnit),\\\
            100)\\\
    end\\\
end\\\
\\\
-- start up\\\
\\\
function limitedAirframes.addSafeZone(aZone)\\\
    if not aZone then \\\
        trigger.action.outText(\\\"WARNING: NIL Zone in addSafeZone\\\", 30)\\\
        return \\\
    end\\\
\\\
    -- transfer properties if they exist \\\
    -- blueSafe, redSafe: what side this is safe for, default = yes \\\
    \\\
    -- add zone to my list\\\
    limitedAirframes.safeZones[aZone] = aZone \\\
    aZone.redSafe = true\\\
    aZone.redSafe = cfxZones.getBoolFromZoneProperty(aZone, \\\"redSafe\\\", true)\\\
    aZone.blueSafe = true \\\
    aZone.blueSafe = cfxZones.getBoolFromZoneProperty(aZone, \\\"blueSafe\\\", true)\\\
\\\
    trigger.action.outText(\\\"limAir: added safeZone \\\" .. aZone.name, 30)\\\
end\\\
\\\
\\\
\\\
--\\\
-- COMMAND & CONFIGURATION\\\
--\\\
function limitedAirframes.setCommsMenu()\\\
    local desc = \\\"Pilot Count (Currently ON)\\\"\\\
    local desc2 = \\\"Turn OFF Pilot Count (Cheat)?\\\"\\\
    if not limitedAirframes.enabled then \\\
        desc = \\\"Pilot Count (Currently OFF)\\\"\\\
        desc2 = \\\"ENABLE Pilot Count\\\"\\\
    end\\\
    -- remove previous version\\\
    if limitedAirframes.rootMenu then \\\
        missionCommands.removeItem(limitedAirframes.theScore)\\\
        missionCommands.removeItem(limitedAirframes.theCommand)\\\
        missionCommands.removeItem(limitedAirframes.rootMenu)\\\
    end\\\
    limitedAirframes.theCommand = nil\\\
    limitedAirframes.rootMenu = nil \\\
    \\\
    -- add current version menu and command\\\
    limitedAirframes.rootMenu = missionCommands.addSubMenu(desc, nil)\\\
    \\\
    limitedAirframes.theScore = missionCommands.addCommand(\\\"How many airframes left?\\\" , limitedAirframes.rootMenu, limitedAirframes.redirectAirframeScore, {\\\"none\\\"})\\\
    \\\
    limitedAirframes.theCommand = missionCommands.addCommand(desc2 , limitedAirframes.rootMenu, limitedAirframes.redirectToggleAirFrames, {\\\"none\\\"})\\\
    \\\
end\\\
\\\
function limitedAirframes.redirectAirframeScore(args)\\\
    timer.scheduleFunction(limitedAirframes.doAirframeScore, args, timer.getTime() + 0.1)\\\
end\\\
\\\
function limitedAirframes.doAirframeScore(args)\\\
    local redRemaining = \\\"unlimited\\\"\\\
    if limitedAirframes.maxRed >= 0 then \\\
        redRemaining = limitedAirframes.currRed .. \\\" of \\\" .. limitedAirframes.maxRed\\\
        if limitedAirframes.currRed < 1 then \\\
            redRemaining = \\\"no\\\"\\\
        end\\\
    end\\\
    \\\
    local blueRemaining = \\\"unlimited\\\"\\\
    if limitedAirframes.maxBlue >= 0 then \\\
        blueRemaining = limitedAirframes.currBlue .. \\\" of \\\" .. limitedAirframes.maxBlue\\\
        if limitedAirframes.currBlue < 1 then \\\
            blueRemaining = \\\"no\\\"\\\
        end\\\
    end\\\
    \\\
    local msg = \\\"\\\\nRED has \\\" .. redRemaining .. \\\" pilots left,\\\\nBLUE has \\\" .. blueRemaining .. \\\" pilots left\\\\n\\\"\\\
    trigger.action.outText(msg, 30, true)\\\
    trigger.action.outSound(\\\"Quest Snare 3.wav\\\")\\\
end\\\
\\\
function limitedAirframes.redirectToggleAirFrames(args)\\\
    timer.scheduleFunction(limitedAirframes.doToggleAirFrames, args, timer.getTime() + 0.1)\\\
end\\\
\\\
function limitedAirframes.doToggleAirFrames(args)\\\
    limitedAirframes.enabled = not limitedAirframes.enabled\\\
    limitedAirframes.setCommsMenu()\\\
    local desc = \\\"\\\\n\\\\nPilot Count rule NOW IN EFFECT\\\\n\\\\n\\\"\\\
    \\\
    if limitedAirframes.enabled then \\\
        trigger.action.outSound(\\\"Quest Snare 3.wav\\\")\\\
    else\\\
        desc = \\\"\\\\n\\\\nYou cowardly disabled Pilot Count\\\\n\\\\n\\\"\\\
        trigger.action.outSound(\\\"Death PIANO.wav\\\")\\\
    end\\\
    trigger.action.outText(desc, 30)\\\
    limitedAirframes.setCommsMenu()\\\
end\\\
\\\
--\\\
-- CSAR CALLBACK\\\
--\\\
\\\
function limitedAirframes.pilotsRescued(theCoalition, success, numRescued, notes)\\\
    local availablePilots = 0\\\
    if theCoalition == 1 then -- red \\\
        limitedAirframes.currRed = limitedAirframes.currRed + numRescued\\\
        if limitedAirframes.currRed > limitedAirframes.maxRed then \\\
            limitedAirframes.currRed = limitedAirframes.maxRed \\\
        end\\\
        availablePilots = limitedAirframes.currRed\\\
        if limitedAirframes.maxRed < 0 then \\\
            availablePilots = \\\"unlimited\\\"\\\
        end \\\
    end\\\
    \\\
    if theCoalition == 2 then -- blue \\\
        limitedAirframes.currBlue = limitedAirframes.currBlue + numRescued\\\
        if limitedAirframes.currBlue > limitedAirframes.maxBlue then \\\
            limitedAirframes.currBlue = limitedAirframes.maxBlue \\\
        end\\\
        availablePilots = limitedAirframes.currBlue\\\
        if limitedAirframes.maxBlue < 0 then \\\
            availablePilots = \\\"unlimited\\\"\\\
        end \\\
    end\\\
    trigger.action.outTextForCoalition(theCoalition, \\\"\\\\nPilots returned to flight line, you now have \\\" .. availablePilots..\\\".\\\\n\\\", 30)\\\
    trigger.action.outSoundForCoalition(theCoalition, \\\"Quest Snare 3.wav\\\")\\\
end\\\
\\\
--\\\
-- START \\\
--\\\
\\\
function limitedAirframes.start()\\\
    if not dcsCommon.libCheck(\\\"cfx Limited Airframes\\\", \\\
        limitedAirframes.requiredLibs) then\\\
        return false \\\
    end\\\
    \\\
    -- override config settings if defined as zone\\\
    limitedAirframes.readConfigZone()\\\
    \\\
    -- collect all zones that are airframe safe \\\
    local afsZones = cfxZones.zonesWithProperty(\\\"pilotSafe\\\")\\\
    \\\
    -- now add all zones to my zones table, and init additional info\\\
    -- from properties\\\
    for k, aZone in pairs(afsZones) do\\\
        limitedAirframes.addSafeZone(aZone)\\\
    end\\\
    \\\
    -- connect player callback \\\
    -- install callbacks for airframe-related events\\\
    dcsCommon.addEventHandler(limitedAirframes.somethingHappened, limitedAirframes.preProcessor, limitedAirframes.postProcessor)\\\
    \\\
    \\\
    -- set current values\\\
    limitedAirframes.currRed = limitedAirframes.maxRed\\\
    limitedAirframes.currBlue = limitedAirframes.maxBlue\\\
    \\\
    -- collect active player unit names \\\
    local allPlayerUnits = cfxPlayer.getAllExistingPlayerUnitsRaw()\\\
    for i=1, #allPlayerUnits do \\\
        local aUnit = allPlayerUnits[i]\\\
        limitedAirframes.addPlayerUnit(aUnit)\\\
--        trigger.action.outText(\\\"limAir: detected active player unit \\\" .. aUnit:getName(), 30)\\\
    end\\\
    \\\
    \\\
    -- allow configuration menu \\\
    if limitedAirframes.userCanToggle then     \\\
        limitedAirframes.setCommsMenu()\\\
    end\\\
    \\\
    -- connect to csarManager if present \\\
    if csarManager and csarManager.installCallback then \\\
        csarManager.installCallback(limitedAirframes.pilotsRescued)\\\
        trigger.action.outText(\\\"+++lim: connected to csar manager\\\", 30)\\\
    else \\\
        trigger.action.outText(\\\"+++lim: NO CSAR integration\\\", 30)\\\
    end\\\
    \\\
    -- say hi\\\
    trigger.action.outText(\\\"limitedAirframes v\\\" .. limitedAirframes.version .. \\\" started: R:\\\".. limitedAirframes.maxRed .. \\\"/B:\\\" .. limitedAirframes.maxBlue, 30)\\\
    return true \\\
end\\\
\\\
if not limitedAirframes.start() then \\\
    limitedAirframes = nil\\\
    trigger.action.outText(\\\"cf/x Limited Airframes aborted: missing libraries\\\", 30)\\\
end\\\
\\\
\\\
\\\
--[[--\\\
   safe ditch: check airspeed and altitude. ditch only counts if less than 10m and 2 kts \\\
   report number of airframes left via second instance in switch off menu\\\
--]]--\");a_do_script(\"cfxPlayerScore = {}\\\
cfxPlayerScore.version = \\\"1.3.0\\\"\\\
cfxPlayerScore.badSound = \\\"Death BRASS.wav\\\"\\\
cfxPlayerScore.scoreSound = \\\"Quest Snare 3.wav\\\"\\\
cfxPlayerScore.announcer = true \\\
--[[-- VERSION HISTORY\\\
    1.0.1 - bug fixes to killDetected \\\
    1.0.2 - messaging clean-up, less verbose \\\
    1.1.0 - integrated score base system\\\
          - accepts configZones \\\
          - module validation \\\
          - isNamedUnit(theUnit)\\\
          - notify if named unit killed \\\
          - kill weapon reported \\\
    1.2.0 - score table \\\
          - announcer attribute \\\
          - badSound name \\\
          - scoreSound name \\\
    1.3.0 - object2score \\\
          - static objects also can score \\\
          - can now also score members of group by adding group name \\\
          - scenery objects are now supported. use the \\\
            number that is given under OBJECT ID when \\\
            using assign as...\\\
    \\\
          \\\
--]]--\\\
cfxPlayerScore.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- this is doing score keeping\\\
    \\\"cfxPlayer\\\", -- player events, comms \\\
    \\\"cfxZones\\\", -- zones for config \\\
}\\\
cfxPlayerScore.playerScore = {} -- init to empty\\\
\\\
-- typeScore: dictionary sorted by typeString for score \\\
-- extend to add more types. It is used by unitType2score to \\\
-- determine the base unit score  \\\
cfxPlayerScore.typeScore = {}\\\
 \\\
--\\\
-- we subscribe to the kill event. each time a unit \\\
-- is killed, we check if it was killed by a player\\\
-- and if so, that player record is updated and the side\\\
-- whom the player belongs to is informed\\\
--\\\
cfxPlayerScore.aircraft = 50 \\\
cfxPlayerScore.helo = 40 \\\
cfxPlayer.ground = 10\\\
cfxPlayerScore.ship = 80 \\\
cfxPlayerScore.train = 5 \\\
\\\
function cfxPlayerScore.cat2BaseScore(inCat)\\\
    if inCat == 0 then return cfxPlayerScore.aircraft end -- airplane\\\
    if inCat == 1 then return cfxPlayerScore.helo end -- helo \\\
    if inCat == 2 then return cfxPlayer.ground end -- ground \\\
    if inCat == 3 then return cfxPlayerScore.ship end -- ship \\\
    if inCat == 4 then return cfxPlayerScore.train end -- train \\\
    \\\
    trigger.action.outText(\\\"+++scr c2bs: unknown category for lookup: <\\\" .. inCat .. \\\">, returning 1\\\", 30)\\\
    \\\
    return 1 \\\
end\\\
\\\
function cfxPlayerScore.object2score(inVictim) -- does not have group\\\
    if not inVictim then return end \\\
    local inName = inVictim:getName()\\\
    if not inName then return 0 end \\\
    if type(inName) == \\\"number\\\" then \\\
        inName = tostring(inName)\\\
    end\\\
        \\\
    local objectScore = cfxPlayerScore.typeScore[inName]\\\
    if not objectScore then \\\
        -- try the type desc \\\
        local theType = inVictim:getTypeName()\\\
        objectScore = cfxPlayerScore.typeScore[theType]\\\
    end\\\
    \\\
    if type(objectScore) == \\\"string\\\" then \\\
        objectScore = tonumber(objectScore)\\\
    end\\\
    if not objectScore then return 0 end \\\
    return objectScore \\\
end\\\
\\\
function cfxPlayerScore.unit2score(inUnit)\\\
    local vicGroup = inUnit:getGroup()\\\
    local vicCat = vicGroup:getCategory()\\\
    local vicType = inUnit:getTypeName()\\\
    local vicName = inUnit:getName() \\\
    if type(vicName) == \\\"number\\\" then vicName = tostring(vicName) end \\\
    \\\
    -- simply extend by adding items to the typescore table.concat\\\
    -- we first try by unit name. This allows individual\\\
    -- named hi-value targets to have individual scores \\\
    local uScore = cfxPlayerScore.typeScore[vicName]\\\
\\\
    -- see if all members of group score \\\
    if not uScore then \\\
        local grpName = vicGroup:getName()\\\
        uScore = cfxPlayerScore.typeScore[grpName]\\\
    end\\\
    \\\
    if uScore == nil then \\\
        -- WE NOW TRY TO ACCESS BY VICTIM'S TYPE STRING        \\\
        uScore = cfxPlayerScore.typeScore[vicType]\\\
    else \\\
\\\
    end \\\
    if type(uScore) == \\\"string\\\" then \\\
        -- convert string to number \\\
        uScore = tonumber(uScore)\\\
    end\\\
\\\
    if uScore == nil then uScore = 0 end \\\
    if uScore > 0 then return uScore end \\\
    \\\
    -- only apply base scores when the lookup did not give a result\\\
    uScore = cfxPlayerScore.cat2BaseScore(vicCat)\\\
    return uScore \\\
end\\\
\\\
function cfxPlayerScore.getPlayerScore(playerName)\\\
    local thePlayerScore = cfxPlayerScore.playerScore[playerName]\\\
    if thePlayerScore == nil then \\\
        thePlayerScore = {}\\\
        thePlayerScore.name = playerName\\\
        thePlayerScore.score = 0 -- score\\\
        thePlayerScore.killTypes = {} -- the type strings killed\\\
        thePlayerScore.totalKills = 0 -- number of kills total \\\
    end\\\
    return thePlayerScore\\\
end\\\
\\\
function cfxPlayerScore.setPlayerScore(playerName, thePlayerScore)\\\
    cfxPlayerScore.playerScore[playerName] = thePlayerScore\\\
end\\\
\\\
function cfxPlayerScore.updateScoreForPlayer(playerName, score)\\\
    local thePlayerScore = cfxPlayerScore.getPlayerScore(playerName)\\\
    \\\
    thePlayerScore.score = thePlayerScore.score + score\\\
    cfxPlayerScore.setPlayerScore(playerName, thePlayerScore)\\\
    return thePlayerScore.score \\\
end\\\
\\\
function cfxPlayerScore.logKillForPlayer(playerName, theUnit)\\\
    if not theUnit then return end\\\
    if not playerName then return end \\\
    \\\
    local thePlayerScore = cfxPlayerScore.getPlayerScore(playerName)\\\
    \\\
    local theType = theUnit:getTypeName()\\\
    local killCount = thePlayerScore.killTypes[theType]\\\
    if killCount == nil then \\\
        killCount = 0\\\
    end\\\
    killCount = killCount + 1\\\
    thePlayerScore.totalKills = thePlayerScore.totalKills + 1\\\
    thePlayerScore.killTypes[theType] = killCount\\\
    \\\
    cfxPlayerScore.setPlayerScore(playerName, thePlayerScore)\\\
end\\\
\\\
function cfxPlayerScore.playerScore2text(thePlayerScore)\\\
    local desc = thePlayerScore.name .. \\\" - score: \\\".. thePlayerScore.score .. \\\" - kills: \\\" .. thePlayerScore.totalKills .. \\\"\\\\n\\\"\\\
    -- now go through all killSide\\\
    for theType, quantity in pairs(thePlayerScore.killTypes) do \\\
        desc = desc .. \\\"  - \\\" .. theType .. \\\": \\\" .. quantity .. \\\"\\\\n\\\"\\\
    end\\\
    return desc\\\
end\\\
\\\
function cfxPlayerScore.scoreTextForPlayerNamed(playerName)\\\
    local thePlayerScore = cfxPlayerScore.getPlayerScore(playerName)\\\
    return cfxPlayerScore.playerScore2text(thePlayerScore)\\\
end\\\
\\\
function cfxPlayerScore.isNamedUnit(theUnit) \\\
    if not theUnit then return false end \\\
    local theName = \\\"(cfx_none)\\\"\\\
    if type(theUnit) == \\\"string\\\" then \\\
        theName = theUnit -- direct name assignment\\\
        -- WARNING: NO EXIST CHECK DONE!\\\
    else \\\
        -- after kill, unit is dead, so will no longer exist!\\\
        theName = theUnit:getName() \\\
        if not theName then return false end \\\
    end\\\
    if cfxPlayerScore.typeScore[theName] then \\\
        return true\\\
    end\\\
    return false \\\
end\\\
\\\
function cfxPlayerScore.awardScoreTo(killSide, theScore, killerName)\\\
    local playerScore = cfxPlayerScore.updateScoreForPlayer(killerName, theScore)\\\
    \\\
    if cfxPlayerScore.announcer then \\\
        trigger.action.outTextForCoalition(killSide, \\\"Killscore:  \\\" .. theScore .. \\\" for a total of \\\" .. playerScore .. \\\" for \\\" .. killerName, 30)\\\
    end \\\
end\\\
--\\\
-- EVENT HANDLING\\\
--\\\
function cfxPlayerScore.preProcessor(theEvent)\\\
    -- return true if the event should be processed\\\
    -- by us\\\
    \\\
    if theEvent.id == 28 then\\\
        -- we only are interested in kill events where \\\
        -- there is an initiator, and the initiator is \\\
        -- a player \\\
        if theEvent.initiator  == nil then \\\
            return false \\\
        end \\\
        \\\
        local killer = theEvent.initiator \\\
        if theEvent.target == nil then \\\
            if cfxPlayerScore.verbose then \\\
                trigger.action.outText(\\\"+++scr pre: nil TARGET\\\", 30) \\\
            end \\\
            return false \\\
        end \\\
        \\\
        local wasPlayer = cfxPlayer.isPlayerUnit(killer)\\\
        return wasPlayer\\\
    end\\\
    return false \\\
end\\\
\\\
function cfxPlayerScore.postProcessor(theEvent)\\\
    -- don't do anything\\\
end\\\
\\\
function cfxPlayerScore.killDetected(theEvent)\\\
    -- we are only getting called when and if \\\
    -- a kill occured and killer was a player \\\
    -- and target exists\\\
    \\\
    local killer = theEvent.initiator\\\
    local killerName = killer:getPlayerName()\\\
    if not killerName then killerName = \\\"<nil>\\\" end\\\
    local killSide = killer:getCoalition()\\\
    local killVehicle = killer:getTypeName()\\\
    if not killVehicle then killVehicle = \\\"<nil>\\\" end \\\
    local victim = theEvent.target\\\
\\\
    -- was it a player kill?\\\
    local pk = cfxPlayer.isPlayerUnit(victim)\\\
\\\
    -- was it a scenery object? \\\
    local wasBuilding = dcsCommon.isSceneryObject(victim)\\\
    if wasBuilding then \\\
        -- these objects have no coalition; we simply award the score if \\\
        -- it exists in look-up table. \\\
        local staticScore = cfxPlayerScore.object2score(victim)\\\
        if staticScore > 0 then \\\
            trigger.action.outSoundForCoalition(killSide, cfxPlayerScore.scoreSound)\\\
            cfxPlayerScore.awardScoreTo(killSide, staticScore, killerName)\\\
        end\\\
        return \\\
    end\\\
\\\
    -- was it fraternicide?\\\
    local vicSide = victim:getCoalition()\\\
    local fraternicide = killSide == vicSide\\\
    local vicDesc = victim:getTypeName()\\\
    local scoreMod = 1 -- start at one \\\
\\\
    -- see what kind of unit (category) we killed\\\
    -- and look up base score \\\
    if not victim.getGroup then\\\
        -- static objects have no group \\\
\\\
        local staticName = victim:getName() -- on statics, this returns \\\
                                            -- name as entered in TOP LINE\\\
        local staticScore = cfxPlayerScore.object2score(victim)\\\
        if staticScore > 0 then \\\
            -- this was a named static, return the score - unless our own\\\
            if fraternicide then \\\
                scoreMod = -2 * scoreMod \\\
                trigger.action.outSoundForCoalition(killSide, cfxPlayerScore.badSound)\\\
            else \\\
                trigger.action.outSoundForCoalition(killSide, cfxPlayerScore.scoreSound)\\\
            end\\\
            staticScore = scoreMod * staticScore\\\
            cfxPlayerScore.awardScoreTo(killSide, staticScore, killerName)\\\
        else \\\
            -- no score, no mentions\\\
        end\\\
        \\\
        return \\\
    end \\\
    \\\
    local vicGroup = victim:getGroup()\\\
    local vicCat = vicGroup:getCategory()\\\
    local unitScore = cfxPlayerScore.unit2score(victim)\\\
\\\
    -- see which weapon was used. gun kills score 2x \\\
    local killMeth = \\\"\\\"\\\
    local killWeap = theEvent.weapon\\\
    if killWeap then \\\
        local killWeapType = killWeap:getCategory()\\\
        if killWeapType == 0 then \\\
            killMeth = \\\" with GUNS\\\" \\\
            scoreMod = scoreMod * 2\\\
        else \\\
            local kWeapon = killWeap:getTypeName()\\\
            killMeth = \\\" with \\\" .. kWeapon\\\
        end\\\
    else \\\
        \\\
    end\\\
    \\\
    if pk then \\\
        vicDesc = victim:getPlayerName() .. \\\" in \\\" .. vicDesc \\\
        scoreMod = scoreMod * 10\\\
    end \\\
    \\\
    if fraternicide then\\\
        scoreMod = scoreMod * -2\\\
        if cfxPlayerScore.announcer then \\\
            trigger.action.outTextForCoalition(killSide, killerName .. \\\" in \\\" .. killVehicle .. \\\" killed FRIENDLY \\\" .. vicDesc .. killMeth .. \\\"!\\\", 30)\\\
            trigger.action.outSoundForCoalition(killSide, cfxPlayerScore.badSound)\\\
        end \\\
    else \\\
        if cfxPlayerScore.announcer then \\\
            trigger.action.outText(killerName .. \\\" in \\\" .. killVehicle ..\\\" killed \\\" .. vicDesc .. killMeth ..\\\"!\\\", 30)\\\
            trigger.action.outSoundForCoalition(vicSide, cfxPlayerScore.badSound)\\\
            trigger.action.outSoundForCoalition(killSide, cfxPlayerScore.scoreSound)\\\
         end \\\
         -- since not fraticide, log this kill\\\
         -- logging kills does not impct score\\\
         cfxPlayerScore.logKillForPlayer(killerName, victim)\\\
    end\\\
    \\\
    -- see if it was a named target \\\
    if cfxPlayerScore.isNamedUnit(victim) then \\\
        if cfxPlayerScore.announcer then \\\
            trigger.action.outTextForCoalition(killSide, killerName .. \\\" reports killing strategic unit '\\\" .. victim:getName() .. \\\"'\\\", 30)\\\
        end \\\
    end\\\
    \\\
    local totalScore = unitScore * scoreMod\\\
    cfxPlayerScore.awardScoreTo(killSide, totalScore, killerName)\\\
\\\
end\\\
\\\
function cfxPlayerScore.readConfigZone(theZone)\\\
    cfxPlayerScore.verbose = cfxZones.getBoolFromZoneProperty(theZone, \\\"verbose\\\", false)\\\
    -- default scores \\\
    cfxPlayerScore.aircraft = cfxZones.getNumberFromZoneProperty(theZone, \\\"aircraft\\\", 50) \\\
    cfxPlayerScore.helo = cfxZones.getNumberFromZoneProperty(theZone, \\\"helo\\\", 40)  \\\
    cfxPlayer.ground = cfxZones.getNumberFromZoneProperty(theZone, \\\"ground\\\", 10)  \\\
    cfxPlayerScore.ship = cfxZones.getNumberFromZoneProperty(theZone, \\\"ship\\\", 80)   \\\
    cfxPlayerScore.train = cfxZones.getNumberFromZoneProperty(theZone, \\\"train\\\", 5)\\\
    \\\
    cfxPlayerScore.announcer = cfxZones.getBoolFromZoneProperty(theZone, \\\"announcer\\\", true)\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"badSound\\\") then \\\
        cfxReconMode.badSound = cfxZones.getStringFromZoneProperty(theZone, \\\"badSound\\\", \\\"<nosound>\\\")\\\
    end\\\
    if cfxZones.hasProperty(theZone, \\\"scoreSound\\\") then \\\
        cfxReconMode.scoreSound = cfxZones.getStringFromZoneProperty(theZone, \\\"scoreSound\\\", \\\"<nosound>\\\")\\\
    end\\\
end\\\
\\\
function cfxPlayerScore.start()\\\
    if not dcsCommon.libCheck(\\\"cfx Player Score\\\", \\\
                              cfxPlayerScore.requiredLibs) \\\
    then \\\
        return false \\\
    end\\\
    \\\
    -- read my score table \\\
    -- identify and process a score table zones\\\
    local theZone = cfxZones.getZoneByName(\\\"playerScoreTable\\\") \\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++scr: no score table!\\\", 30) \\\
    else \\\
        -- read all into my types registry, replacing whatever is there\\\
        cfxPlayerScore.typeScore = cfxZones.getAllZoneProperties(theZone)\\\
        trigger.action.outText(\\\"+++scr: read score table\\\", 30) \\\
    end \\\
    \\\
    -- now read my config zone \\\
    local theZone = cfxZones.getZoneByName(\\\"playerScoreConfig\\\") \\\
    if not theZone then \\\
        trigger.action.outText(\\\"+++scr: no config!\\\", 30) \\\
    else \\\
        cfxPlayerScore.readConfigZone(theZone)\\\
        trigger.action.outText(\\\"+++scr: read config\\\", 30) \\\
    end \\\
    \\\
    -- subscribe to events and use dcsCommon's handler structure\\\
    dcsCommon.addEventHandler(cfxPlayerScore.killDetected,\\\
                              cfxPlayerScore.preProcessor,\\\
                              cfxPlayerScore.postProcessor)\\\
    trigger.action.outText(\\\"cfxPlayerScore v\\\" .. cfxPlayerScore.version .. \\\" started\\\", 30)\\\
    return true \\\
end\\\
\\\
\\\
if not cfxPlayerScore.start() then \\\
    trigger.action.outText(\\\"+++ aborted cfxPlayerScore v\\\" .. cfxPlayerScore.version .. \\\"  -- libcheck failed\\\", 30)\\\
    cfxPlayerScore = nil \\\
end\\\
\\\
-- TODO: score mod for weapons type \\\
-- TODO: player kill score \\\
 \");a_do_script(\"cfxReconMode = {}\\\
cfxReconMode.version = \\\"1.4.1\\\"\\\
cfxReconMode.verbose = false -- set to true for debug info  \\\
cfxReconMode.reconSound = \\\"UI_SCI-FI_Tone_Bright_Dry_20_stereo.wav\\\" -- to be played when somethiong discovered\\\
\\\
cfxReconMode.prioList = {} -- group names that are high prio and generate special event\\\
cfxReconMode.blackList = {} -- group names that are NEVER detected. Comma separated strings, e.g. {\\\"Always Hidden\\\", \\\"Invisible Group\\\"}\\\
\\\
cfxReconMode.requiredLibs = {\\\
    \\\"dcsCommon\\\", -- always\\\
    \\\"cfxZones\\\", -- Zones, of course \\\
}\\\
\\\
--[[--\\\
VERSION HISTORY\\\
 1.0.0 - initial version \\\
 1.0.1 - removeScoutByName()\\\
 1.0.2 - garbage collection \\\
 1.1.0 - autoRecon - any aircraft taking off immediately\\\
         signs up, no message when signing up or closing down\\\
         standalone - copied common procs lerp, agl, dist, distflat\\\
         from dcsCommon\\\
         report numbers \\\
         verbose flag \\\
 1.2.0 - queued recons. One scout per second for more even\\\
         performance\\\
         removed gc since it's now integrated into \\\
         update queue\\\
         removeScout optimization when directly passing name\\\
         playerOnlyRecon for autoRecon \\\
         red, blue, grey side filtering on auto scout\\\
 1.2.1 - parametrized report sound \\\
 1.3.0 - added black list, prio list functionality \\\
 1.3.1 - callbacks now also push name, as group can be dead\\\
       - removed bug when removing dead groups from map\\\
 1.4.0 - import dcsCommon, cfxZones etc \\\
       - added lib check \\\
       - config zone \\\
       - prio+\\\
       - detect+\\\
 1.4.1 - invocation no longer happen twice for prio. \\\
       - recon sound \\\
       - read all flight groups at start to get rid of the \\\
       - late activation work-around \\\
 \\\
 \\\
 cfxReconMode is a script that allows units to perform reconnaissance\\\
 missions and, after detecting units, marks them on the map with \\\
 markers for their coalition and some text \\\
 Also, a callback is initiated for scouts as follows\\\
   signature: (reason, theSide, theSout, theGroup) with  \\\
   reason a string \\\
     'detected' a group was detected\\\
     'removed' a mark for a group timed out\\\
     'priority' a member of prio group was detected \\\
     'start' a scout started scouting\\\
     'end' a scout stopped scouting\\\
     'dead' a scout has died and was removed from pool \\\
   theSide - side of the SCOUT that detected units\\\
   theScout - the scout that detected the group \\\
   theGroup - the group that is detected  \\\
   theName - the group's name    \\\
--]]--\\\
\\\
cfxReconMode.detectionMinRange = 3000 -- meters at ground level\\\
cfxReconMode.detectionMaxRange = 12000 -- meters at max alt (10'000m)\\\
cfxReconMode.maxAlt = 9000 -- alt for maxrange (9km = 27k feet)\\\
\\\
cfxReconMode.autoRecon = true -- add all airborne units, unless \\\
cfxReconMode.redScouts = false -- set to false to prevent red scouts in auto mode\\\
cfxReconMode.blueScouts = true -- set to false to prevent blue scouts in auto-mode\\\
cfxReconMode.greyScouts = false -- set to false to prevent neutral scouts in auto mode\\\
cfxReconMode.playerOnlyRecon = false -- only players can do recon \\\
cfxReconMode.reportNumbers = true -- also add unit count in report \\\
cfxReconMode.prioFlag = nil \\\
cfxReconMode.detectFlag = nil \\\
cfxReconMode.applyMarks = true \\\
\\\
cfxReconMode.ups = 1 -- updates per second.\\\
cfxReconMode.scouts = {} -- units that are performing scouting.\\\
cfxReconMode.processedScouts = {} -- for managing performance: queue\\\
cfxReconMode.detectedGroups = {} -- so we know which have been detected\\\
cfxReconMode.marksFadeAfter = 30*60 -- after detection, marks disappear after\\\
                     -- this amount of seconds. -1 means no fade\\\
                     -- 60 is one minute\\\
\\\
cfxReconMode.callbacks = {} -- sig: cb(reason, side, scout, group)\\\
cfxReconMode.uuidCount = 0 -- for unique marks \\\
\\\
\\\
-- end standalone dcsCommon extract \\\
\\\
function cfxReconMode.uuid()\\\
    cfxReconMode.uuidCount = cfxReconMode.uuidCount + 1\\\
    return cfxReconMode.uuidCount\\\
end\\\
\\\
function cfxReconMode.addCallback(theCB)\\\
    table.insert(cfxReconMode.callbacks, theCB)\\\
end\\\
\\\
function cfxReconMode.invokeCallbacks(reason, theSide, theScout, theGroup, theName)\\\
    for idx, theCB in pairs(cfxReconMode.callbacks) do \\\
        theCB(reason, theSide, theScout, theGroup, theName)\\\
    end\\\
end\\\
\\\
-- add a priority/blackList group name to prio list \\\
function cfxReconMode.addToPrioList(aGroup)\\\
    if not aGroup then return end \\\
    if type(aGroup) == \\\"table\\\" and aGroup.getName then \\\
        aGroup = aGroup:getName()\\\
    end\\\
    if type(aGroup) == \\\"string\\\" then \\\
        table.insert(cfxReconMode.prioList, aGroup)\\\
    end\\\
end\\\
\\\
function cfxReconMode.addToBlackList(aGroup)\\\
    if not aGroup then return end \\\
    if type(aGroup) == \\\"table\\\" and aGroup.getName then \\\
        aGroup = aGroup:getName()\\\
    end\\\
    if type(aGroup) == \\\"string\\\" then \\\
        table.insert(cfxReconMode.blackList, aGroup)\\\
    end\\\
end\\\
\\\
\\\
function cfxReconMode.isStringInList(theString, theList)\\\
    if not theString then return false end \\\
    if not theList then return false end \\\
    if type(theString) == \\\"string\\\" then \\\
        for idx,anItem in pairs(theList) do \\\
            if anItem == theString then return true end\\\
        end\\\
    end\\\
    return false\\\
end\\\
\\\
-- addScout directly adds a scout unit. Use from external \\\
-- to manually add a unit (e.g. via GUI when autoscout isExist\\\
-- off, or to force a scout unit (e.g. when scouts for a side\\\
-- are not allowed but you still want a unit from that side \\\
-- to scout\\\
-- since we use a queue for scouts, also always check the \\\
-- processed queue before adding to make sure a scout isn't \\\
-- entered multiple times \\\
\\\
function cfxReconMode.addScout(theUnit)\\\
    if not theUnit then \\\
        trigger.action.outText(\\\"+++cfxRecon: WARNING - nil Unit on add\\\", 30)\\\
        return\\\
    end\\\
    \\\
    if type(theUnit) == \\\"string\\\" then \\\
        local u = Unit.getByName(theUnit) \\\
        theUnit = u\\\
    end \\\
    \\\
    if not theUnit then \\\
        trigger.action.outText(\\\"+++cfxRecon: WARNING - did not find unit on add\\\", 30)\\\
        return \\\
    end    \\\
    if not theUnit:isExist() then return end \\\
    -- find out if this an update or a new scout \\\
    local thisID = tonumber(theUnit:getID())\\\
    local theName = theUnit:getName() \\\
    local lastUnit = cfxReconMode.scouts[theName]\\\
    local isProcced = false -- may also be in procced line \\\
    if not lastUnit then \\\
        lastUnit = cfxReconMode.processedScouts[theName]\\\
        if lastUnit then isProcced = true end \\\
    end\\\
\\\
    if lastUnit then \\\
        -- this is merely an overwrite \\\
        if cfxReconMode.verbose then trigger.action.outText(\\\"+++rcn: UPDATE scout \\\" .. theName .. \\\" -- no CB invoke\\\", 30) end \\\
    else \\\
        if cfxReconMode.verbose then trigger.action.outText(\\\"+++rcn: new scout \\\" .. theName .. \\\" with ID \\\" .. thisID, 30) end \\\
        -- a new scout! Invoke callbacks\\\
        local scoutGroup = theUnit:getGroup()\\\
        local theSide = scoutGroup:getCoalition()\\\
        cfxReconMode.invokeCallbacks(\\\"start\\\", theSide, theUnit, nil, \\\"<none>\\\")\\\
    end \\\
    \\\
    if isProcced then \\\
        -- overwrite exiting entry in procced queue\\\
        cfxReconMode.processedScouts[theName] = theUnit\\\
    else \\\
        -- add / overwrite into normal queue \\\
        cfxReconMode.scouts[theName] = theUnit\\\
    end \\\
    \\\
    if cfxReconMode.verbose then\\\
        trigger.action.outText(\\\"+++rcn: addded scout \\\" .. theUnit:getName(), 30)\\\
    end\\\
end\\\
\\\
\\\
function cfxReconMode.removeScout(theUnit)\\\
    if not theUnit then \\\
        trigger.action.outText(\\\"+++cfxRecon: WARNING - nil Unit on remove\\\", 30)\\\
        return \\\
    end\\\
    \\\
    if type(theUnit) == \\\"string\\\" then \\\
        cfxReconMode.removeScoutByName(theUnit)\\\
        return \\\
    end \\\
    \\\
    if not theUnit then return end    \\\
    if not theUnit:isExist() then return end \\\
    cfxReconMode.removeScoutByName(theUnit:getName())\\\
    local scoutGroup = theUnit:getGroup()\\\
    local theSide = scoutGroup:getCoalition()\\\
    cfxReconMode.invokeCallbacks(\\\"end\\\", theSide, theUnit, nil, \\\"<none>\\\")\\\
end\\\
\\\
-- warning: removeScoutByName does NOT invoke callbacks, always\\\
-- use removeScout instead!\\\
function cfxReconMode.removeScoutByName(aName)\\\
    cfxReconMode.scouts[aName] = nil\\\
    cfxReconMode.processedScouts[aName] = nil -- also remove from processed stack \\\
    if cfxReconMode.verbose then\\\
        trigger.action.outText(\\\"+++rcn: removed scout \\\" .. aName, 30)\\\
    end\\\
end\\\
\\\
\\\
function cfxReconMode.canDetect(scoutPos, theGroup, visRange)\\\
    -- determine if a member of theGroup can be seen from \\\
    -- scoutPos at visRange \\\
    -- returns true and pos when detected\\\
    local allUnits = theGroup:getUnits()\\\
    for idx, aUnit in pairs(allUnits) do\\\
        if aUnit:isExist() and aUnit:getLife() >= 1 then \\\
            local uPos = aUnit:getPoint()\\\
            uPos.y = uPos.y + 3 -- raise my 3 meters\\\
            local d = dcsCommon.distFlat(scoutPos, uPos) \\\
            if d < visRange then \\\
                -- is in visual range. do we have LOS?\\\
                if land.isVisible(scoutPos, uPos) then \\\
                    -- group is visible, stop here, return true\\\
                    return true, uPos\\\
                end\\\
            else \\\
                -- OPTIMIZATION: if a unit is outside \\\
                -- detect range, we assume that entire group \\\
                -- is, since they are bunched together\\\
                -- edge cases may get lucky tests\\\
                return false, nil \\\
            end\\\
        end        \\\
    end\\\
    return false, nil -- nothing visible\\\
end\\\
\\\
function cfxReconMode.placeMarkForUnit(location, theSide, theGroup) \\\
    local theID = cfxReconMode.uuid()\\\
    local theDesc = \\\"Contact: \\\"..theGroup:getName()\\\
    if cfxReconMode.reportNumbers then \\\
        theDesc = theDesc .. \\\" (\\\" .. theGroup:getSize() .. \\\" units)\\\"\\\
    end\\\
    trigger.action.markToCoalition(\\\
                    theID, \\\
                    theDesc, \\\
                    location, \\\
                    theSide, \\\
                    false, \\\
                    nil)\\\
    return theID\\\
end\\\
\\\
function cfxReconMode.removeMarkForArgs(args)\\\
    local theSide = args[1]\\\
    local theScout = args[2]\\\
    local theGroup = args[3]\\\
    local theID = args[4]\\\
    local theName = args[5]\\\
    \\\
--    if not theGroup then return end \\\
--    if not theGroup:isExist then return end \\\
    \\\
    trigger.action.removeMark(theID)\\\
    cfxReconMode.detectedGroups[theName] = nil \\\
    \\\
    -- invoke callbacks\\\
    cfxReconMode.invokeCallbacks(\\\"removed\\\", theSide, theScout, theGroup, theName)\\\
end \\\
\\\
\\\
function cfxReconMode.detectedGroup(mySide, theScout, theGroup, theLoc)\\\
    -- put a mark on the map \\\
    if cfxReconMode.applyMarks then \\\
        local theID = cfxReconMode.placeMarkForUnit(theLoc, mySide, theGroup)\\\
    \\\
        -- schedule removal if desired \\\
        if cfxReconMode.marksFadeAfter > 0 then \\\
            args = {mySide, theScout, theGroup, theID, theGroup:getName()}\\\
            timer.scheduleFunction(cfxReconMode.removeMarkForArgs, args, timer.getTime() + cfxReconMode.marksFadeAfter)\\\
        end\\\
    end \\\
    -- say something\\\
    if cfxReconMode.announcer then \\\
        trigger.action.outTextForCoalition(mySide, theScout:getName() .. \\\" reports new ground contact \\\" .. theGroup:getName(), 30)\\\
        -- play a sound \\\
        trigger.action.outSoundForCoalition(mySide, cfxReconMode.reconSound)\\\
    end \\\
    \\\
    -- see if it was a prio target \\\
    if cfxReconMode.isStringInList(theGroup:getName(), cfxReconMode.prioList) then \\\
        if cfxReconMode.announcer then \\\
            trigger.action.outTextForCoalition(mySide, \\\"Priority target confirmed\\\",    30)\\\
        end \\\
        -- invoke callbacks\\\
        cfxReconMode.invokeCallbacks(\\\"priotity\\\", mySide, theScout, theGroup, theGroup:getName())\\\
        \\\
        -- increase prio flag \\\
        if cfxReconMode.prioFlag then \\\
            local currVal = trigger.misc.getUserFlag(cfxReconMode.prioFlag)\\\
            trigger.action.setUserFlag(cfxReconMode.prioFlag, currVal + 1)\\\
        end\\\
    else \\\
        -- invoke callbacks\\\
        cfxReconMode.invokeCallbacks(\\\"detected\\\", mySide, theScout, theGroup, theGroup:getName())\\\
    \\\
        -- increase normal flag \\\
        if cfxReconMode.detectFlag then \\\
            local currVal = trigger.misc.getUserFlag(cfxReconMode.detectFlag)\\\
            trigger.action.setUserFlag(cfxReconMode.detectFlag, currVal + 1)\\\
        end\\\
    end\\\
end\\\
\\\
function cfxReconMode.performReconForUnit(theScout)\\\
    if not theScout then return end \\\
    if not theScout:isExist() then return end -- will be gc'd soon\\\
    -- get altitude above ground to calculate visual range \\\
    local alt = dcsCommon.getUnitAGL(theScout)\\\
    local visRange = dcsCommon.lerp(cfxReconMode.detectionMinRange, cfxReconMode.detectionMaxRange, alt/cfxReconMode.maxAlt)\\\
    local scoutPos = theScout:getPoint()\\\
    -- figure out which groups we are looking for\\\
    local myCoal = theScout:getCoalition()\\\
    local enemyCoal = 1 \\\
    if myCoal == 1 then enemyCoal = 2 end \\\
    \\\
    -- iterate all enemy units until we find one \\\
    -- and then stop this iteration (can only detect one \\\
    -- group per pass)\\\
    local enemyGroups = coalition.getGroups(enemyCoal)\\\
    for idx, theGroup in pairs (enemyGroups) do \\\
        -- make sure it's a ground unit \\\
        local isGround = theGroup:getCategory() == 2\\\
        if theGroup:isExist() and isGround then \\\
            local visible, location = cfxReconMode.canDetect(scoutPos, theGroup, visRange)\\\
            if visible then \\\
                -- see if we already detected this one \\\
                local groupName = theGroup:getName()\\\
                if cfxReconMode.detectedGroups[groupName] == nil then \\\
                    -- only now check against blackList\\\
                    if not cfxReconMode.isStringInList(groupName, cfxReconMode.blackList) then \\\
                        -- visible and not yet seen \\\
                        -- perhaps add some percent chance now \\\
                        -- remember that we know this group \\\
                        cfxReconMode.detectedGroups[groupName] = theGroup\\\
                        cfxReconMode.detectedGroup(myCoal, theScout, theGroup, location)\\\
                        return -- stop, as we only detect one group per pass\\\
                    end \\\
                end\\\
            end\\\
        end\\\
    end\\\
end\\\
\\\
\\\
\\\
function cfxReconMode.updateQueues()\\\
    -- schedule next call \\\
    timer.scheduleFunction(cfxReconMode.updateQueues, {}, timer.getTime() + 1/cfxReconMode.ups)\\\
    \\\
    -- we only process the first aircraft in \\\
    -- the scouts array, move it to processed and then shrink\\\
    -- scouts table until it's empty. When empty, transfer all \\\
    -- back and start cycle anew\\\
\\\
    local theFocusScoutName = nil \\\
    local procCount = 0 -- no iterations done yet\\\
    for name, scout in pairs(cfxReconMode.scouts) do \\\
        theFocusScoutName = name -- remember so we can delete\\\
        if not scout:isExist() then \\\
            -- we ignore the scout, and it's \\\
            -- forgotten since no longer transferred\\\
            -- i.e. built-in GC\\\
            if cfxReconMode.verbose then\\\
                trigger.action.outText(\\\"+++rcn: GC - removing scout \\\" .. name .. \\\" because it no longer exists\\\", 30)\\\
            end\\\
            -- invoke 'end' for this scout  \\\
            cfxReconMode.invokeCallbacks(\\\"dead\\\", -1, nil, nil, name)\\\
        else\\\
            -- scan for this scout\\\
            cfxReconMode.performReconForUnit(scout)\\\
            -- move it to processed table\\\
            cfxReconMode.processedScouts[name] = scout\\\
        end\\\
        procCount = 1 -- remember we went through one iteration\\\
        break -- always end after first iteration\\\
    end\\\
\\\
    -- remove processed scouts from scouts array\\\
    if procCount > 0 then \\\
        -- we processed one scout (even if scout itself did not exist)\\\
        -- remove that scout from active scouts table\\\
        cfxReconMode.scouts[theFocusScoutName] = nil\\\
    else \\\
        -- scouts is empty. copy processed table back to scouts\\\
        -- restart scouts array, contains GC already \\\
        cfxReconMode.scouts = cfxReconMode.processedScouts\\\
        cfxReconMode.processedScouts = {} -- start new empty processed queue\\\
    end \\\
end\\\
\\\
-- event handler \\\
function cfxReconMode:onEvent(event) \\\
    if not event then return end \\\
    if not event.initiator then return end \\\
    local theUnit = event.initiator \\\
    \\\
    -- we simply add scouts as they are garbage-collected \\\
    -- every so often when they do not exist \\\
    if event.id == 15 or -- birth\\\
       event.id == 3 -- take-off. should already have been taken \\\
                     -- care of by birth, but you never know \\\
    then\\\
        -- check if a side must not have scouts.\\\
        -- this will prevent player units to auto-\\\
        -- scout when they are on that side. in that case\\\
        -- you must add manually\\\
        local theSide = theUnit:getCoalition()\\\
        if theSide == 0 and not cfxReconMode.greyScouts then \\\
            return -- grey scouts are not allowed\\\
        end\\\
        if theSide == 1 and not cfxReconMode.redScouts then \\\
            return -- grey scouts are not allowed\\\
        end\\\
        if theSide == 2 and not cfxReconMode.blueScouts then \\\
            return -- grey scouts are not allowed\\\
        end\\\
        \\\
        if cfxReconMode.playerOnlyRecon then \\\
            if not theUnit:getPlayerName() then \\\
                return -- only players can do recon. this unit is AI\\\
            end\\\
        end\\\
        if cfxReconMode.verbose then \\\
            trigger.action.outText(\\\"+++rcn: event \\\" .. event.id .. \\\" for unit \\\" .. theUnit:getName(), 30)\\\
        end \\\
        cfxReconMode.addScout(theUnit)\\\
    end\\\
end\\\
\\\
--\\\
-- read all existing planes \\\
-- \\\
function cfxReconMode.processScoutGroups(theGroups)\\\
    for idx, aGroup in pairs(theGroups) do \\\
        -- process all planes in that group \\\
        -- we are very early in the mission, only few groups really \\\
        -- exist now, the rest of the units come in with 15 event\\\
        if aGroup:isExist() then \\\
            local allUnits = Group.getUnits(aGroup)\\\
            for idy, aUnit in pairs (allUnits) do \\\
                if aUnit:isExist() then \\\
                    cfxReconMode.addScout(aUnit)\\\
                    if cfxReconMode.verbose then\\\
                        trigger.action.outText(\\\"+++rcn: added unit \\\" ..aUnit:getName() .. \\\" to pool at startup\\\", 30)\\\
                    end \\\
                end\\\
            end\\\
        end\\\
    end\\\
end\\\
\\\
function cfxReconMode.initScouts()\\\
    -- get all groups of aircraft. Unrolled loop 0..2 \\\
    local theAirGroups = {}  \\\
    if cfxReconMode.greyScouts then\\\
        theAirGroups = coalition.getGroups(0, 0) -- 0 = aircraft\\\
        cfxReconMode.processScoutGroups(theAirGroups) \\\
    end\\\
    if cfxReconMode.redScouts then\\\
        theAirGroups = coalition.getGroups(1, 0) -- 1 = red, 0 = aircraft\\\
        cfxReconMode.processScoutGroups(theAirGroups) \\\
    end\\\
    \\\
    if cfxReconMode.blueScouts then\\\
        theAirGroups = coalition.getGroups(2, 0) -- 2 = blue, 0 = aircraft\\\
        cfxReconMode.processScoutGroups(theAirGroups) \\\
    end\\\
end\\\
\\\
--\\\
-- read config \\\
--\\\
function cfxReconMode.readConfigZone()\\\
    -- note: must match exactly!!!!\\\
    local theZone = cfxZones.getZoneByName(\\\"reconModeConfig\\\") \\\
    if not theZone then \\\
        if cfxReconMode.verbose then\\\
            trigger.action.outText(\\\"+++rcn: no config zone!\\\", 30) \\\
        end \\\
        return \\\
    end \\\
    if cfxReconMode.verbose then \\\
        trigger.action.outText(\\\"+++rcn: found config zone!\\\", 30) \\\
    end \\\
    \\\
    cfxReconMode.verbose = cfxZones.getBoolFromZoneProperty(theZone, \\\"verbose\\\", false)\\\
\\\
    cfxReconMode.autoRecon = cfxZones.getBoolFromZoneProperty(theZone, \\\"autoRecon\\\", true)\\\
    cfxReconMode.redScouts = cfxZones.getBoolFromZoneProperty(theZone, \\\"redScouts\\\", false)\\\
    cfxReconMode.blueScouts = cfxZones.getBoolFromZoneProperty(theZone, \\\"blueScouts\\\", true)    \\\
    cfxReconMode.greyScouts = cfxZones.getBoolFromZoneProperty(theZone, \\\"greyScouts\\\", false)\\\
    cfxReconMode.playerOnlyRecon = cfxZones.getBoolFromZoneProperty(theZone, \\\"playerOnlyRecon\\\", false)\\\
    cfxReconMode.reportNumbers = cfxZones.getBoolFromZoneProperty(theZone, \\\"reportNumbers\\\", true)\\\
        \\\
    cfxReconMode.detectionMinRange = cfxZones.getNumberFromZoneProperty(theZone, \\\"detectionMinRange\\\", 3000)\\\
    cfxReconMode.detectionMaxRange = cfxZones.getNumberFromZoneProperty(theZone, \\\"detectionMaxRange\\\", 12000)\\\
    cfxReconMode.maxAlt = cfxZones.getNumberFromZoneProperty(theZone, \\\"maxAlt\\\", 9000)\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"prio+\\\") then \\\
        cfxReconMode.prioFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"prio+\\\", \\\"none\\\")\\\
    end\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"detect+\\\") then \\\
        cfxReconMode.detectFlag = cfxZones.getStringFromZoneProperty(theZone, \\\"detect+\\\", \\\"none\\\")\\\
    end\\\
    \\\
    \\\
    cfxReconMode.applyMarks = cfxZones.getBoolFromZoneProperty(theZone, \\\"applyMarks\\\", true)\\\
    cfxReconMode.announcer = cfxZones.getBoolFromZoneProperty(theZone, \\\"announcer\\\", true)\\\
    \\\
    if cfxZones.hasProperty(theZone, \\\"reconSound\\\") then \\\
        cfxReconMode.reconSound = cfxZones.getStringFromZoneProperty(theZone, \\\"reconSound\\\", \\\"<nosound>\\\")\\\
    end\\\
end\\\
\\\
--\\\
-- start \\\
--\\\
function cfxReconMode.start()\\\
    -- lib check \\\
    if not dcsCommon.libCheck(\\\"cfx Recon Mode\\\", \\\
        cfxReconMode.requiredLibs) then\\\
        return false \\\
    end\\\
    \\\
    -- read config \\\
    cfxReconMode.readConfigZone()\\\
    \\\
    -- gather exiting planes \\\
    cfxReconMode.initScouts()\\\
    \\\
    -- start update cycle\\\
    cfxReconMode.updateQueues()\\\
        \\\
    if cfxReconMode.autoRecon then \\\
        -- install own event handler to detect \\\
        -- when a unit takes off and add it to scout\\\
        -- roster \\\
        world.addEventHandler(cfxReconMode)\\\
    end\\\
    \\\
    trigger.action.outText(\\\"cfx Recon version \\\" .. cfxReconMode.version .. \\\" started.\\\", 30)\\\
    return true\\\
end\\\
\\\
--\\\
-- test callback \\\
--\\\
function cfxReconMode.demoReconCB(reason, theSide, theScout, theGroup, theName)\\\
    trigger.action.outText(\\\"recon CB: \\\" .. reason .. \\\" -- \\\" .. theScout:getName() .. \\\" spotted \\\" .. theName, 30)\\\
end\\\
\\\
if not cfxReconMode.start() then \\\
    cfxReconMode = nil\\\
end\\\
\\\
-- debug: wire up my own callback\\\
-- cfxReconMode.addCallback(cfxReconMode.demoReconCB)\\\
\\\
\\\
--[[--\\\
\\\
ideas:\\\
 \\\
- renew lease. when already sighted, simply renew lease, maybe update location.\\\
- update marks and renew lease \\\
TODO: red+ and blue+ - flags to increase when a plane of the other side is detected\\\
\\\
 \\\
--]]--\\\
\\\
\\\
 \\\
 \");a_out_text_delay(getValueDictByKey(\"DictKey_ActionText_11\"), 10, true, 0); mission.trig.func[2]=nil;",
            [3] = "a_out_sound(getValueResourceByKey(\"ResKey_Action_6\"), 0);a_out_sound(getValueResourceByKey(\"ResKey_Action_7\"), 0);a_out_sound(getValueResourceByKey(\"ResKey_Action_8\"), 0);a_out_sound(getValueResourceByKey(\"ResKey_Action_9\"), 0);a_out_sound(getValueResourceByKey(\"ResKey_Action_10\"), 0);a_out_sound(getValueResourceByKey(\"ResKey_Action_12\"), 0); mission.trig.func[3]=nil;",
        }, -- end of ["actions"]
        ["events"] = 
        {
        }, -- end of ["events"]
        ["custom"] = 
        {
        }, -- end of ["custom"]
        ["func"] = 
        {
            [2] = "if mission.trig.conditions[2]() then mission.trig.actions[2]() end",
            [3] = "if mission.trig.conditions[3]() then mission.trig.actions[3]() end",
        }, -- end of ["func"]
        ["flag"] = 
        {
            [1] = true,
            [2] = true,
            [3] = true,
        }, -- end of ["flag"]
        ["conditions"] = 
        {
            [1] = "return(true)",
            [2] = "return(c_time_after(1) )",
            [3] = "return(c_time_after(999999) )",
        }, -- end of ["conditions"]
        ["customStartup"] = 
        {
        }, -- end of ["customStartup"]
        ["funcStartup"] = 
        {
            [1] = "if mission.trig.conditions[1]() then mission.trig.actions[1]() end",
        }, -- end of ["funcStartup"]
    }, -- end of ["trig"]
    ["requiredModules"] = 
    {
    }, -- end of ["requiredModules"]
    ["date"] = 
    {
        ["Day"] = 21,
        ["Year"] = 2016,
        ["Month"] = 6,
    }, -- end of ["date"]
    ["result"] = 
    {
        ["offline"] = 
        {
            ["conditions"] = 
            {
            }, -- end of ["conditions"]
            ["actions"] = 
            {
            }, -- end of ["actions"]
            ["func"] = 
            {
            }, -- end of ["func"]
        }, -- end of ["offline"]
        ["total"] = 0,
        ["blue"] = 
        {
            ["conditions"] = 
            {
            }, -- end of ["conditions"]
            ["actions"] = 
            {
            }, -- end of ["actions"]
            ["func"] = 
            {
            }, -- end of ["func"]
        }, -- end of ["blue"]
        ["red"] = 
        {
            ["conditions"] = 
            {
            }, -- end of ["conditions"]
            ["actions"] = 
            {
            }, -- end of ["actions"]
            ["func"] = 
            {
            }, -- end of ["func"]
        }, -- end of ["red"]
    }, -- end of ["result"]
    ["groundControl"] = 
    {
        ["isPilotControlVehicles"] = false,
        ["roles"] = 
        {
            ["artillery_commander"] = 
            {
                ["neutrals"] = 0,
                ["blue"] = 0,
                ["red"] = 0,
            }, -- end of ["artillery_commander"]
            ["instructor"] = 
            {
                ["neutrals"] = 0,
                ["blue"] = 0,
                ["red"] = 0,
            }, -- end of ["instructor"]
            ["observer"] = 
            {
                ["neutrals"] = 0,
                ["blue"] = 0,
                ["red"] = 0,
            }, -- end of ["observer"]
            ["forward_observer"] = 
            {
                ["neutrals"] = 0,
                ["blue"] = 0,
                ["red"] = 0,
            }, -- end of ["forward_observer"]
        }, -- end of ["roles"]
    }, -- end of ["groundControl"]
    ["maxDictId"] = 12,
    ["pictureFileNameN"] = 
    {
    }, -- end of ["pictureFileNameN"]
    ["drawings"] = 
    {
        ["options"] = 
        {
            ["hiddenOnF10Map"] = 
            {
                ["Observer"] = 
                {
                    ["Neutral"] = false,
                    ["Blue"] = false,
                    ["Red"] = false,
                }, -- end of ["Observer"]
                ["Instructor"] = 
                {
                    ["Neutral"] = false,
                    ["Blue"] = false,
                    ["Red"] = false,
                }, -- end of ["Instructor"]
                ["ForwardObserver"] = 
                {
                    ["Neutral"] = false,
                    ["Blue"] = false,
                    ["Red"] = false,
                }, -- end of ["ForwardObserver"]
                ["Pilot"] = 
                {
                    ["Neutral"] = false,
                    ["Blue"] = false,
                    ["Red"] = false,
                }, -- end of ["Pilot"]
                ["Spectrator"] = 
                {
                    ["Neutral"] = false,
                    ["Blue"] = false,
                    ["Red"] = false,
                }, -- end of ["Spectrator"]
                ["ArtilleryCommander"] = 
                {
                    ["Neutral"] = false,
                    ["Blue"] = false,
                    ["Red"] = false,
                }, -- end of ["ArtilleryCommander"]
            }, -- end of ["hiddenOnF10Map"]
        }, -- end of ["options"]
        ["layers"] = 
        {
            [2] = 
            {
                ["visible"] = true,
                ["name"] = "Blue",
                ["objects"] = 
                {
                }, -- end of ["objects"]
            }, -- end of [2]
            [3] = 
            {
                ["visible"] = true,
                ["name"] = "Neutral",
                ["objects"] = 
                {
                }, -- end of ["objects"]
            }, -- end of [3]
            [1] = 
            {
                ["visible"] = true,
                ["name"] = "Red",
                ["objects"] = 
                {
                }, -- end of ["objects"]
            }, -- end of [1]
            [4] = 
            {
                ["visible"] = true,
                ["name"] = "Author",
                ["objects"] = 
                {
                }, -- end of ["objects"]
            }, -- end of [4]
            [5] = 
            {
                ["visible"] = true,
                ["name"] = "Common",
                ["objects"] = 
                {
                    [1] = 
                    {
                        ["visible"] = true,
                        ["radius"] = 633.27319163112,
                        ["mapY"] = 102260.14076256,
                        ["primitiveType"] = "Polygon",
                        ["thickness"] = 3,
                        ["colorString"] = "0x0000ffff",
                        ["style"] = "solid",
                        ["layerName"] = "Common",
                        ["name"] = "Polygon 1",
                        ["fillColorString"] = "0x0000ff00",
                        ["mapX"] = 191655.75910264,
                        ["polygonMode"] = "circle",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["visible"] = true,
                        ["borderThickness"] = 4,
                        ["mapY"] = 102662.46558398,
                        ["layerName"] = "Common",
                        ["font"] = "DejaVuLGCSansCondensed.ttf",
                        ["mapX"] = 192378.73378174,
                        ["colorString"] = "0xffffffff",
                        ["name"] = "Text Box 1",
                        ["angle"] = 0,
                        ["text"] = "Harbor",
                        ["fillColorString"] = "0x0000ff80",
                        ["primitiveType"] = "TextBox",
                        ["fontSize"] = 24,
                    }, -- end of [2]
                    [4] = 
                    {
                        ["visible"] = true,
                        ["borderThickness"] = 4,
                        ["mapY"] = 99845.526198326,
                        ["layerName"] = "Common",
                        ["font"] = "DejaVuLGCSansCondensed.ttf",
                        ["mapX"] = 181022.38623035,
                        ["colorString"] = "0xffffffff",
                        ["name"] = "Airfield",
                        ["angle"] = 0,
                        ["text"] = "Airfield",
                        ["fillColorString"] = "0x0000ff80",
                        ["primitiveType"] = "TextBox",
                        ["fontSize"] = 24,
                    }, -- end of [4]
                    [3] = 
                    {
                        ["visible"] = true,
                        ["radius"] = 736.68397989946,
                        ["mapY"] = 101388.02988449,
                        ["primitiveType"] = "Polygon",
                        ["thickness"] = 3,
                        ["colorString"] = "0x0000ffff",
                        ["style"] = "solid",
                        ["layerName"] = "Common",
                        ["name"] = "Polygon 2",
                        ["fillColorString"] = "0xff000000",
                        ["mapX"] = 180519.20420119,
                        ["polygonMode"] = "circle",
                    }, -- end of [3]
                }, -- end of ["objects"]
            }, -- end of [5]
        }, -- end of ["layers"]
    }, -- end of ["drawings"]
    ["goals"] = 
    {
    }, -- end of ["goals"]
    ["descriptionNeutralsTask"] = "DictKey_descriptionNeutralsTask_4",
    ["weather"] = 
    {
        ["atmosphere_type"] = 0,
        ["wind"] = 
        {
            ["at8000"] = 
            {
                ["speed"] = 0,
                ["dir"] = 0,
            }, -- end of ["at8000"]
            ["at2000"] = 
            {
                ["speed"] = 0,
                ["dir"] = 0,
            }, -- end of ["at2000"]
            ["atGround"] = 
            {
                ["speed"] = 3,
                ["dir"] = 238,
            }, -- end of ["atGround"]
        }, -- end of ["wind"]
        ["enable_fog"] = false,
        ["groundTurbulence"] = 0,
        ["enable_dust"] = false,
        ["season"] = 
        {
            ["temperature"] = 20,
        }, -- end of ["season"]
        ["type_weather"] = 0,
        ["modifiedTime"] = false,
        ["cyclones"] = 
        {
        }, -- end of ["cyclones"]
        ["name"] = "Winter, clean sky",
        ["fog"] = 
        {
            ["thickness"] = 0,
            ["visibility"] = 0,
        }, -- end of ["fog"]
        ["dust_density"] = 0,
        ["qnh"] = 760,
        ["visibility"] = 
        {
            ["distance"] = 80000,
        }, -- end of ["visibility"]
        ["clouds"] = 
        {
            ["thickness"] = 200,
            ["density"] = 0,
            ["preset"] = "Preset2",
            ["base"] = 2500,
            ["iprecptns"] = 0,
        }, -- end of ["clouds"]
    }, -- end of ["weather"]
    ["theatre"] = "MarianaIslands",
    ["triggers"] = 
    {
        ["zones"] = 
        {
            [1] = 
            {
                ["radius"] = 50,
                ["zoneId"] = 20,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 0,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "startDelay?",
                        ["value"] = "inv-1",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "timeDelay",
                        ["value"] = "1",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "delayDone!",
                        ["value"] = "*start",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "cloner",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "clone?",
                        ["value"] = "*start",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "empty!",
                        ["value"] = "attackerRepelled",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "message",
                        ["value"] = "WARNING: Invaders Inbound on Harbour!",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "*start",
                    }, -- end of [9]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 108453.1972145,
                ["x"] = 196196.6942063,
                ["name"] = "Invader-1",
                ["type"] = 0,
            }, -- end of [1]
            [2] = 
            {
                ["radius"] = 500,
                ["zoneId"] = 40,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.15,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "RND",
                        ["value"] = "",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "rndMethod",
                        ["value"] = "inc",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "rndPoll?",
                        ["value"] = "new Invaders",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "flags!",
                        ["value"] = "inv-1, inv-2, inv-3, inv-4, inv-5, inv-6, inv-7",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "remove",
                        ["value"] = "yes",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messageOff",
                        ["value"] = "A new group of invaders has been sighted",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "new Invaders",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "soundFile",
                        ["value"] = "claxon.ogg",
                    }, -- end of [9]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 100459.80902581,
                ["x"] = 197599.29652108,
                ["name"] = "Attack Invaders Randomizer",
                ["type"] = 0,
            }, -- end of [2]
            [3] = 
            {
                ["radius"] = 500,
                ["zoneId"] = 42,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.15,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "pulse!",
                        ["value"] = "*new wave",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "time",
                        ["value"] = "400-600",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "countDown",
                        ["value"] = "5",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "count?",
                        ["value"] = "*new wave",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "tMinus!",
                        ["value"] = "new Invaders",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "zero!",
                        ["value"] = "new Invaders",
                    }, -- end of [6]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 99080.503631679,
                ["x"] = 197567.24833652,
                ["name"] = "Trigger Waves Invaders",
                ["type"] = 0,
            }, -- end of [3]
            [4] = 
            {
                ["radius"] = 50,
                ["zoneId"] = 43,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 0,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "startDelay?",
                        ["value"] = "inv-2",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "timeDelay",
                        ["value"] = "1",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "delayDone!",
                        ["value"] = "*start",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "cloner",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "clone?",
                        ["value"] = "*start",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "empty!",
                        ["value"] = "attackerRepelled",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "message",
                        ["value"] = "WARNING: Invaders Inbound on Harbour!",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "*start",
                    }, -- end of [9]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 107220.89965384,
                ["x"] = 191288.31982364,
                ["name"] = "Invader-2",
                ["type"] = 0,
            }, -- end of [4]
            [5] = 
            {
                ["radius"] = 500,
                ["zoneId"] = 63,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "verbose",
                        ["value"] = "no",
                    }, -- end of [1]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 97408.211741945,
                ["x"] = 200362.92727158,
                ["name"] = "rndFlagsConfig",
                ["type"] = 0,
            }, -- end of [5]
            [6] = 
            {
                ["radius"] = 500,
                ["zoneId"] = 84,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.15,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "RND",
                        ["value"] = "",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "rndMethod",
                        ["value"] = "inc",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "rndPoll?",
                        ["value"] = "deploy new AAA",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "flags!",
                        ["value"] = "aaa-1, aaa-2, aaa-3, aaa-4, aaa-5",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "message",
                        ["value"] = "WARNING: new SAM delpoying",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "deploy new AAA",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "soundFile",
                        ["value"] = "claxon.ogg",
                    }, -- end of [8]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 100490.54805343,
                ["x"] = 195740.63331526,
                ["name"] = "AAA Randomizer",
                ["type"] = 0,
            }, -- end of [6]
            [7] = 
            {
                ["radius"] = 50,
                ["zoneId"] = 85,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 0,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "startDelay?",
                        ["value"] = "aaa-1",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "timeDelay",
                        ["value"] = "60",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "delayDone!",
                        ["value"] = "*start",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "cloner",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "clone?",
                        ["value"] = "*start",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "empty!",
                        ["value"] = "aaa destroyed",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "message",
                        ["value"] = "WARNING: new SAM has come on-line",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "*start",
                    }, -- end of [9]
                    [10] = 
                    {
                        ["key"] = "soundFile",
                        ["value"] = "Death BRASS.wav",
                    }, -- end of [10]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 106309.31389574,
                ["x"] = 188679.02377231,
                ["name"] = "AAA-1",
                ["type"] = 0,
            }, -- end of [7]
            [8] = 
            {
                ["radius"] = 500,
                ["zoneId"] = 105,
                ["color"] = 
                {
                    [1] = 0,
                    [2] = 0,
                    [3] = 1,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "countDown",
                        ["value"] = "5",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "count?",
                        ["value"] = "attackerRepelled",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "zero!",
                        ["value"] = "we won!",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "attackerRepelled",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "message",
                        ["value"] = "Good Job! Invader Group Neutralized",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "soundFile",
                        ["value"] = "Quest Snare 3.wav",
                    }, -- end of [7]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 112418.92010316,
                ["x"] = 190282.62390528,
                ["name"] = "Win Counter",
                ["type"] = 0,
            }, -- end of [8]
            [9] = 
            {
                ["radius"] = 50,
                ["zoneId"] = 125,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 0,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "startDelay?",
                        ["value"] = "aaa-2",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "timeDelay",
                        ["value"] = "60",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "delayDone!",
                        ["value"] = "*start",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "cloner",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "clone?",
                        ["value"] = "*start",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "empty!",
                        ["value"] = "aaa destroyed",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "message",
                        ["value"] = "WARNING: new SAM has come on-line",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "*start",
                    }, -- end of [9]
                    [10] = 
                    {
                        ["key"] = "soundFile",
                        ["value"] = "Death BRASS.wav",
                    }, -- end of [10]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 105962.37887139,
                ["x"] = 186173.20346156,
                ["name"] = "AAA-2",
                ["type"] = 0,
            }, -- end of [9]
            [10] = 
            {
                ["radius"] = 50,
                ["zoneId"] = 145,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 0,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "startDelay?",
                        ["value"] = "aaa-3",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "timeDelay",
                        ["value"] = "60",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "delayDone!",
                        ["value"] = "*start",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "cloner",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "clone?",
                        ["value"] = "*start",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "empty!",
                        ["value"] = "aaa destroyed",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "message",
                        ["value"] = "WARNING: new SAM has come on-line",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "*start",
                    }, -- end of [9]
                    [10] = 
                    {
                        ["key"] = "soundFile",
                        ["value"] = "Death BRASS.wav",
                    }, -- end of [10]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 100767.76438352,
                ["x"] = 191018.47892726,
                ["name"] = "AAA-3",
                ["type"] = 0,
            }, -- end of [10]
            [11] = 
            {
                ["radius"] = 50,
                ["zoneId"] = 165,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 0,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "startDelay?",
                        ["value"] = "inv-3",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "timeDelay",
                        ["value"] = "1",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "delayDone!",
                        ["value"] = "*start",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "cloner",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "clone?",
                        ["value"] = "*start",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "empty!",
                        ["value"] = "attackerRepelled",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "message",
                        ["value"] = "WARNING: Airfield under Attack! Troops Inbound!",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "*start",
                    }, -- end of [9]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 104793.55914605,
                ["x"] = 189424.19927349,
                ["name"] = "Invader-3",
                ["type"] = 0,
            }, -- end of [11]
            [12] = 
            {
                ["radius"] = 50,
                ["zoneId"] = 166,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 0,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "startDelay?",
                        ["value"] = "inv-4",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "timeDelay",
                        ["value"] = "1",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "delayDone!",
                        ["value"] = "*start",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "cloner",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "clone?",
                        ["value"] = "*start",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "empty!",
                        ["value"] = "attackerRepelled",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "message",
                        ["value"] = "WARNING: Airfield under Attack! Troops Inbound!",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "*start",
                    }, -- end of [9]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 101081.75364895,
                ["x"] = 189909.93267614,
                ["name"] = "Invader-4",
                ["type"] = 0,
            }, -- end of [12]
            [13] = 
            {
                ["radius"] = 500,
                ["zoneId"] = 186,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "verbose",
                        ["value"] = "no",
                    }, -- end of [1]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 99773.622174883,
                ["x"] = 200433.09650153,
                ["name"] = "countDownConfig",
                ["type"] = 0,
            }, -- end of [13]
            [14] = 
            {
                ["radius"] = 500,
                ["zoneId"] = 206,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.15,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "pulse!",
                        ["value"] = "*new wave",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "time",
                        ["value"] = "900-1500",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "countDown",
                        ["value"] = "6",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "count?",
                        ["value"] = "*new wave",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "tMinus!",
                        ["value"] = "deploy new AAA",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "zero!",
                        ["value"] = "deploy new AAA",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "pause?",
                        ["value"] = "we won!",
                    }, -- end of [7]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 99127.127435647,
                ["x"] = 195720.49136402,
                ["name"] = "Trigger Waves AAA",
                ["type"] = 0,
            }, -- end of [14]
            [15] = 
            {
                ["radius"] = 50,
                ["zoneId"] = 226,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 0,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "startDelay?",
                        ["value"] = "inv-5",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "timeDelay",
                        ["value"] = "1",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "delayDone!",
                        ["value"] = "*start",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "cloner",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "clone?",
                        ["value"] = "*start",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "empty!",
                        ["value"] = "attackerRepelled",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "message",
                        ["value"] = "WARNING: Invaders Inbound on Harbour!",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "*start",
                    }, -- end of [9]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 102917.20985204,
                ["x"] = 187652.00913191,
                ["name"] = "Invader-5",
                ["type"] = 0,
            }, -- end of [15]
            [16] = 
            {
                ["radius"] = 3000,
                ["zoneId"] = 246,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "singleUse",
                        ["value"] = "yes",
                    }, -- end of [1]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 97708.660101201,
                ["x"] = 207525.26400868,
                ["name"] = "SSBClientConfig",
                ["type"] = 0,
            }, -- end of [16]
            [17] = 
            {
                ["radius"] = 1000,
                ["zoneId"] = 266,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.15,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "pilotSafe",
                        ["value"] = "",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "CSARBASE",
                        ["value"] = "Saipan Intl",
                    }, -- end of [2]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 101499.1701484,
                ["x"] = 180043.15472645,
                ["name"] = "airport",
                ["type"] = 0,
            }, -- end of [17]
            [18] = 
            {
                ["radius"] = 500,
                ["zoneId"] = 267,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.15,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "pilotSafe",
                        ["value"] = "",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "CSARBASE",
                        ["value"] = "Saipan Outerfield",
                    }, -- end of [2]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 102859.46774153,
                ["x"] = 180526.09146182,
                ["name"] = "airport-1",
                ["type"] = 0,
            }, -- end of [18]
            [19] = 
            {
                ["radius"] = 50,
                ["zoneId"] = 287,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 0,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "startDelay?",
                        ["value"] = "aaa-4",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "timeDelay",
                        ["value"] = "60",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "delayDone!",
                        ["value"] = "*start",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "cloner",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "clone?",
                        ["value"] = "*start",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "empty!",
                        ["value"] = "aaa destroyed",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "message",
                        ["value"] = "WARNING: new SAM has come on-line",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "*start",
                    }, -- end of [9]
                    [10] = 
                    {
                        ["key"] = "soundFile",
                        ["value"] = "Death BRASS.wav",
                    }, -- end of [10]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 105210.06265349,
                ["x"] = 189489.0499577,
                ["name"] = "AAA-4",
                ["type"] = 0,
            }, -- end of [19]
            [20] = 
            {
                ["radius"] = 500,
                ["zoneId"] = 307,
                ["color"] = 
                {
                    [1] = 0,
                    [2] = 0,
                    [3] = 1,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "message",
                        ["value"] = "GOOD JOB!",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "soundFile",
                        ["value"] = "Triumphant Victory.wav",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "we won!",
                    }, -- end of [4]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 113560.75923565,
                ["x"] = 190258.16655208,
                ["name"] = "Win Message",
                ["type"] = 0,
            }, -- end of [20]
            [21] = 
            {
                ["radius"] = 150,
                ["zoneId"] = 327,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.15,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "comment",
                        ["value"] = "late activation",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "raiseFlag!",
                        ["value"] = "*go",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "afterTime",
                        ["value"] = "1300-3000",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "cloner",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "clone?",
                        ["value"] = "*go",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "message",
                        ["value"] = "Disturbance reported from Managaha Island! Investigate.",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "*go",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "soundFile",
                        ["value"] = "claxon.ogg",
                    }, -- end of [9]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 99974.157738198,
                ["x"] = 193651.82167665,
                ["name"] = "Late Surprise ",
                ["type"] = 0,
            }, -- end of [21]
            [22] = 
            {
                ["radius"] = 300,
                ["zoneId"] = 347,
                ["color"] = 
                {
                    [1] = 0.50196078431373,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "unitZone",
                        ["value"] = "",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "lookFor",
                        ["value"] = "Inva*",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "filterFor",
                        ["value"] = "ground",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "enterZone!",
                        ["value"] = "mission fail",
                    }, -- end of [4]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 102549.91746188,
                ["x"] = 191505.80892515,
                ["name"] = "Enemy At The Gates!",
                ["type"] = 0,
            }, -- end of [22]
            [23] = 
            {
                ["radius"] = 500,
                ["zoneId"] = 367,
                ["color"] = 
                {
                    [1] = 0.50196078431373,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "message",
                        ["value"] = "Mission Failed!",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "soundFile",
                        ["value"] = "Death PIANO.wav",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "mission fail",
                    }, -- end of [4]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 112985.48048373,
                ["x"] = 189246.70083722,
                ["name"] = "Lose Mission",
                ["type"] = 0,
            }, -- end of [23]
            [24] = 
            {
                ["radius"] = 300,
                ["zoneId"] = 387,
                ["color"] = 
                {
                    [1] = 0.50196078431373,
                    [2] = 1,
                    [3] = 1,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "unitZone",
                        ["value"] = "",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "lookFor",
                        ["value"] = "Inva*",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "filterFor",
                        ["value"] = "ground",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "enterZone!",
                        ["value"] = "mission fail",
                    }, -- end of [4]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 101287.97591773,
                ["x"] = 180795.51418419,
                ["name"] = "Enemy At The Gates!-1",
                ["type"] = 0,
            }, -- end of [24]
            [25] = 
            {
                ["radius"] = 50,
                ["zoneId"] = 427,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 0,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "startDelay?",
                        ["value"] = "inv-6",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "timeDelay",
                        ["value"] = "1",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "delayDone!",
                        ["value"] = "*start",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "cloner",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "clone?",
                        ["value"] = "*start",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "empty!",
                        ["value"] = "attackerRepelled",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "message",
                        ["value"] = "WARNING: Invaders Inbound on Harbour!",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "*start",
                    }, -- end of [9]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 110657.2849712,
                ["x"] = 195785.58442325,
                ["name"] = "Invader-6",
                ["type"] = 0,
            }, -- end of [25]
            [26] = 
            {
                ["radius"] = 50,
                ["zoneId"] = 447,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 0,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "startDelay?",
                        ["value"] = "aaa-5",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "timeDelay",
                        ["value"] = "60",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "delayDone!",
                        ["value"] = "*start",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "cloner",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "clone?",
                        ["value"] = "*start",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "empty!",
                        ["value"] = "aaa destroyed",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "message",
                        ["value"] = "WARNING: new SAM has come on-line",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "*start",
                    }, -- end of [9]
                    [10] = 
                    {
                        ["key"] = "soundFile",
                        ["value"] = "Death BRASS.wav",
                    }, -- end of [10]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 106287.65005331,
                ["x"] = 194226.68565269,
                ["name"] = "AAA-5",
                ["type"] = 0,
            }, -- end of [26]
            [27] = 
            {
                ["radius"] = 50,
                ["zoneId"] = 467,
                ["color"] = 
                {
                    [1] = 1,
                    [2] = 0,
                    [3] = 0,
                    [4] = 0.14901960784314,
                }, -- end of ["color"]
                ["properties"] = 
                {
                    [1] = 
                    {
                        ["key"] = "startDelay?",
                        ["value"] = "inv-7",
                    }, -- end of [1]
                    [2] = 
                    {
                        ["key"] = "timeDelay",
                        ["value"] = "1",
                    }, -- end of [2]
                    [3] = 
                    {
                        ["key"] = "delayDone!",
                        ["value"] = "*start",
                    }, -- end of [3]
                    [4] = 
                    {
                        ["key"] = "cloner",
                        ["value"] = "",
                    }, -- end of [4]
                    [5] = 
                    {
                        ["key"] = "clone?",
                        ["value"] = "*start",
                    }, -- end of [5]
                    [6] = 
                    {
                        ["key"] = "empty!",
                        ["value"] = "attackerRepelled",
                    }, -- end of [6]
                    [7] = 
                    {
                        ["key"] = "messenger",
                        ["value"] = "",
                    }, -- end of [7]
                    [8] = 
                    {
                        ["key"] = "message",
                        ["value"] = "WARNING: Invaders Inbound on Harbour!",
                    }, -- end of [8]
                    [9] = 
                    {
                        ["key"] = "messageOut?",
                        ["value"] = "*start",
                    }, -- end of [9]
                }, -- end of ["properties"]
                ["hidden"] = true,
                ["y"] = 109315.90441321,
                ["x"] = 196044.57173049,
                ["name"] = "Invader-7",
                ["type"] = 0,
            }, -- end of [27]
        }, -- end of ["zones"]
    }, -- end of ["triggers"]
    ["map"] = 
    {
        ["centerY"] = 108452.29116582,
        ["zoom"] = 73914.359068115,
        ["centerX"] = 188310.7558753,
    }, -- end of ["map"]
    ["coalitions"] = 
    {
        ["neutrals"] = 
        {
            [1] = 70,
            [2] = 83,
            [3] = 23,
            [4] = 65,
            [5] = 86,
            [6] = 64,
            [7] = 25,
            [8] = 63,
            [9] = 76,
            [10] = 84,
            [11] = 29,
            [12] = 62,
            [13] = 30,
            [14] = 78,
            [15] = 87,
            [16] = 31,
            [17] = 61,
            [18] = 32,
            [19] = 33,
            [20] = 60,
            [21] = 17,
            [22] = 35,
            [23] = 69,
            [24] = 36,
            [25] = 59,
            [26] = 71,
            [27] = 79,
            [28] = 58,
            [29] = 57,
            [30] = 56,
            [31] = 55,
            [32] = 88,
            [33] = 73,
            [34] = 39,
            [35] = 89,
            [36] = 54,
            [37] = 77,
            [38] = 72,
            [39] = 41,
            [40] = 42,
            [41] = 44,
            [42] = 85,
            [43] = 75,
            [44] = 53,
            [45] = 22,
            [46] = 52,
            [47] = 66,
            [48] = 51,
            [49] = 74,
            [50] = 82,
            [51] = 7,
            [52] = 68,
            [53] = 50,
            [54] = 49,
            [55] = 48,
            [56] = 67,
        }, -- end of ["neutrals"]
        ["blue"] = 
        {
            [1] = 21,
            [2] = 11,
            [3] = 8,
            [4] = 80,
            [5] = 28,
            [6] = 26,
            [7] = 13,
            [8] = 5,
            [9] = 16,
            [10] = 6,
            [11] = 15,
            [12] = 20,
            [13] = 12,
            [14] = 40,
            [15] = 45,
            [16] = 9,
            [17] = 46,
            [18] = 10,
            [19] = 3,
            [20] = 4,
            [21] = 1,
            [22] = 2,
        }, -- end of ["blue"]
        ["red"] = 
        {
            [1] = 18,
            [2] = 24,
            [3] = 27,
            [4] = 81,
            [5] = 34,
            [6] = 37,
            [7] = 38,
            [8] = 0,
            [9] = 43,
            [10] = 19,
            [11] = 47,
        }, -- end of ["red"]
    }, -- end of ["coalitions"]
    ["descriptionText"] = "DictKey_descriptionText_1",
    ["pictureFileNameR"] = 
    {
    }, -- end of ["pictureFileNameR"]
    ["descriptionBlueTask"] = "DictKey_descriptionBlueTask_3",
    ["descriptionRedTask"] = "DictKey_descriptionRedTask_2",
    ["pictureFileNameB"] = 
    {
    }, -- end of ["pictureFileNameB"]
    ["coalition"] = 
    {
        ["neutrals"] = 
        {
            ["bullseye"] = 
            {
                ["y"] = 0,
                ["x"] = 0,
            }, -- end of ["bullseye"]
            ["nav_points"] = 
            {
            }, -- end of ["nav_points"]
            ["name"] = "neutrals",
            ["country"] = 
            {
                [1] = 
                {
                    ["id"] = 82,
                    ["name"] = "UN",
                    ["ship"] = 
                    {
                        ["group"] = 
                        {
                            [1] = 
                            {
                                ["visible"] = false,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 109539.56277635,
                                            ["x"] = 182685.61872369,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2687.2460865563,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 116354.67906363,
                                            ["x"] = 204203.64960398,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 7.20222,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                        [3] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 18130.72637639,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 105242.74038681,
                                            ["x"] = 314874.54263192,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 7.20222,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [3]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 49,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Dry-cargo ship-2",
                                        ["unitId"] = 103,
                                        ["y"] = 109539.56277635,
                                        ["x"] = 182685.61872369,
                                        ["name"] = "Naval-1-5",
                                        ["heading"] = 0.30672164666732,
                                        ["modulation"] = 0,
                                        ["frequency"] = 127500000,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 109539.56277635,
                                ["x"] = 182685.61872369,
                                ["name"] = "Naval-1",
                                ["start_time"] = 0,
                            }, -- end of [1]
                            [2] = 
                            {
                                ["visible"] = false,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 102366.51818932,
                                            ["x"] = 192203.55722325,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 11080.404752442,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 29812.718430066,
                                            ["x"] = 158968.834683,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 7.20222,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                        [3] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 37286.644826899,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = -43662.444016285,
                                            ["x"] = -14885.589226409,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 7.20222,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [3]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 50,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "ZWEZDNY",
                                        ["unitId"] = 104,
                                        ["y"] = 102366.51818932,
                                        ["x"] = 192203.55722325,
                                        ["name"] = "Naval-2-1",
                                        ["heading"] = 4.2828443016596,
                                        ["modulation"] = 0,
                                        ["frequency"] = 127500000,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 102366.51818932,
                                ["x"] = 192203.55722325,
                                ["name"] = "Naval-2",
                                ["start_time"] = 0,
                            }, -- end of [2]
                        }, -- end of ["group"]
                    }, -- end of ["ship"]
                }, -- end of [1]
            }, -- end of ["country"]
        }, -- end of ["neutrals"]
        ["blue"] = 
        {
            ["bullseye"] = 
            {
                ["y"] = 0,
                ["x"] = 0,
            }, -- end of ["bullseye"]
            ["nav_points"] = 
            {
            }, -- end of ["nav_points"]
            ["name"] = "blue",
            ["country"] = 
            {
                [1] = 
                {
                    ["name"] = "USA",
                    ["id"] = 2,
                    ["vehicle"] = 
                    {
                        ["group"] = 
                        {
                            [1] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["hiddenOnMFD"] = true,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 65,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 101248.66476615,
                                            ["x"] = 180423.84914068,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "Off Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["enabled"] = true,
                                                            ["auto"] = false,
                                                            ["id"] = "WrappedAction",
                                                            ["number"] = 1,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = 4,
                                                                        ["name"] = 0,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                        [2] = 
                                                        {
                                                            ["enabled"] = true,
                                                            ["auto"] = false,
                                                            ["id"] = "WrappedAction",
                                                            ["number"] = 2,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "SetInvisible",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = true,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [2]
                                                        [3] = 
                                                        {
                                                            ["enabled"] = true,
                                                            ["auto"] = false,
                                                            ["id"] = "WrappedAction",
                                                            ["number"] = 3,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "SetImmortal",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = true,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [3]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 33,
                                ["hidden"] = true,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "AAV7",
                                        ["unitId"] = 69,
                                        ["y"] = 101248.66476615,
                                        ["x"] = 180423.84914068,
                                        ["name"] = "Ground-1-7",
                                        ["heading"] = 0,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101248.66476615,
                                ["x"] = 180423.84914068,
                                ["name"] = "Keeping The Spot",
                                ["start_time"] = 0,
                            }, -- end of [1]
                        }, -- end of ["group"]
                    }, -- end of ["vehicle"]
                    ["plane"] = 
                    {
                        ["group"] = 
                        {
                            [1] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Nothing",
                                ["uncontrolled"] = false,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 125,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101030.60134098,
                                            ["x"] = 180089.47823099,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 3,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 2000,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "104th FS Maryland ANG, Baltimore (MD)",
                                        ["skill"] = "Client",
                                        ["speed"] = 125,
                                        ["AddPropAircraft"] = 
                                        {
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "A-10A",
                                        ["unitId"] = 13,
                                        ["psi"] = -2.757620218151,
                                        ["y"] = 101030.60134098,
                                        ["x"] = 180089.47823099,
                                        ["name"] = "Hogger One",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "ALQ_184",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{DAC53A2F-79CA-42FF-A77A-F5649B601308}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [6]
                                                [7] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [7]
                                                [8] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [8]
                                                [9] = 
                                                {
                                                    ["CLSID"] = "LAU_88_AGM_65H_3",
                                                }, -- end of [9]
                                                [10] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [10]
                                                [11] = 
                                                {
                                                    ["CLSID"] = "LAU-105_2*AIM-9P5",
                                                }, -- end of [11]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 3017,
                                            ["flare"] = 120,
                                            ["ammo_type"] = 1,
                                            ["chaff"] = 240,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 2.757620218151,
                                        ["callsign"] = 
                                        {
                                            [1] = 1,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Enfield11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "010",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101030.60134098,
                                ["x"] = 180089.47823099,
                                ["name"] = "Hogger One",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 124,
                            }, -- end of [1]
                            [2] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Nothing",
                                ["uncontrolled"] = false,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 125,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101063.65324159,
                                            ["x"] = 180102.87345971,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 4,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 2000,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "104th FS Maryland ANG, Baltimore (MD)",
                                        ["skill"] = "Client",
                                        ["speed"] = 125,
                                        ["AddPropAircraft"] = 
                                        {
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "A-10A",
                                        ["unitId"] = 14,
                                        ["psi"] = -2.757620218151,
                                        ["y"] = 101063.65324159,
                                        ["x"] = 180102.87345971,
                                        ["name"] = "Hogger Two",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "ALQ_184",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{DAC53A2F-79CA-42FF-A77A-F5649B601308}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [6]
                                                [7] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [7]
                                                [8] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [8]
                                                [9] = 
                                                {
                                                    ["CLSID"] = "LAU_88_AGM_65H_3",
                                                }, -- end of [9]
                                                [10] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [10]
                                                [11] = 
                                                {
                                                    ["CLSID"] = "LAU-105_2*AIM-9P5",
                                                }, -- end of [11]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 3017,
                                            ["flare"] = 120,
                                            ["ammo_type"] = 1,
                                            ["chaff"] = 240,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 2.757620218151,
                                        ["callsign"] = 
                                        {
                                            [1] = 2,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Springfield11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "011",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101063.65324159,
                                ["x"] = 180102.87345971,
                                ["name"] = "Hogger Two",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 124,
                            }, -- end of [2]
                            [3] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Nothing",
                                ["uncontrolled"] = false,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 125,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101050.71855303,
                                            ["x"] = 180133.89287056,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 38,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 2000,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "104th FS Maryland ANG, Baltimore (MD)",
                                        ["skill"] = "Client",
                                        ["speed"] = 125,
                                        ["AddPropAircraft"] = 
                                        {
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "A-10A",
                                        ["unitId"] = 77,
                                        ["psi"] = -2.757620218151,
                                        ["y"] = 101050.71855303,
                                        ["x"] = 180133.89287056,
                                        ["name"] = "Cluster-Hog One",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "ALQ_184",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [6]
                                                [7] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [7]
                                                [8] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [8]
                                                [9] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [9]
                                                [10] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [10]
                                                [11] = 
                                                {
                                                    ["CLSID"] = "LAU-105_2*AIM-9P5",
                                                }, -- end of [11]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 3017,
                                            ["flare"] = 120,
                                            ["ammo_type"] = 1,
                                            ["chaff"] = 240,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 2.757620218151,
                                        ["callsign"] = 
                                        {
                                            [1] = 3,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Uzi11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "012",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101050.71855303,
                                ["x"] = 180133.89287056,
                                ["name"] = "Cluster-Hog One",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 124,
                            }, -- end of [3]
                            [4] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Nothing",
                                ["uncontrolled"] = false,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 125,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101018.55079712,
                                            ["x"] = 180121.72128725,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 39,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 2000,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "104th FS Maryland ANG, Baltimore (MD)",
                                        ["skill"] = "Client",
                                        ["speed"] = 125,
                                        ["AddPropAircraft"] = 
                                        {
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "A-10A",
                                        ["unitId"] = 78,
                                        ["psi"] = -2.757620218151,
                                        ["y"] = 101018.55079712,
                                        ["x"] = 180121.72128725,
                                        ["name"] = "Cluster-Hog Two",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "ALQ_184",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [6]
                                                [7] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [7]
                                                [8] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [8]
                                                [9] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [9]
                                                [10] = 
                                                {
                                                    ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}",
                                                }, -- end of [10]
                                                [11] = 
                                                {
                                                    ["CLSID"] = "LAU-105_2*AIM-9P5",
                                                }, -- end of [11]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 3017,
                                            ["flare"] = 120,
                                            ["ammo_type"] = 1,
                                            ["chaff"] = 240,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 2.757620218151,
                                        ["callsign"] = 
                                        {
                                            [1] = 4,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Colt11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "013",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101018.55079712,
                                ["x"] = 180121.72128725,
                                ["name"] = "Cluster-Hog Two",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 124,
                            }, -- end of [4]
                        }, -- end of ["group"]
                    }, -- end of ["plane"]
                    ["static"] = 
                    {
                        ["group"] = 
                        {
                            [1] = 
                            {
                                ["heading"] = 0,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "",
                                            ["name"] = "",
                                            ["y"] = 101577.23083918,
                                            ["speed"] = 0,
                                            ["x"] = 180441.10493126,
                                            ["formation_template"] = "",
                                            ["action"] = "",
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 55,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["category"] = "Fortifications",
                                        ["shape_name"] = "H-Windsock_RW",
                                        ["type"] = "Windsock",
                                        ["unitId"] = 109,
                                        ["rate"] = 3,
                                        ["y"] = 101577.23083918,
                                        ["x"] = 180441.10493126,
                                        ["name"] = "Static Windsock-1-1",
                                        ["heading"] = 0,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101577.23083918,
                                ["x"] = 180441.10493126,
                                ["name"] = "Static Windsock-1",
                                ["dead"] = false,
                            }, -- end of [1]
                            [2] = 
                            {
                                ["heading"] = 0,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "",
                                            ["name"] = "",
                                            ["y"] = 101510.8376325,
                                            ["speed"] = 0,
                                            ["x"] = 180194.8614358,
                                            ["formation_template"] = "",
                                            ["action"] = "",
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 56,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["category"] = "Fortifications",
                                        ["shape_name"] = "H-Windsock_RW",
                                        ["type"] = "Windsock",
                                        ["unitId"] = 110,
                                        ["rate"] = 3,
                                        ["y"] = 101510.8376325,
                                        ["x"] = 180194.8614358,
                                        ["name"] = "Static Windsock-2-1",
                                        ["heading"] = 0,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101510.8376325,
                                ["x"] = 180194.8614358,
                                ["name"] = "Static Windsock-2",
                                ["dead"] = false,
                            }, -- end of [2]
                            [3] = 
                            {
                                ["heading"] = 0,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "",
                                            ["name"] = "",
                                            ["y"] = 100712.39919864,
                                            ["speed"] = 0,
                                            ["x"] = 179487.62088707,
                                            ["formation_template"] = "",
                                            ["action"] = "",
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 57,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["category"] = "Fortifications",
                                        ["shape_name"] = "H-Windsock_RW",
                                        ["type"] = "Windsock",
                                        ["unitId"] = 111,
                                        ["rate"] = 3,
                                        ["y"] = 100712.39919864,
                                        ["x"] = 179487.62088707,
                                        ["name"] = "Static Windsock-3-1",
                                        ["heading"] = 0,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 100712.39919864,
                                ["x"] = 179487.62088707,
                                ["name"] = "Static Windsock-3",
                                ["dead"] = false,
                            }, -- end of [3]
                        }, -- end of ["group"]
                    }, -- end of ["static"]
                }, -- end of [1]
                [2] = 
                {
                    ["helicopter"] = 
                    {
                        ["group"] = 
                        {
                            [1] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "CAS",
                                ["uncontrolled"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["number"] = 1,
                                                            ["key"] = "CAS",
                                                            ["id"] = "EngageTargets",
                                                            ["enabled"] = true,
                                                            ["auto"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["targetTypes"] = 
                                                                {
                                                                    [1] = "Helicopters",
                                                                    [2] = "Ground Units",
                                                                    [3] = "Light armed ships",
                                                                }, -- end of ["targetTypes"]
                                                                ["priority"] = 0,
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101548.33335364,
                                            ["x"] = 180860.54878859,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 8,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 500,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Italy Aeronautica Militare",
                                        ["skill"] = "Client",
                                        ["ropeLength"] = 15,
                                        ["speed"] = 44.444444444444,
                                        ["type"] = "Ka-50",
                                        ["Radio"] = 
                                        {
                                            [1] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [7] = 40,
                                                    [1] = 21.5,
                                                    [2] = 25.7,
                                                    [4] = 28,
                                                    [8] = 50,
                                                    [9] = 55.5,
                                                    [5] = 30,
                                                    [10] = 59.9,
                                                    [3] = 27,
                                                    [6] = 32,
                                                }, -- end of ["channels"]
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [4] = 0.591,
                                                    [13] = 0.583,
                                                    [7] = 0.443,
                                                    [1] = 0.625,
                                                    [2] = 0.303,
                                                    [15] = 0.995,
                                                    [8] = 0.215,
                                                    [16] = 1.21,
                                                    [9] = 0.525,
                                                    [5] = 0.408,
                                                    [10] = 1.065,
                                                    [3] = 0.289,
                                                    [11] = 0.718,
                                                    [6] = 0.803,
                                                    [12] = 0.35,
                                                    [14] = 0.283,
                                                }, -- end of ["channels"]
                                            }, -- end of [2]
                                        }, -- end of ["Radio"]
                                        ["unitId"] = 24,
                                        ["psi"] = -2.9496064358704,
                                        ["y"] = 101548.33335364,
                                        ["x"] = 180860.54878859,
                                        ["name"] = "Sharky One",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}",
                                                }, -- end of [4]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = "1450",
                                            ["flare"] = 128,
                                            ["chaff"] = 0,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 2.9496064358704,
                                        ["callsign"] = 
                                        {
                                            [1] = 1,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Enfield11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "010",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101548.33335364,
                                ["x"] = 180860.54878859,
                                ["name"] = "Sharky One",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 124,
                            }, -- end of [1]
                            [2] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "CAS",
                                ["uncontrolled"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["number"] = 1,
                                                            ["key"] = "CAS",
                                                            ["id"] = "EngageTargets",
                                                            ["enabled"] = true,
                                                            ["auto"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["targetTypes"] = 
                                                                {
                                                                    [1] = "Helicopters",
                                                                    [2] = "Ground Units",
                                                                    [3] = "Light armed ships",
                                                                }, -- end of ["targetTypes"]
                                                                ["priority"] = 0,
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101525.72244868,
                                            ["x"] = 180854.94437624,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 9,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 500,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Italy Aeronautica Militare",
                                        ["skill"] = "Client",
                                        ["ropeLength"] = 15,
                                        ["speed"] = 44.444444444444,
                                        ["type"] = "Ka-50",
                                        ["Radio"] = 
                                        {
                                            [1] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [7] = 40,
                                                    [1] = 21.5,
                                                    [2] = 25.7,
                                                    [4] = 28,
                                                    [8] = 50,
                                                    [9] = 55.5,
                                                    [5] = 30,
                                                    [10] = 59.9,
                                                    [3] = 27,
                                                    [6] = 32,
                                                }, -- end of ["channels"]
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [4] = 0.591,
                                                    [13] = 0.583,
                                                    [7] = 0.443,
                                                    [1] = 0.625,
                                                    [2] = 0.303,
                                                    [15] = 0.995,
                                                    [8] = 0.215,
                                                    [16] = 1.21,
                                                    [9] = 0.525,
                                                    [5] = 0.408,
                                                    [10] = 1.065,
                                                    [3] = 0.289,
                                                    [11] = 0.718,
                                                    [6] = 0.803,
                                                    [12] = 0.35,
                                                    [14] = 0.283,
                                                }, -- end of ["channels"]
                                            }, -- end of [2]
                                        }, -- end of ["Radio"]
                                        ["unitId"] = 25,
                                        ["psi"] = -2.9496064358704,
                                        ["y"] = 101525.72244868,
                                        ["x"] = 180854.94437624,
                                        ["name"] = "Sharky Two",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}",
                                                }, -- end of [4]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = "1450",
                                            ["flare"] = 128,
                                            ["chaff"] = 0,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 2.9496064358704,
                                        ["callsign"] = 
                                        {
                                            [1] = 2,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Springfield11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "011",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101525.72244868,
                                ["x"] = 180854.94437624,
                                ["name"] = "Sharky Two",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 124,
                            }, -- end of [2]
                            [3] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Transport",
                                ["uncontrolled"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101479.22385743,
                                            ["x"] = 180639.64823956,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 20,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 500,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Italy 15B Stormo S.A.R -Soccorso",
                                        ["skill"] = "Client",
                                        ["ropeLength"] = 15,
                                        ["speed"] = 44.444444444444,
                                        ["AddPropAircraft"] = 
                                        {
                                            ["SoloFlight"] = false,
                                            ["ExhaustScreen"] = true,
                                            ["GunnersAISkill"] = 90,
                                            ["NetCrewControlPriority"] = 0,
                                            ["EngineResource"] = 90,
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "UH-1H",
                                        ["Radio"] = 
                                        {
                                            [1] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 251,
                                                    [2] = 264,
                                                    [4] = 256,
                                                    [8] = 257,
                                                    [16] = 261,
                                                    [17] = 267,
                                                    [9] = 255,
                                                    [18] = 251,
                                                    [5] = 254,
                                                    [10] = 262,
                                                    [20] = 266,
                                                    [11] = 259,
                                                    [3] = 265,
                                                    [6] = 250,
                                                    [12] = 268,
                                                    [13] = 269,
                                                    [7] = 270,
                                                    [14] = 260,
                                                    [15] = 263,
                                                    [19] = 253,
                                                }, -- end of ["channels"]
                                            }, -- end of [1]
                                        }, -- end of ["Radio"]
                                        ["unitId"] = 51,
                                        ["psi"] = -1.535889741755,
                                        ["y"] = 101479.22385743,
                                        ["x"] = 180639.64823956,
                                        ["name"] = "Hooi One",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "M134_L",
                                                }, -- end of [1]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "M134_SIDE_L",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "M60_SIDE_R",
                                                }, -- end of [4]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "M134_R",
                                                }, -- end of [6]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = "631",
                                            ["flare"] = 60,
                                            ["chaff"] = 0,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 1.535889741755,
                                        ["callsign"] = 
                                        {
                                            [1] = 6,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Ford11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "015",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101479.22385743,
                                ["x"] = 180639.64823956,
                                ["name"] = "Hooi One",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 251,
                            }, -- end of [3]
                            [4] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Transport",
                                ["uncontrolled"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101477.70953277,
                                            ["x"] = 180620.62849889,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 21,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 500,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Italy 15B Stormo S.A.R -Soccorso",
                                        ["skill"] = "Client",
                                        ["ropeLength"] = 15,
                                        ["speed"] = 44.444444444444,
                                        ["AddPropAircraft"] = 
                                        {
                                            ["SoloFlight"] = false,
                                            ["ExhaustScreen"] = true,
                                            ["GunnersAISkill"] = 90,
                                            ["NetCrewControlPriority"] = 0,
                                            ["EngineResource"] = 90,
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "UH-1H",
                                        ["Radio"] = 
                                        {
                                            [1] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 251,
                                                    [2] = 264,
                                                    [4] = 256,
                                                    [8] = 257,
                                                    [16] = 261,
                                                    [17] = 267,
                                                    [9] = 255,
                                                    [18] = 251,
                                                    [5] = 254,
                                                    [10] = 262,
                                                    [20] = 266,
                                                    [11] = 259,
                                                    [3] = 265,
                                                    [6] = 250,
                                                    [12] = 268,
                                                    [13] = 269,
                                                    [7] = 270,
                                                    [14] = 260,
                                                    [15] = 263,
                                                    [19] = 253,
                                                }, -- end of ["channels"]
                                            }, -- end of [1]
                                        }, -- end of ["Radio"]
                                        ["unitId"] = 52,
                                        ["psi"] = -1.535889741755,
                                        ["y"] = 101477.70953277,
                                        ["x"] = 180620.62849889,
                                        ["name"] = "Hooi Two",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "M134_L",
                                                }, -- end of [1]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "M134_SIDE_L",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "M60_SIDE_R",
                                                }, -- end of [4]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "M134_R",
                                                }, -- end of [6]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = "631",
                                            ["flare"] = 60,
                                            ["chaff"] = 0,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 1.535889741755,
                                        ["callsign"] = 
                                        {
                                            [1] = 7,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Chevy11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "016",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101477.70953277,
                                ["x"] = 180620.62849889,
                                ["name"] = "Hooi Two",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 251,
                            }, -- end of [4]
                            [5] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "CAS",
                                ["uncontrolled"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["number"] = 1,
                                                            ["key"] = "CAS",
                                                            ["id"] = "EngageTargets",
                                                            ["enabled"] = true,
                                                            ["auto"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["targetTypes"] = 
                                                                {
                                                                    [1] = "Helicopters",
                                                                    [2] = "Ground Units",
                                                                    [3] = "Light armed ships",
                                                                }, -- end of ["targetTypes"]
                                                                ["priority"] = 0,
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101509.10458499,
                                            ["x"] = 180783.05468243,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 42,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 500,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Georgian Air Force",
                                        ["skill"] = "Client",
                                        ["ropeLength"] = 15,
                                        ["speed"] = 44.444444444444,
                                        ["AddPropAircraft"] = 
                                        {
                                            ["LeftEngineResource"] = 90,
                                            ["RightEngineResource"] = 90,
                                            ["PilotNVG"] = true,
                                            ["GunnersAISkill"] = 90,
                                            ["SimplifiedAI"] = false,
                                            ["OperatorNVG"] = true,
                                            ["ExhaustScreen"] = true,
                                            ["HideAngleBoxes"] = false,
                                            ["NetCrewControlPriority"] = 0,
                                            ["TrackAirTargets"] = true,
                                            ["NS430allow"] = true,
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "Mi-24P",
                                        ["Radio"] = 
                                        {
                                            [1] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 127.5,
                                                    [2] = 135,
                                                    [4] = 127,
                                                    [8] = 128,
                                                    [16] = 132,
                                                    [17] = 138,
                                                    [9] = 126,
                                                    [18] = 122,
                                                    [5] = 125,
                                                    [10] = 133,
                                                    [20] = 137,
                                                    [11] = 130,
                                                    [3] = 136,
                                                    [6] = 121,
                                                    [12] = 129,
                                                    [13] = 123,
                                                    [7] = 141,
                                                    [14] = 131,
                                                    [19] = 124,
                                                    [15] = 134,
                                                }, -- end of ["channels"]
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [7] = 40,
                                                    [1] = 21.5,
                                                    [2] = 25.7,
                                                    [4] = 28,
                                                    [8] = 50,
                                                    [9] = 55.5,
                                                    [5] = 30,
                                                    [10] = 59.9,
                                                    [3] = 27,
                                                    [6] = 32,
                                                }, -- end of ["channels"]
                                            }, -- end of [2]
                                        }, -- end of ["Radio"]
                                        ["unitId"] = 86,
                                        ["psi"] = -1.6406094968747,
                                        ["y"] = 101509.10458499,
                                        ["x"] = 180783.05468243,
                                        ["name"] = "Hind One",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
                                                }, -- end of [6]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 1191,
                                            ["flare"] = 192,
                                            ["ammo_type"] = 1,
                                            ["chaff"] = 0,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 1.6406094968747,
                                        ["callsign"] = 
                                        {
                                            [1] = 1,
                                            [2] = 2,
                                            [3] = 1,
                                            ["name"] = "Enfield21",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "019",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101509.10458499,
                                ["x"] = 180783.05468243,
                                ["name"] = "Hind One",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 127.5,
                            }, -- end of [5]
                            [6] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "CAS",
                                ["uncontrolled"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["number"] = 1,
                                                            ["key"] = "CAS",
                                                            ["id"] = "EngageTargets",
                                                            ["enabled"] = true,
                                                            ["auto"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["targetTypes"] = 
                                                                {
                                                                    [1] = "Helicopters",
                                                                    [2] = "Ground Units",
                                                                    [3] = "Light armed ships",
                                                                }, -- end of ["targetTypes"]
                                                                ["priority"] = 0,
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101506.3866257,
                                            ["x"] = 180760.9227282,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 43,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 500,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Georgian Air Force",
                                        ["skill"] = "Client",
                                        ["ropeLength"] = 15,
                                        ["speed"] = 44.444444444444,
                                        ["AddPropAircraft"] = 
                                        {
                                            ["LeftEngineResource"] = 90,
                                            ["RightEngineResource"] = 90,
                                            ["PilotNVG"] = true,
                                            ["GunnersAISkill"] = 90,
                                            ["SimplifiedAI"] = false,
                                            ["OperatorNVG"] = true,
                                            ["ExhaustScreen"] = true,
                                            ["HideAngleBoxes"] = false,
                                            ["NetCrewControlPriority"] = 0,
                                            ["TrackAirTargets"] = true,
                                            ["NS430allow"] = true,
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "Mi-24P",
                                        ["Radio"] = 
                                        {
                                            [1] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 127.5,
                                                    [2] = 135,
                                                    [4] = 127,
                                                    [8] = 128,
                                                    [16] = 132,
                                                    [17] = 138,
                                                    [9] = 126,
                                                    [18] = 122,
                                                    [5] = 125,
                                                    [10] = 133,
                                                    [20] = 137,
                                                    [11] = 130,
                                                    [3] = 136,
                                                    [6] = 121,
                                                    [12] = 129,
                                                    [13] = 123,
                                                    [7] = 141,
                                                    [14] = 131,
                                                    [19] = 124,
                                                    [15] = 134,
                                                }, -- end of ["channels"]
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [7] = 40,
                                                    [1] = 21.5,
                                                    [2] = 25.7,
                                                    [4] = 28,
                                                    [8] = 50,
                                                    [9] = 55.5,
                                                    [5] = 30,
                                                    [10] = 59.9,
                                                    [3] = 27,
                                                    [6] = 32,
                                                }, -- end of ["channels"]
                                            }, -- end of [2]
                                        }, -- end of ["Radio"]
                                        ["unitId"] = 87,
                                        ["psi"] = -1.6406094968747,
                                        ["y"] = 101506.3866257,
                                        ["x"] = 180760.9227282,
                                        ["name"] = "Hind Two",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
                                                }, -- end of [6]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 1191,
                                            ["flare"] = 192,
                                            ["ammo_type"] = 1,
                                            ["chaff"] = 0,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 1.6406094968747,
                                        ["callsign"] = 
                                        {
                                            [1] = 2,
                                            [2] = 2,
                                            [3] = 1,
                                            ["name"] = "Springfield21",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "020",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101506.3866257,
                                ["x"] = 180760.9227282,
                                ["name"] = "Hind Two",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 127.5,
                            }, -- end of [6]
                            [7] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Ground Attack",
                                ["uncontrolled"] = false,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101508.84447044,
                                            ["x"] = 180736.34333243,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 53,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 500,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "BP_RS01",
                                        ["skill"] = "Client",
                                        ["ropeLength"] = 15,
                                        ["speed"] = 44.444444444444,
                                        ["AddPropAircraft"] = 
                                        {
                                            ["LeftEngineResource"] = 90,
                                            ["RightEngineResource"] = 90,
                                            ["NetCrewControlPriority"] = 1,
                                            ["ExhaustScreen"] = true,
                                            ["CargoHalfdoor"] = true,
                                            ["GunnersAISkill"] = 90,
                                            ["AdditionalArmor"] = true,
                                            ["NS430allow"] = true,
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "Mi-8MT",
                                        ["Radio"] = 
                                        {
                                            [1] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 127.5,
                                                    [2] = 135,
                                                    [4] = 127,
                                                    [8] = 128,
                                                    [16] = 132,
                                                    [17] = 138,
                                                    [9] = 126,
                                                    [18] = 122,
                                                    [5] = 125,
                                                    [10] = 133,
                                                    [20] = 137,
                                                    [11] = 130,
                                                    [3] = 136,
                                                    [6] = 121,
                                                    [12] = 129,
                                                    [13] = 123,
                                                    [7] = 141,
                                                    [14] = 131,
                                                    [15] = 134,
                                                    [19] = 124,
                                                }, -- end of ["channels"]
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [7] = 40,
                                                    [1] = 21.5,
                                                    [2] = 25.7,
                                                    [4] = 28,
                                                    [8] = 50,
                                                    [9] = 55.5,
                                                    [5] = 30,
                                                    [10] = 59.9,
                                                    [3] = 27,
                                                    [6] = 32,
                                                }, -- end of ["channels"]
                                            }, -- end of [2]
                                        }, -- end of ["Radio"]
                                        ["unitId"] = 107,
                                        ["psi"] = -1.6406094968747,
                                        ["y"] = 101508.84447044,
                                        ["x"] = 180736.34333243,
                                        ["name"] = "Hind Two-1-1",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{05544F1A-C39C-466b-BC37-5BD1D52E57BB}",
                                                }, -- end of [5]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{05544F1A-C39C-466b-BC37-5BD1D52E57BB}",
                                                }, -- end of [2]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
                                                }, -- end of [4]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
                                                }, -- end of [3]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 1350,
                                            ["flare"] = 128,
                                            ["chaff"] = 0,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 1.6406094968747,
                                        ["callsign"] = 
                                        {
                                            [1] = 4,
                                            [2] = 2,
                                            [3] = 1,
                                            ["name"] = "Colt21",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "023",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101508.84447044,
                                ["x"] = 180736.34333243,
                                ["name"] = "Hippie One",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 127.5,
                            }, -- end of [7]
                            [8] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Ground Attack",
                                ["uncontrolled"] = false,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101502.09276709,
                                            ["x"] = 180710.6349235,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 54,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 500,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "BP_RS01",
                                        ["skill"] = "Client",
                                        ["ropeLength"] = 15,
                                        ["speed"] = 44.444444444444,
                                        ["AddPropAircraft"] = 
                                        {
                                            ["LeftEngineResource"] = 90,
                                            ["RightEngineResource"] = 90,
                                            ["NetCrewControlPriority"] = 1,
                                            ["ExhaustScreen"] = true,
                                            ["CargoHalfdoor"] = true,
                                            ["GunnersAISkill"] = 90,
                                            ["AdditionalArmor"] = true,
                                            ["NS430allow"] = true,
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "Mi-8MT",
                                        ["Radio"] = 
                                        {
                                            [1] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 127.5,
                                                    [2] = 135,
                                                    [4] = 127,
                                                    [8] = 128,
                                                    [16] = 132,
                                                    [17] = 138,
                                                    [9] = 126,
                                                    [18] = 122,
                                                    [5] = 125,
                                                    [10] = 133,
                                                    [20] = 137,
                                                    [11] = 130,
                                                    [3] = 136,
                                                    [6] = 121,
                                                    [12] = 129,
                                                    [13] = 123,
                                                    [7] = 141,
                                                    [14] = 131,
                                                    [15] = 134,
                                                    [19] = 124,
                                                }, -- end of ["channels"]
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [7] = 40,
                                                    [1] = 21.5,
                                                    [2] = 25.7,
                                                    [4] = 28,
                                                    [8] = 50,
                                                    [9] = 55.5,
                                                    [5] = 30,
                                                    [10] = 59.9,
                                                    [3] = 27,
                                                    [6] = 32,
                                                }, -- end of ["channels"]
                                            }, -- end of [2]
                                        }, -- end of ["Radio"]
                                        ["unitId"] = 108,
                                        ["psi"] = -1.6406094968747,
                                        ["y"] = 101502.09276709,
                                        ["x"] = 180710.6349235,
                                        ["name"] = "Hippie Two",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{05544F1A-C39C-466b-BC37-5BD1D52E57BB}",
                                                }, -- end of [5]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{05544F1A-C39C-466b-BC37-5BD1D52E57BB}",
                                                }, -- end of [2]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
                                                }, -- end of [4]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
                                                }, -- end of [3]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 1350,
                                            ["flare"] = 128,
                                            ["chaff"] = 0,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 1.6406094968747,
                                        ["callsign"] = 
                                        {
                                            [1] = 5,
                                            [2] = 2,
                                            [3] = 1,
                                            ["name"] = "Dodge21",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "024",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101502.09276709,
                                ["x"] = 180710.6349235,
                                ["name"] = "Hippie Two",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 127.5,
                            }, -- end of [8]
                        }, -- end of ["group"]
                    }, -- end of ["helicopter"]
                    ["name"] = "CJTF Blue",
                    ["id"] = 80,
                    ["static"] = 
                    {
                        ["group"] = 
                        {
                            [1] = 
                            {
                                ["heading"] = 2.2165681500328,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "",
                                            ["name"] = "",
                                            ["y"] = 101132.80489052,
                                            ["speed"] = 0,
                                            ["x"] = 180180.96024334,
                                            ["formation_template"] = "",
                                            ["action"] = "",
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 14,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["livery_id"] = "usaf standard",
                                        ["category"] = "Planes",
                                        ["type"] = "C-17A",
                                        ["unitId"] = 40,
                                        ["rate"] = "100",
                                        ["y"] = 101132.80489052,
                                        ["x"] = 180180.96024334,
                                        ["name"] = "Static C-17A-1-1",
                                        ["heading"] = 2.2165681500328,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101132.80489052,
                                ["x"] = 180180.96024334,
                                ["name"] = "Static C-17A-1",
                                ["dead"] = false,
                            }, -- end of [1]
                            [2] = 
                            {
                                ["heading"] = 1.535889741755,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "",
                                            ["name"] = "",
                                            ["y"] = 101504.02288886,
                                            ["speed"] = 0,
                                            ["x"] = 180836.85604027,
                                            ["formation_template"] = "",
                                            ["action"] = "",
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 18,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["livery_id"] = "ah-64_d_green neth",
                                        ["category"] = "Helicopters",
                                        ["type"] = "AH-64D",
                                        ["unitId"] = 49,
                                        ["rate"] = "50",
                                        ["y"] = 101504.02288886,
                                        ["x"] = 180836.85604027,
                                        ["name"] = "Static AH-64D-1-1",
                                        ["heading"] = 1.535889741755,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101504.02288886,
                                ["x"] = 180836.85604027,
                                ["name"] = "Static AH-64D-1",
                                ["dead"] = false,
                            }, -- end of [2]
                            [3] = 
                            {
                                ["heading"] = 1.535889741755,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "",
                                            ["name"] = "",
                                            ["y"] = 101501.15875707,
                                            ["speed"] = 0,
                                            ["x"] = 180818.82885787,
                                            ["formation_template"] = "",
                                            ["action"] = "",
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 19,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["livery_id"] = "ah-64_d_green neth",
                                        ["category"] = "Helicopters",
                                        ["type"] = "AH-64D",
                                        ["unitId"] = 50,
                                        ["rate"] = "50",
                                        ["y"] = 101501.15875707,
                                        ["x"] = 180818.82885787,
                                        ["name"] = "Static AH-64D-2-1",
                                        ["heading"] = 1.535889741755,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101501.15875707,
                                ["x"] = 180818.82885787,
                                ["name"] = "Static AH-64D-2",
                                ["dead"] = false,
                            }, -- end of [3]
                            [4] = 
                            {
                                ["heading"] = 2.7401669256311,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "",
                                            ["name"] = "",
                                            ["y"] = 101388.56975351,
                                            ["speed"] = 0,
                                            ["x"] = 180289.27211887,
                                            ["formation_template"] = "",
                                            ["action"] = "",
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 28,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["livery_id"] = "KRAF_15AL",
                                        ["category"] = "Planes",
                                        ["type"] = "C-130",
                                        ["unitId"] = 64,
                                        ["rate"] = "70",
                                        ["y"] = 101388.56975351,
                                        ["x"] = 180289.27211887,
                                        ["name"] = "Static C-130-1",
                                        ["heading"] = 2.7401669256311,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101388.56975351,
                                ["x"] = 180289.27211887,
                                ["name"] = "Static C-130-1",
                                ["dead"] = false,
                            }, -- end of [4]
                            [5] = 
                            {
                                ["heading"] = 2.7401669256311,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "",
                                            ["name"] = "",
                                            ["y"] = 101320.43356943,
                                            ["speed"] = 0,
                                            ["x"] = 180261.77857091,
                                            ["formation_template"] = "",
                                            ["action"] = "",
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 29,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["livery_id"] = "KRAF_15AL",
                                        ["category"] = "Planes",
                                        ["type"] = "C-130",
                                        ["unitId"] = 65,
                                        ["rate"] = "70",
                                        ["y"] = 101320.43356943,
                                        ["x"] = 180261.77857091,
                                        ["name"] = "Static C-130-2-1",
                                        ["heading"] = 2.7401669256311,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101320.43356943,
                                ["x"] = 180261.77857091,
                                ["name"] = "Static C-130-2",
                                ["dead"] = false,
                            }, -- end of [5]
                            [6] = 
                            {
                                ["heading"] = 2.8623399732707,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "",
                                            ["name"] = "",
                                            ["y"] = 101449.96974359,
                                            ["speed"] = 0,
                                            ["x"] = 180257.18250186,
                                            ["formation_template"] = "",
                                            ["action"] = "",
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 30,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["livery_id"] = "Aeroflot",
                                        ["category"] = "Planes",
                                        ["type"] = "Yak-40",
                                        ["unitId"] = 66,
                                        ["rate"] = "50",
                                        ["y"] = 101449.96974359,
                                        ["x"] = 180257.18250186,
                                        ["name"] = "Static Yak-40-1",
                                        ["heading"] = 2.8623399732707,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101449.96974359,
                                ["x"] = 180257.18250186,
                                ["name"] = "Static Yak-40-1",
                                ["dead"] = false,
                            }, -- end of [6]
                            [7] = 
                            {
                                ["heading"] = 2.8623399732707,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "",
                                            ["name"] = "",
                                            ["y"] = 101484.40134481,
                                            ["speed"] = 0,
                                            ["x"] = 180269.07959984,
                                            ["formation_template"] = "",
                                            ["action"] = "",
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 31,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["livery_id"] = "Aeroflot",
                                        ["category"] = "Planes",
                                        ["type"] = "Yak-40",
                                        ["unitId"] = 67,
                                        ["rate"] = "50",
                                        ["y"] = 101484.40134481,
                                        ["x"] = 180269.07959984,
                                        ["name"] = "Static Yak-40-2-1",
                                        ["heading"] = 2.8623399732707,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101484.40134481,
                                ["x"] = 180269.07959984,
                                ["name"] = "Static Yak-40-2",
                                ["dead"] = false,
                            }, -- end of [7]
                            [8] = 
                            {
                                ["heading"] = 2.8623399732707,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "",
                                            ["name"] = "",
                                            ["y"] = 101519.39280946,
                                            ["speed"] = 0,
                                            ["x"] = 180281.81649297,
                                            ["formation_template"] = "",
                                            ["action"] = "",
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 32,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["livery_id"] = "Aeroflot",
                                        ["category"] = "Planes",
                                        ["type"] = "Yak-40",
                                        ["unitId"] = 68,
                                        ["rate"] = "50",
                                        ["y"] = 101519.39280946,
                                        ["x"] = 180281.81649297,
                                        ["name"] = "Static Yak-40-3-1",
                                        ["heading"] = 2.8623399732707,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101519.39280946,
                                ["x"] = 180281.81649297,
                                ["name"] = "Static Yak-40-3",
                                ["dead"] = false,
                            }, -- end of [8]
                            [9] = 
                            {
                                ["heading"] = 2.0420352248334,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "",
                                            ["name"] = "",
                                            ["y"] = 101445.78231238,
                                            ["speed"] = 0,
                                            ["x"] = 180407.80934818,
                                            ["formation_template"] = "",
                                            ["action"] = "",
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 47,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["category"] = "Unarmed",
                                        ["type"] = "Ural ATsP-6",
                                        ["unitId"] = 101,
                                        ["rate"] = 5,
                                        ["y"] = 101445.78231238,
                                        ["x"] = 180407.80934818,
                                        ["name"] = "Static Firefighter Ural ATsP-6-1-1",
                                        ["heading"] = 2.0420352248334,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101445.78231238,
                                ["x"] = 180407.80934818,
                                ["name"] = "Static Firefighter Ural ATsP-6-1",
                                ["dead"] = false,
                            }, -- end of [9]
                            [10] = 
                            {
                                ["heading"] = 2.0420352248334,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "",
                                            ["name"] = "",
                                            ["y"] = 101443.80361581,
                                            ["speed"] = 0,
                                            ["x"] = 180403.3572809,
                                            ["formation_template"] = "",
                                            ["action"] = "",
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 48,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["category"] = "Unarmed",
                                        ["type"] = "Ural ATsP-6",
                                        ["unitId"] = 102,
                                        ["rate"] = 5,
                                        ["y"] = 101443.80361581,
                                        ["x"] = 180403.3572809,
                                        ["name"] = "Static Firefighter Ural ATsP-6-2-1",
                                        ["heading"] = 2.0420352248334,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101443.80361581,
                                ["x"] = 180403.3572809,
                                ["name"] = "Static Firefighter Ural ATsP-6-2",
                                ["dead"] = false,
                            }, -- end of [10]
                        }, -- end of ["group"]
                    }, -- end of ["static"]
                    ["plane"] = 
                    {
                        ["group"] = 
                        {
                            [1] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Nothing",
                                ["uncontrolled"] = false,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 180.55555555556,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101113.03811671,
                                            ["x"] = 180118.55371463,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 12,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 2000,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Algerian AF Desert KU-03",
                                        ["skill"] = "Client",
                                        ["speed"] = 180.55555555556,
                                        ["type"] = "Su-25T",
                                        ["unitId"] = 38,
                                        ["psi"] = -2.757620218151,
                                        ["y"] = 101113.03811671,
                                        ["x"] = 180118.55371463,
                                        ["name"] = "Frogger Ground",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82D}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{F789E86A-EE2E-4E6B-B81E-D5E5F903B6ED}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{B1EF6B0E-3D91-4047-A7A5-A99E7D8B4A8B}",
                                                }, -- end of [6]
                                                [7] = 
                                                {
                                                    ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}",
                                                }, -- end of [7]
                                                [8] = 
                                                {
                                                    ["CLSID"] = "{F789E86A-EE2E-4E6B-B81E-D5E5F903B6ED}",
                                                }, -- end of [8]
                                                [9] = 
                                                {
                                                    ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}",
                                                }, -- end of [9]
                                                [10] = 
                                                {
                                                    ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}",
                                                }, -- end of [10]
                                                [11] = 
                                                {
                                                    ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82C}",
                                                }, -- end of [11]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = "3790",
                                            ["flare"] = 128,
                                            ["chaff"] = 128,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 2.757620218151,
                                        ["callsign"] = 
                                        {
                                            [1] = 3,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Uzi11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "012",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101113.03811671,
                                ["x"] = 180118.55371463,
                                ["name"] = "Frogger Ground",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 124,
                            }, -- end of [1]
                            [2] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "SEAD",
                                ["uncontrolled"] = false,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 180.55555555556,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["number"] = 1,
                                                            ["key"] = "SEAD",
                                                            ["id"] = "EngageTargets",
                                                            ["enabled"] = true,
                                                            ["auto"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["targetTypes"] = 
                                                                {
                                                                    [1] = "Air Defence",
                                                                }, -- end of ["targetTypes"]
                                                                ["priority"] = 0,
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                        [2] = 
                                                        {
                                                            ["number"] = 2,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = 2,
                                                                        ["name"] = 1,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [2]
                                                        [3] = 
                                                        {
                                                            ["number"] = 3,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = 2,
                                                                        ["name"] = 13,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [3]
                                                        [4] = 
                                                        {
                                                            ["number"] = 4,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = true,
                                                                        ["name"] = 19,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [4]
                                                        [5] = 
                                                        {
                                                            ["number"] = 5,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["targetTypes"] = 
                                                                        {
                                                                            [1] = "Air Defence",
                                                                        }, -- end of ["targetTypes"]
                                                                        ["name"] = 21,
                                                                        ["value"] = "Air Defence;",
                                                                        ["noTargetTypes"] = 
                                                                        {
                                                                            [1] = "Fighters",
                                                                            [2] = "Multirole fighters",
                                                                            [3] = "Bombers",
                                                                            [4] = "Helicopters",
                                                                            [5] = "Infantry",
                                                                            [6] = "Fortifications",
                                                                            [7] = "Tanks",
                                                                            [8] = "IFV",
                                                                            [9] = "APC",
                                                                            [10] = "Artillery",
                                                                            [11] = "Unarmed vehicles",
                                                                            [12] = "Aircraft Carriers",
                                                                            [13] = "Cruisers",
                                                                            [14] = "Destroyers",
                                                                            [15] = "Frigates",
                                                                            [16] = "Corvettes",
                                                                            [17] = "Light armed ships",
                                                                            [18] = "Unarmed ships",
                                                                            [19] = "Submarines",
                                                                            [20] = "Cruise missiles",
                                                                            [21] = "Antiship Missiles",
                                                                            [22] = "AA Missiles",
                                                                            [23] = "AG Missiles",
                                                                            [24] = "SA Missiles",
                                                                        }, -- end of ["noTargetTypes"]
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [5]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101233.33305442,
                                            ["x"] = 180164.86444182,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 13,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 2000,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Algerian AF Desert KU-03",
                                        ["skill"] = "Client",
                                        ["speed"] = 180.55555555556,
                                        ["type"] = "Su-25T",
                                        ["unitId"] = 39,
                                        ["psi"] = -2.757620218151,
                                        ["y"] = 101233.33305442,
                                        ["x"] = 180164.86444182,
                                        ["name"] = "Frogger Sammie",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82D}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{B5CA9846-776E-4230-B4FD-8BCC9BFB1676}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{0519A264-0AB6-11d6-9193-00A0249B6F00}",
                                                }, -- end of [6]
                                                [7] = 
                                                {
                                                    ["CLSID"] = "{B5CA9846-776E-4230-B4FD-8BCC9BFB1676}",
                                                }, -- end of [7]
                                                [8] = 
                                                {
                                                    ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}",
                                                }, -- end of [8]
                                                [9] = 
                                                {
                                                    ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}",
                                                }, -- end of [9]
                                                [10] = 
                                                {
                                                    ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}",
                                                }, -- end of [10]
                                                [11] = 
                                                {
                                                    ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82C}",
                                                }, -- end of [11]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = "3790",
                                            ["flare"] = 128,
                                            ["chaff"] = 128,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 2.757620218151,
                                        ["callsign"] = 
                                        {
                                            [1] = 4,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Colt11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "013",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101233.33305442,
                                ["x"] = 180164.86444182,
                                ["name"] = "Frogger Sammie",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 124,
                            }, -- end of [2]
                            [3] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Nothing",
                                ["uncontrolled"] = false,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 180.55555555556,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["number"] = 1,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "EPLRS",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = true,
                                                                        ["groupId"] = 1,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101583.94465154,
                                            ["x"] = 180469.09615191,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 17,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 2000,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "BP_AP141_BOLIVAR",
                                        ["skill"] = "Client",
                                        ["speed"] = 180.55555555556,
                                        ["AddPropAircraft"] = 
                                        {
                                            ["OuterBoard"] = 0,
                                            ["InnerBoard"] = 0,
                                            ["HelmetMountedDevice"] = 1,
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "FA-18C_hornet",
                                        ["Radio"] = 
                                        {
                                            [1] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                    [1] = 0,
                                                    [2] = 0,
                                                    [4] = 0,
                                                    [8] = 0,
                                                    [16] = 0,
                                                    [17] = 0,
                                                    [9] = 0,
                                                    [18] = 0,
                                                    [5] = 0,
                                                    [10] = 0,
                                                    [20] = 0,
                                                    [11] = 0,
                                                    [3] = 0,
                                                    [6] = 0,
                                                    [12] = 0,
                                                    [13] = 0,
                                                    [7] = 0,
                                                    [14] = 0,
                                                    [19] = 0,
                                                    [15] = 0,
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 305,
                                                    [2] = 264,
                                                    [4] = 256,
                                                    [8] = 257,
                                                    [16] = 261,
                                                    [17] = 267,
                                                    [9] = 255,
                                                    [18] = 251,
                                                    [5] = 254,
                                                    [10] = 262,
                                                    [20] = 266,
                                                    [11] = 259,
                                                    [3] = 265,
                                                    [6] = 250,
                                                    [12] = 268,
                                                    [13] = 269,
                                                    [7] = 270,
                                                    [14] = 260,
                                                    [19] = 253,
                                                    [15] = 263,
                                                }, -- end of ["channels"]
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                    [1] = 0,
                                                    [2] = 0,
                                                    [4] = 0,
                                                    [8] = 0,
                                                    [16] = 0,
                                                    [17] = 0,
                                                    [9] = 0,
                                                    [18] = 0,
                                                    [5] = 0,
                                                    [10] = 0,
                                                    [20] = 0,
                                                    [11] = 0,
                                                    [3] = 0,
                                                    [6] = 0,
                                                    [12] = 0,
                                                    [13] = 0,
                                                    [7] = 0,
                                                    [14] = 0,
                                                    [19] = 0,
                                                    [15] = 0,
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 305,
                                                    [2] = 264,
                                                    [4] = 256,
                                                    [8] = 257,
                                                    [16] = 261,
                                                    [17] = 267,
                                                    [9] = 255,
                                                    [18] = 251,
                                                    [5] = 254,
                                                    [10] = 262,
                                                    [20] = 266,
                                                    [11] = 259,
                                                    [3] = 265,
                                                    [6] = 250,
                                                    [12] = 268,
                                                    [13] = 269,
                                                    [7] = 270,
                                                    [14] = 260,
                                                    [19] = 253,
                                                    [15] = 263,
                                                }, -- end of ["channels"]
                                            }, -- end of [2]
                                        }, -- end of ["Radio"]
                                        ["unitId"] = 48,
                                        ["psi"] = -4.7822021504645,
                                        ["dataCartridge"] = 
                                        {
                                            ["GroupsPoints"] = 
                                            {
                                                ["Initial Point"] = 
                                                {
                                                }, -- end of ["Initial Point"]
                                                ["Sequence 2 Red"] = 
                                                {
                                                }, -- end of ["Sequence 2 Red"]
                                                ["PB"] = 
                                                {
                                                }, -- end of ["PB"]
                                                ["Sequence 1 Blue"] = 
                                                {
                                                }, -- end of ["Sequence 1 Blue"]
                                                ["Sequence 3 Yellow"] = 
                                                {
                                                }, -- end of ["Sequence 3 Yellow"]
                                                ["A/A Waypoint"] = 
                                                {
                                                }, -- end of ["A/A Waypoint"]
                                                ["PP"] = 
                                                {
                                                }, -- end of ["PP"]
                                                ["Start Location"] = 
                                                {
                                                }, -- end of ["Start Location"]
                                            }, -- end of ["GroupsPoints"]
                                            ["Points"] = 
                                            {
                                            }, -- end of ["Points"]
                                        }, -- end of ["dataCartridge"]
                                        ["y"] = 101583.94465154,
                                        ["x"] = 180469.09615191,
                                        ["name"] = "Bugger Harmer",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{AWW-13}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
                                                }, -- end of [6]
                                                [7] = 
                                                {
                                                    ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
                                                }, -- end of [7]
                                                [8] = 
                                                {
                                                    ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
                                                }, -- end of [8]
                                                [9] = 
                                                {
                                                    ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}",
                                                }, -- end of [9]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 4900,
                                            ["flare"] = 60,
                                            ["ammo_type"] = 1,
                                            ["chaff"] = 60,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 4.7822021504645,
                                        ["callsign"] = 
                                        {
                                            [1] = 5,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Dodge11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "014",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101583.94465154,
                                ["x"] = 180469.09615191,
                                ["name"] = "Bugger Harmer",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 305,
                            }, -- end of [3]
                            [4] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Nothing",
                                ["uncontrolled"] = false,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 180.55555555556,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["number"] = 1,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "EPLRS",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = true,
                                                                        ["groupId"] = 2,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101586.94775265,
                                            ["x"] = 180520.85823745,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 22,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 2000,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "BP_AP141_BOLIVAR",
                                        ["skill"] = "Client",
                                        ["speed"] = 180.55555555556,
                                        ["AddPropAircraft"] = 
                                        {
                                            ["OuterBoard"] = 0,
                                            ["InnerBoard"] = 0,
                                            ["HelmetMountedDevice"] = 1,
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "FA-18C_hornet",
                                        ["Radio"] = 
                                        {
                                            [1] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                    [1] = 0,
                                                    [2] = 0,
                                                    [4] = 0,
                                                    [8] = 0,
                                                    [16] = 0,
                                                    [17] = 0,
                                                    [9] = 0,
                                                    [18] = 0,
                                                    [5] = 0,
                                                    [10] = 0,
                                                    [20] = 0,
                                                    [11] = 0,
                                                    [3] = 0,
                                                    [6] = 0,
                                                    [12] = 0,
                                                    [13] = 0,
                                                    [7] = 0,
                                                    [14] = 0,
                                                    [15] = 0,
                                                    [19] = 0,
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 305,
                                                    [2] = 264,
                                                    [4] = 256,
                                                    [8] = 257,
                                                    [16] = 261,
                                                    [17] = 267,
                                                    [9] = 255,
                                                    [18] = 251,
                                                    [5] = 254,
                                                    [10] = 262,
                                                    [20] = 266,
                                                    [11] = 259,
                                                    [3] = 265,
                                                    [6] = 250,
                                                    [12] = 268,
                                                    [13] = 269,
                                                    [7] = 270,
                                                    [14] = 260,
                                                    [15] = 263,
                                                    [19] = 253,
                                                }, -- end of ["channels"]
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                    [1] = 0,
                                                    [2] = 0,
                                                    [4] = 0,
                                                    [8] = 0,
                                                    [16] = 0,
                                                    [17] = 0,
                                                    [9] = 0,
                                                    [18] = 0,
                                                    [5] = 0,
                                                    [10] = 0,
                                                    [20] = 0,
                                                    [11] = 0,
                                                    [3] = 0,
                                                    [6] = 0,
                                                    [12] = 0,
                                                    [13] = 0,
                                                    [7] = 0,
                                                    [14] = 0,
                                                    [15] = 0,
                                                    [19] = 0,
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 305,
                                                    [2] = 264,
                                                    [4] = 256,
                                                    [8] = 257,
                                                    [16] = 261,
                                                    [17] = 267,
                                                    [9] = 255,
                                                    [18] = 251,
                                                    [5] = 254,
                                                    [10] = 262,
                                                    [20] = 266,
                                                    [11] = 259,
                                                    [3] = 265,
                                                    [6] = 250,
                                                    [12] = 268,
                                                    [13] = 269,
                                                    [7] = 270,
                                                    [14] = 260,
                                                    [15] = 263,
                                                    [19] = 253,
                                                }, -- end of ["channels"]
                                            }, -- end of [2]
                                        }, -- end of ["Radio"]
                                        ["unitId"] = 53,
                                        ["psi"] = -4.7822021504645,
                                        ["dataCartridge"] = 
                                        {
                                            ["GroupsPoints"] = 
                                            {
                                                ["PB"] = 
                                                {
                                                }, -- end of ["PB"]
                                                ["Sequence 2 Red"] = 
                                                {
                                                }, -- end of ["Sequence 2 Red"]
                                                ["Start Location"] = 
                                                {
                                                }, -- end of ["Start Location"]
                                                ["Sequence 1 Blue"] = 
                                                {
                                                }, -- end of ["Sequence 1 Blue"]
                                                ["Sequence 3 Yellow"] = 
                                                {
                                                }, -- end of ["Sequence 3 Yellow"]
                                                ["A/A Waypoint"] = 
                                                {
                                                }, -- end of ["A/A Waypoint"]
                                                ["PP"] = 
                                                {
                                                }, -- end of ["PP"]
                                                ["Initial Point"] = 
                                                {
                                                }, -- end of ["Initial Point"]
                                            }, -- end of ["GroupsPoints"]
                                            ["Points"] = 
                                            {
                                            }, -- end of ["Points"]
                                        }, -- end of ["dataCartridge"]
                                        ["y"] = 101586.94775265,
                                        ["x"] = 180520.85823745,
                                        ["name"] = "Bugger Misseleer",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "LAU-115_2*LAU-127_AIM-9X",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "LAU-115_2*LAU-127_AIM-120B",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{FPU_8A_FUEL_TANK}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}",
                                                }, -- end of [6]
                                                [7] = 
                                                {
                                                    ["CLSID"] = "LAU-115_2*LAU-127_AIM-120C",
                                                }, -- end of [7]
                                                [8] = 
                                                {
                                                    ["CLSID"] = "LAU-115_2*LAU-127_AIM-9X",
                                                }, -- end of [8]
                                                [9] = 
                                                {
                                                    ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}",
                                                }, -- end of [9]
                                                [10] = 
                                                {
                                                    ["CLSID"] = "{INV-SMOKE-RED}",
                                                }, -- end of [10]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 4900,
                                            ["flare"] = 60,
                                            ["ammo_type"] = 1,
                                            ["chaff"] = 60,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 4.7822021504645,
                                        ["callsign"] = 
                                        {
                                            [1] = 8,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Pontiac11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "017",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101586.94775265,
                                ["x"] = 180520.85823745,
                                ["name"] = "Bugger Misseleer",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 305,
                            }, -- end of [4]
                            [5] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Nothing",
                                ["uncontrolled"] = false,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 180.55555555556,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["number"] = 1,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "EPLRS",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = true,
                                                                        ["groupId"] = 3,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101586.88828043,
                                            ["x"] = 180562.07830166,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 34,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 2000,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "BP_AP141_BOLIVAR",
                                        ["skill"] = "Client",
                                        ["speed"] = 180.55555555556,
                                        ["AddPropAircraft"] = 
                                        {
                                            ["OuterBoard"] = 0,
                                            ["InnerBoard"] = 0,
                                            ["HelmetMountedDevice"] = 1,
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "FA-18C_hornet",
                                        ["Radio"] = 
                                        {
                                            [1] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                    [1] = 0,
                                                    [2] = 0,
                                                    [4] = 0,
                                                    [8] = 0,
                                                    [16] = 0,
                                                    [17] = 0,
                                                    [9] = 0,
                                                    [18] = 0,
                                                    [5] = 0,
                                                    [10] = 0,
                                                    [20] = 0,
                                                    [11] = 0,
                                                    [3] = 0,
                                                    [6] = 0,
                                                    [12] = 0,
                                                    [13] = 0,
                                                    [7] = 0,
                                                    [14] = 0,
                                                    [15] = 0,
                                                    [19] = 0,
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 305,
                                                    [2] = 264,
                                                    [4] = 256,
                                                    [8] = 257,
                                                    [16] = 261,
                                                    [17] = 267,
                                                    [9] = 255,
                                                    [18] = 251,
                                                    [5] = 254,
                                                    [10] = 262,
                                                    [20] = 266,
                                                    [11] = 259,
                                                    [3] = 265,
                                                    [6] = 250,
                                                    [12] = 268,
                                                    [13] = 269,
                                                    [7] = 270,
                                                    [14] = 260,
                                                    [15] = 263,
                                                    [19] = 253,
                                                }, -- end of ["channels"]
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                    [1] = 0,
                                                    [2] = 0,
                                                    [4] = 0,
                                                    [8] = 0,
                                                    [16] = 0,
                                                    [17] = 0,
                                                    [9] = 0,
                                                    [18] = 0,
                                                    [5] = 0,
                                                    [10] = 0,
                                                    [20] = 0,
                                                    [11] = 0,
                                                    [3] = 0,
                                                    [6] = 0,
                                                    [12] = 0,
                                                    [13] = 0,
                                                    [7] = 0,
                                                    [14] = 0,
                                                    [15] = 0,
                                                    [19] = 0,
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 305,
                                                    [2] = 264,
                                                    [4] = 256,
                                                    [8] = 257,
                                                    [16] = 261,
                                                    [17] = 267,
                                                    [9] = 255,
                                                    [18] = 251,
                                                    [5] = 254,
                                                    [10] = 262,
                                                    [20] = 266,
                                                    [11] = 259,
                                                    [3] = 265,
                                                    [6] = 250,
                                                    [12] = 268,
                                                    [13] = 269,
                                                    [7] = 270,
                                                    [14] = 260,
                                                    [15] = 263,
                                                    [19] = 253,
                                                }, -- end of ["channels"]
                                            }, -- end of [2]
                                        }, -- end of ["Radio"]
                                        ["unitId"] = 70,
                                        ["psi"] = -4.7822021504645,
                                        ["dataCartridge"] = 
                                        {
                                            ["GroupsPoints"] = 
                                            {
                                                ["PB"] = 
                                                {
                                                }, -- end of ["PB"]
                                                ["Sequence 2 Red"] = 
                                                {
                                                }, -- end of ["Sequence 2 Red"]
                                                ["Start Location"] = 
                                                {
                                                }, -- end of ["Start Location"]
                                                ["Sequence 1 Blue"] = 
                                                {
                                                }, -- end of ["Sequence 1 Blue"]
                                                ["Sequence 3 Yellow"] = 
                                                {
                                                }, -- end of ["Sequence 3 Yellow"]
                                                ["A/A Waypoint"] = 
                                                {
                                                }, -- end of ["A/A Waypoint"]
                                                ["PP"] = 
                                                {
                                                }, -- end of ["PP"]
                                                ["Initial Point"] = 
                                                {
                                                }, -- end of ["Initial Point"]
                                            }, -- end of ["GroupsPoints"]
                                            ["Points"] = 
                                            {
                                            }, -- end of ["Points"]
                                        }, -- end of ["dataCartridge"]
                                        ["y"] = 101586.88828043,
                                        ["x"] = 180562.07830166,
                                        ["name"] = "Bugger JSOW",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{CBU_99}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{BRU55_2*AGM-154A}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
                                                }, -- end of [6]
                                                [7] = 
                                                {
                                                    ["CLSID"] = "{BRU55_2*AGM-154A}",
                                                }, -- end of [7]
                                                [8] = 
                                                {
                                                    ["CLSID"] = "{CBU_99}",
                                                }, -- end of [8]
                                                [9] = 
                                                {
                                                    ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}",
                                                }, -- end of [9]
                                                [10] = 
                                                {
                                                    ["CLSID"] = "{INV-SMOKE-RED}",
                                                }, -- end of [10]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 4900,
                                            ["flare"] = 60,
                                            ["ammo_type"] = 1,
                                            ["chaff"] = 60,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 4.7822021504645,
                                        ["callsign"] = 
                                        {
                                            [1] = 9,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Hornet11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "018",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101586.88828043,
                                ["x"] = 180562.07830166,
                                ["name"] = "Bugger JSOW",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 305,
                            }, -- end of [5]
                            [6] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Nothing",
                                ["uncontrolled"] = false,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 180.55555555556,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["number"] = 1,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "EPLRS",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = true,
                                                                        ["groupId"] = 4,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101584.28847708,
                                            ["x"] = 180493.61320021,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 51,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 2000,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "BP_AP141_BOLIVAR",
                                        ["skill"] = "Client",
                                        ["speed"] = 180.55555555556,
                                        ["AddPropAircraft"] = 
                                        {
                                            ["OuterBoard"] = 0,
                                            ["InnerBoard"] = 0,
                                            ["HelmetMountedDevice"] = 1,
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "FA-18C_hornet",
                                        ["Radio"] = 
                                        {
                                            [1] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                    [1] = 0,
                                                    [2] = 0,
                                                    [4] = 0,
                                                    [8] = 0,
                                                    [16] = 0,
                                                    [17] = 0,
                                                    [9] = 0,
                                                    [18] = 0,
                                                    [5] = 0,
                                                    [10] = 0,
                                                    [20] = 0,
                                                    [11] = 0,
                                                    [3] = 0,
                                                    [6] = 0,
                                                    [12] = 0,
                                                    [13] = 0,
                                                    [7] = 0,
                                                    [14] = 0,
                                                    [19] = 0,
                                                    [15] = 0,
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 305,
                                                    [2] = 264,
                                                    [4] = 256,
                                                    [8] = 257,
                                                    [16] = 261,
                                                    [17] = 267,
                                                    [9] = 255,
                                                    [18] = 251,
                                                    [5] = 254,
                                                    [10] = 262,
                                                    [20] = 266,
                                                    [11] = 259,
                                                    [3] = 265,
                                                    [6] = 250,
                                                    [12] = 268,
                                                    [13] = 269,
                                                    [7] = 270,
                                                    [14] = 260,
                                                    [19] = 253,
                                                    [15] = 263,
                                                }, -- end of ["channels"]
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["modulations"] = 
                                                {
                                                    [1] = 0,
                                                    [2] = 0,
                                                    [4] = 0,
                                                    [8] = 0,
                                                    [16] = 0,
                                                    [17] = 0,
                                                    [9] = 0,
                                                    [18] = 0,
                                                    [5] = 0,
                                                    [10] = 0,
                                                    [20] = 0,
                                                    [11] = 0,
                                                    [3] = 0,
                                                    [6] = 0,
                                                    [12] = 0,
                                                    [13] = 0,
                                                    [7] = 0,
                                                    [14] = 0,
                                                    [19] = 0,
                                                    [15] = 0,
                                                }, -- end of ["modulations"]
                                                ["channels"] = 
                                                {
                                                    [1] = 305,
                                                    [2] = 264,
                                                    [4] = 256,
                                                    [8] = 257,
                                                    [16] = 261,
                                                    [17] = 267,
                                                    [9] = 255,
                                                    [18] = 251,
                                                    [5] = 254,
                                                    [10] = 262,
                                                    [20] = 266,
                                                    [11] = 259,
                                                    [3] = 265,
                                                    [6] = 250,
                                                    [12] = 268,
                                                    [13] = 269,
                                                    [7] = 270,
                                                    [14] = 260,
                                                    [19] = 253,
                                                    [15] = 263,
                                                }, -- end of ["channels"]
                                            }, -- end of [2]
                                        }, -- end of ["Radio"]
                                        ["unitId"] = 105,
                                        ["psi"] = -4.7822021504645,
                                        ["dataCartridge"] = 
                                        {
                                            ["GroupsPoints"] = 
                                            {
                                                ["Initial Point"] = 
                                                {
                                                }, -- end of ["Initial Point"]
                                                ["Sequence 2 Red"] = 
                                                {
                                                }, -- end of ["Sequence 2 Red"]
                                                ["PB"] = 
                                                {
                                                }, -- end of ["PB"]
                                                ["Sequence 1 Blue"] = 
                                                {
                                                }, -- end of ["Sequence 1 Blue"]
                                                ["Start Location"] = 
                                                {
                                                }, -- end of ["Start Location"]
                                                ["A/A Waypoint"] = 
                                                {
                                                }, -- end of ["A/A Waypoint"]
                                                ["PP"] = 
                                                {
                                                }, -- end of ["PP"]
                                                ["Sequence 3 Yellow"] = 
                                                {
                                                }, -- end of ["Sequence 3 Yellow"]
                                            }, -- end of ["GroupsPoints"]
                                            ["Points"] = 
                                            {
                                            }, -- end of ["Points"]
                                        }, -- end of ["dataCartridge"]
                                        ["y"] = 101584.28847708,
                                        ["x"] = 180493.61320021,
                                        ["name"] = "Bugger Harmer Two",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{AWW-13}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
                                                }, -- end of [6]
                                                [7] = 
                                                {
                                                    ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
                                                }, -- end of [7]
                                                [8] = 
                                                {
                                                    ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
                                                }, -- end of [8]
                                                [9] = 
                                                {
                                                    ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}",
                                                }, -- end of [9]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 4900,
                                            ["flare"] = 60,
                                            ["ammo_type"] = 1,
                                            ["chaff"] = 60,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 4.7822021504645,
                                        ["callsign"] = 
                                        {
                                            [1] = 10,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Squid11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "021",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101584.28847708,
                                ["x"] = 180493.61320021,
                                ["name"] = "Bugger Harmer Two",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 305,
                            }, -- end of [6]
                            [7] = 
                            {
                                ["modulation"] = 0,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Nothing",
                                ["uncontrolled"] = false,
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "From Ground Area Hot",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 180.55555555556,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGroundHot",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 101263.7792396,
                                            ["x"] = 180175.64013207,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 52,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 2000,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Algerian AF Desert KU-03",
                                        ["skill"] = "Client",
                                        ["speed"] = 180.55555555556,
                                        ["type"] = "Su-25T",
                                        ["unitId"] = 106,
                                        ["psi"] = -2.757620218151,
                                        ["y"] = 101263.7792396,
                                        ["x"] = 180175.64013207,
                                        ["name"] = "Frogger Ground-1",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82D}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{F789E86A-EE2E-4E6B-B81E-D5E5F903B6ED}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{B1EF6B0E-3D91-4047-A7A5-A99E7D8B4A8B}",
                                                }, -- end of [6]
                                                [7] = 
                                                {
                                                    ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}",
                                                }, -- end of [7]
                                                [8] = 
                                                {
                                                    ["CLSID"] = "{F789E86A-EE2E-4E6B-B81E-D5E5F903B6ED}",
                                                }, -- end of [8]
                                                [9] = 
                                                {
                                                    ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}",
                                                }, -- end of [9]
                                                [10] = 
                                                {
                                                    ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}",
                                                }, -- end of [10]
                                                [11] = 
                                                {
                                                    ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82C}",
                                                }, -- end of [11]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = "3790",
                                            ["flare"] = 128,
                                            ["chaff"] = 128,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 2.757620218151,
                                        ["callsign"] = 
                                        {
                                            [1] = 3,
                                            [2] = 2,
                                            [3] = 1,
                                            ["name"] = "Uzi21",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "022",
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 101263.7792396,
                                ["x"] = 180175.64013207,
                                ["name"] = "Frogger Ground-1",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["uncontrollable"] = false,
                                ["frequency"] = 124,
                            }, -- end of [7]
                        }, -- end of ["group"]
                    }, -- end of ["plane"]
                }, -- end of [2]
            }, -- end of ["country"]
        }, -- end of ["blue"]
        ["red"] = 
        {
            ["bullseye"] = 
            {
                ["y"] = 0,
                ["x"] = 0,
            }, -- end of ["bullseye"]
            ["nav_points"] = 
            {
            }, -- end of ["nav_points"]
            ["name"] = "red",
            ["country"] = 
            {
                [1] = 
                {
                    ["helicopter"] = 
                    {
                        ["group"] = 
                        {
                            [1] = 
                            {
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Escort",
                                ["uncontrolled"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "From Ground Area",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["number"] = 1,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "EPLRS",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = true,
                                                                        ["groupId"] = 1,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGround",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 111412.82170191,
                                            ["x"] = 196945.01426159,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 106.07482940407,
                                            ["ETA_locked"] = false,
                                            ["y"] = 107435.3995444,
                                            ["x"] = 194414.00104343,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                        [3] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 194.12744344513,
                                            ["ETA_locked"] = false,
                                            ["y"] = 104217.52377947,
                                            ["x"] = 192186.81388205,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [3]
                                        [4] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 272.08109381842,
                                            ["ETA_locked"] = false,
                                            ["y"] = 101133.72617142,
                                            ["x"] = 190607.67114556,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [4]
                                        [5] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 308.2270642092,
                                            ["ETA_locked"] = false,
                                            ["y"] = 101007.09680104,
                                            ["x"] = 189006.18204959,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [5]
                                        [6] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 364.89243762103,
                                            ["ETA_locked"] = false,
                                            ["y"] = 102832.04949179,
                                            ["x"] = 187270.61479675,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [6]
                                        [7] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 454.85993616697,
                                            ["ETA_locked"] = false,
                                            ["y"] = 106817.15026549,
                                            ["x"] = 187598.36140243,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [7]
                                        [8] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 527.98171810143,
                                            ["ETA_locked"] = false,
                                            ["y"] = 106697.9696816,
                                            ["x"] = 190846.03231333,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [8]
                                        [9] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 568.47312724057,
                                            ["ETA_locked"] = false,
                                            ["y"] = 105215.66116952,
                                            ["x"] = 191866.51606286,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [9]
                                        [10] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 742.58511371674,
                                            ["ETA_locked"] = false,
                                            ["y"] = 111264.07580174,
                                            ["x"] = 196693.32971025,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [10]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 24,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 500,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Combat",
                                        ["skill"] = "High",
                                        ["ropeLength"] = 15,
                                        ["speed"] = 44.444444444444,
                                        ["AddPropAircraft"] = 
                                        {
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "SA342Mistral",
                                        ["unitId"] = 56,
                                        ["psi"] = -1.7681918865445,
                                        ["y"] = 111412.82170191,
                                        ["x"] = 196945.01426159,
                                        ["name"] = "Rotary-1-1",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 416.33,
                                            ["flare"] = 32,
                                            ["chaff"] = 0,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 1.7681918865445,
                                        ["callsign"] = 
                                        {
                                            [1] = 1,
                                            [2] = 2,
                                            [3] = 1,
                                            ["name"] = "Enfield21",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "018",
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["alt"] = 500,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Combat",
                                        ["skill"] = "Good",
                                        ["ropeLength"] = 15,
                                        ["speed"] = 44.444444444444,
                                        ["AddPropAircraft"] = 
                                        {
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "SA342Mistral",
                                        ["unitId"] = 57,
                                        ["psi"] = -0,
                                        ["y"] = 111444.35698118,
                                        ["x"] = 196926.57934824,
                                        ["name"] = "Rotary-1-2",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{MBDA_MistralD}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{MBDA_MistralG}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{MBDA_MistralD}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{MBDA_MistralG}",
                                                }, -- end of [4]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{IR_Deflector}",
                                                }, -- end of [6]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 416.33,
                                            ["flare"] = 32,
                                            ["chaff"] = 0,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 0,
                                        ["callsign"] = 
                                        {
                                            [1] = 1,
                                            [2] = 2,
                                            [3] = 2,
                                            ["name"] = "Enfield22",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "020",
                                    }, -- end of [2]
                                }, -- end of ["units"]
                                ["y"] = 111412.82170191,
                                ["x"] = 196945.01426159,
                                ["name"] = "Rotary-1",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["modulation"] = 0,
                                ["frequency"] = 124,
                            }, -- end of [1]
                            [2] = 
                            {
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "Escort",
                                ["uncontrolled"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "From Ground Area",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["number"] = 1,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["enabled"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "EPLRS",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = true,
                                                                        ["groupId"] = 2,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffGround",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 83849.293486136,
                                            ["x"] = 151143.4224073,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 367.87258457681,
                                            ["ETA_locked"] = false,
                                            ["y"] = 95239.022762556,
                                            ["x"] = 162873.42908276,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                        [3] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 524.45597491343,
                                            ["ETA_locked"] = false,
                                            ["y"] = 94354.05299692,
                                            ["x"] = 169776.19325473,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [3]
                                        [4] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 639.34983958494,
                                            ["ETA_locked"] = false,
                                            ["y"] = 94177.059043792,
                                            ["x"] = 174879.51890323,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [4]
                                        [5] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 828.52144223164,
                                            ["ETA_locked"] = false,
                                            ["y"] = 97038.461286017,
                                            ["x"] = 182785.24880958,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [5]
                                        [6] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 977.83058827659,
                                            ["ETA_locked"] = false,
                                            ["y"] = 102613.77080953,
                                            ["x"] = 186384.12585651,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [6]
                                        [7] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1103.9405265186,
                                            ["ETA_locked"] = false,
                                            ["y"] = 108218.57932523,
                                            ["x"] = 186354.62686432,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [7]
                                        [8] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1251.7968683202,
                                            ["ETA_locked"] = false,
                                            ["y"] = 103646.2355361,
                                            ["x"] = 191074.46561438,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [8]
                                        [9] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1429.3237664643,
                                            ["ETA_locked"] = false,
                                            ["y"] = 104472.20731737,
                                            ["x"] = 183227.7336924,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [9]
                                        [10] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1547.1648098928,
                                            ["ETA_locked"] = false,
                                            ["y"] = 106802.62770021,
                                            ["x"] = 178537.39393453,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [10]
                                        [11] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1681.9423204234,
                                            ["ETA_locked"] = false,
                                            ["y"] = 101640.30406733,
                                            ["x"] = 175498.99773918,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [11]
                                        [12] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1831.257367316,
                                            ["ETA_locked"] = false,
                                            ["y"] = 97362.950200084,
                                            ["x"] = 180572.82439549,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [12]
                                        [13] = 
                                        {
                                            ["alt"] = 500,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 44.444444444444,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2152.7440273392,
                                            ["ETA_locked"] = false,
                                            ["y"] = 108366.07428617,
                                            ["x"] = 189688.01298155,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [13]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 25,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 500,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Combat",
                                        ["skill"] = "High",
                                        ["ropeLength"] = 15,
                                        ["speed"] = 44.444444444444,
                                        ["AddPropAircraft"] = 
                                        {
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "SA342Mistral",
                                        ["unitId"] = 58,
                                        ["psi"] = -1.7681918865445,
                                        ["y"] = 83849.293486136,
                                        ["x"] = 151143.4224073,
                                        ["name"] = "Rotary-2-1",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 416.33,
                                            ["flare"] = 32,
                                            ["chaff"] = 0,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 1.7681918865445,
                                        ["callsign"] = 
                                        {
                                            [1] = 2,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Springfield11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "010",
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["alt"] = 500,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Combat",
                                        ["skill"] = "Good",
                                        ["ropeLength"] = 15,
                                        ["speed"] = 44.444444444444,
                                        ["AddPropAircraft"] = 
                                        {
                                        }, -- end of ["AddPropAircraft"]
                                        ["type"] = "SA342Mistral",
                                        ["unitId"] = 59,
                                        ["psi"] = -0,
                                        ["y"] = 83889.293486136,
                                        ["x"] = 151103.4224073,
                                        ["name"] = "Rotary-2-2",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{MBDA_MistralD}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{MBDA_MistralG}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{MBDA_MistralD}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{MBDA_MistralG}",
                                                }, -- end of [4]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{IR_Deflector}",
                                                }, -- end of [6]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 416.33,
                                            ["flare"] = 32,
                                            ["chaff"] = 0,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["heading"] = 0,
                                        ["callsign"] = 
                                        {
                                            [1] = 2,
                                            [2] = 1,
                                            [3] = 2,
                                            ["name"] = "Springfield12",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "011",
                                    }, -- end of [2]
                                }, -- end of ["units"]
                                ["y"] = 83849.293486136,
                                ["x"] = 151143.4224073,
                                ["name"] = "Rotary-2",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["modulation"] = 0,
                                ["frequency"] = 124,
                            }, -- end of [2]
                        }, -- end of ["group"]
                    }, -- end of ["helicopter"]
                    ["name"] = "CJTF Red",
                    ["ship"] = 
                    {
                        ["group"] = 
                        {
                            [1] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 99953.401364039,
                                            ["x"] = 193565.37609468,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 21.364962630946,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 99659.94378038,
                                            ["x"] = 193521.39262616,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                        [3] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 105.99379361019,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 99155.92191844,
                                            ["x"] = 192459.542182,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [3]
                                        [4] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 292.51302698567,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 101693.94754077,
                                            ["x"] = 191940.56215279,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [4]
                                        [5] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 316.93978982214,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 101889.45371616,
                                            ["x"] = 191663.29884951,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [5]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 36,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "speedboat",
                                        ["unitId"] = 72,
                                        ["y"] = 99953.401364039,
                                        ["x"] = 193565.37609468,
                                        ["name"] = "Naval-1-2",
                                        ["heading"] = 4.563616241342,
                                        ["modulation"] = 0,
                                        ["frequency"] = 127500000,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "speedboat",
                                        ["unitId"] = 73,
                                        ["y"] = 99923.910579689,
                                        ["x"] = 193609.38155926,
                                        ["name"] = "Naval-1-3",
                                        ["heading"] = 4.563616241342,
                                        ["modulation"] = 0,
                                        ["frequency"] = 127500000,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "speedboat",
                                        ["unitId"] = 74,
                                        ["y"] = 99889.276637935,
                                        ["x"] = 193629.97471382,
                                        ["name"] = "Naval-1-4",
                                        ["heading"] = 4.563616241342,
                                        ["modulation"] = 0,
                                        ["frequency"] = 127500000,
                                    }, -- end of [3]
                                }, -- end of ["units"]
                                ["y"] = 99953.401364039,
                                ["x"] = 193565.37609468,
                                ["name"] = "Sneaky Naval",
                                ["start_time"] = 0,
                            }, -- end of [1]
                        }, -- end of ["group"]
                    }, -- end of ["ship"]
                    ["id"] = 81,
                    ["vehicle"] = 
                    {
                        ["group"] = 
                        {
                            [1] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                        [1] = 
                                        {
                                            [31] = 
                                            {
                                                ["y"] = 104011.09133931,
                                                ["x"] = 192285.81293603,
                                            }, -- end of [31]
                                            [2] = 
                                            {
                                                ["y"] = 108374.24993266,
                                                ["x"] = 196109.43225581,
                                            }, -- end of [2]
                                            [8] = 
                                            {
                                                ["y"] = 107427.40457902,
                                                ["x"] = 194839.05927013,
                                            }, -- end of [8]
                                            [32] = 
                                            {
                                                ["y"] = 103999.67782218,
                                                ["x"] = 192269.39385374,
                                            }, -- end of [32]
                                            [33] = 
                                            {
                                                ["y"] = 103984.24229703,
                                                ["x"] = 192249.73171506,
                                            }, -- end of [33]
                                            [34] = 
                                            {
                                                ["y"] = 103717.39546889,
                                                ["x"] = 191918.97976126,
                                            }, -- end of [34]
                                            [35] = 
                                            {
                                                ["y"] = 103700.0270094,
                                                ["x"] = 191901.0023269,
                                            }, -- end of [35]
                                            [9] = 
                                            {
                                                ["y"] = 107417.13602892,
                                                ["x"] = 194828.1280608,
                                            }, -- end of [9]
                                            [36] = 
                                            {
                                                ["y"] = 103663.79948373,
                                                ["x"] = 191866.54582562,
                                            }, -- end of [36]
                                            [37] = 
                                            {
                                                ["y"] = 103656.1498605,
                                                ["x"] = 191860.10960213,
                                            }, -- end of [37]
                                            [38] = 
                                            {
                                                ["y"] = 103652.05514858,
                                                ["x"] = 191857.24218244,
                                            }, -- end of [38]
                                            [39] = 
                                            {
                                                ["y"] = 103647.74844106,
                                                ["x"] = 191854.70436275,
                                            }, -- end of [39]
                                            [10] = 
                                            {
                                                ["y"] = 107364.59724507,
                                                ["x"] = 194774.62039011,
                                            }, -- end of [10]
                                            [40] = 
                                            {
                                                ["y"] = 103643.22820173,
                                                ["x"] = 191852.5733272,
                                            }, -- end of [40]
                                            [41] = 
                                            {
                                                ["y"] = 103638.52451701,
                                                ["x"] = 191850.88220054,
                                            }, -- end of [41]
                                            [42] = 
                                            {
                                                ["y"] = 103633.69664907,
                                                ["x"] = 191849.58688208,
                                            }, -- end of [42]
                                            [43] = 
                                            {
                                                ["y"] = 103628.7897693,
                                                ["x"] = 191848.62926559,
                                            }, -- end of [43]
                                            [11] = 
                                            {
                                                ["y"] = 107322.58851459,
                                                ["x"] = 194739.12569065,
                                            }, -- end of [11]
                                            [44] = 
                                            {
                                                ["y"] = 103623.83683202,
                                                ["x"] = 191847.94998935,
                                            }, -- end of [44]
                                            [45] = 
                                            {
                                                ["y"] = 103613.86553264,
                                                ["x"] = 191847.22286087,
                                            }, -- end of [45]
                                            [46] = 
                                            {
                                                ["y"] = 103593.86818102,
                                                ["x"] = 191847.06159682,
                                            }, -- end of [46]
                                            [3] = 
                                            {
                                                ["y"] = 108352.94948403,
                                                ["x"] = 196081.67036913,
                                            }, -- end of [3]
                                            [12] = 
                                            {
                                                ["y"] = 107302.92084038,
                                                ["x"] = 194723.69908521,
                                            }, -- end of [12]
                                            [48] = 
                                            {
                                                ["y"] = 103484.14345435,
                                                ["x"] = 191854.55829857,
                                            }, -- end of [48]
                                            [49] = 
                                            {
                                                ["y"] = 103459.40698808,
                                                ["x"] = 191858.16376989,
                                            }, -- end of [49]
                                            [50] = 
                                            {
                                                ["y"] = 103312.03396251,
                                                ["x"] = 191885.90964352,
                                            }, -- end of [50]
                                            [51] = 
                                            {
                                                ["y"] = 103297.08838598,
                                                ["x"] = 191887.16262351,
                                            }, -- end of [51]
                                            [13] = 
                                            {
                                                ["y"] = 107290.48334258,
                                                ["x"] = 194715.31881829,
                                            }, -- end of [13]
                                            [52] = 
                                            {
                                                ["y"] = 103282.09441188,
                                                ["x"] = 191887.44515124,
                                            }, -- end of [52]
                                            [53] = 
                                            {
                                                ["y"] = 103272.10640749,
                                                ["x"] = 191886.98312968,
                                            }, -- end of [53]
                                            [54] = 
                                            {
                                                ["y"] = 103262.16142275,
                                                ["x"] = 191885.95088451,
                                            }, -- end of [54]
                                            [55] = 
                                            {
                                                ["y"] = 103252.286994,
                                                ["x"] = 191884.37727188,
                                            }, -- end of [55]
                                            [14] = 
                                            {
                                                ["y"] = 107281.87566926,
                                                ["x"] = 194710.23109579,
                                            }, -- end of [14]
                                            [56] = 
                                            {
                                                ["y"] = 103237.64774476,
                                                ["x"] = 191881.12119995,
                                            }, -- end of [56]
                                            [57] = 
                                            {
                                                ["y"] = 103223.25150768,
                                                ["x"] = 191876.91689958,
                                            }, -- end of [57]
                                            [58] = 
                                            {
                                                ["y"] = 103209.1294699,
                                                ["x"] = 191871.86647451,
                                            }, -- end of [58]
                                            [59] = 
                                            {
                                                ["y"] = 103195.30998421,
                                                ["x"] = 191866.03851404,
                                            }, -- end of [59]
                                            [15] = 
                                            {
                                                ["y"] = 107268.58692422,
                                                ["x"] = 194703.27739694,
                                            }, -- end of [15]
                                            [60] = 
                                            {
                                                ["y"] = 103177.33914725,
                                                ["x"] = 191857.26654991,
                                            }, -- end of [60]
                                            [61] = 
                                            {
                                                ["y"] = 103110.61125192,
                                                ["x"] = 191823.05974002,
                                            }, -- end of [61]
                                            [62] = 
                                            {
                                                ["y"] = 103014.3590077,
                                                ["x"] = 191781.04035344,
                                            }, -- end of [62]
                                            [1] = 
                                            {
                                                ["y"] = 108443.42135697,
                                                ["x"] = 196188.42509749,
                                            }, -- end of [1]
                                            [4] = 
                                            {
                                                ["y"] = 108346.26162431,
                                                ["x"] = 196074.24162098,
                                            }, -- end of [4]
                                            [16] = 
                                            {
                                                ["y"] = 107125.79225616,
                                                ["x"] = 194631.18418491,
                                            }, -- end of [16]
                                            [64] = 
                                            {
                                                ["y"] = 103004.95565426,
                                                ["x"] = 191782.77755828,
                                            }, -- end of [64]
                                            [65] = 
                                            {
                                                ["y"] = 103000.97934531,
                                                ["x"] = 191785.79959567,
                                            }, -- end of [65]
                                            [66] = 
                                            {
                                                ["y"] = 102985.81199221,
                                                ["x"] = 191798.81247827,
                                            }, -- end of [66]
                                            [17] = 
                                            {
                                                ["y"] = 104895.20627464,
                                                ["x"] = 193406.26938491,
                                            }, -- end of [17]
                                            [68] = 
                                            {
                                                ["y"] = 102977.10943894,
                                                ["x"] = 191803.71059083,
                                            }, -- end of [68]
                                            [69] = 
                                            {
                                                ["y"] = 102972.48007812,
                                                ["x"] = 191805.59839115,
                                            }, -- end of [69]
                                            [70] = 
                                            {
                                                ["y"] = 102967.74659436,
                                                ["x"] = 191807.2056975,
                                            }, -- end of [70]
                                            [18] = 
                                            {
                                                ["y"] = 104891.04084818,
                                                ["x"] = 193403.50821917,
                                            }, -- end of [18]
                                            [72] = 
                                            {
                                                ["y"] = 102958.02304372,
                                                ["x"] = 191809.51551583,
                                            }, -- end of [72]
                                            [73] = 
                                            {
                                                ["y"] = 102948.1126117,
                                                ["x"] = 191810.82786426,
                                            }, -- end of [73]
                                            [74] = 
                                            {
                                                ["y"] = 102938.13080342,
                                                ["x"] = 191811.40518017,
                                            }, -- end of [74]
                                            [19] = 
                                            {
                                                ["y"] = 104887.05756347,
                                                ["x"] = 193400.49005137,
                                            }, -- end of [19]
                                            [76] = 
                                            {
                                                ["y"] = 102928.14998152,
                                                ["x"] = 191810.95040194,
                                            }, -- end of [76]
                                            [77] = 
                                            {
                                                ["y"] = 102923.23664148,
                                                ["x"] = 191810.04468831,
                                            }, -- end of [77]
                                            [5] = 
                                            {
                                                ["y"] = 108343.44124864,
                                                ["x"] = 196070.11536834,
                                            }, -- end of [5]
                                            [20] = 
                                            {
                                                ["y"] = 104821.3459078,
                                                ["x"] = 193346.59145583,
                                            }, -- end of [20]
                                            [80] = 
                                            {
                                                ["y"] = 102890.76618757,
                                                ["x"] = 191797.14359093,
                                            }, -- end of [80]
                                            [81] = 
                                            {
                                                ["y"] = 102782.69711985,
                                                ["x"] = 191724.89982096,
                                            }, -- end of [81]
                                            [82] = 
                                            {
                                                ["y"] = 102467.78715383,
                                                ["x"] = 191486.46477925,
                                            }, -- end of [82]
                                            [21] = 
                                            {
                                                ["y"] = 104817.86738939,
                                                ["x"] = 193343.00268045,
                                            }, -- end of [21]
                                            [84] = 
                                            {
                                                ["y"] = 102381.87075349,
                                                ["x"] = 191417.9214264,
                                            }, -- end of [84]
                                            [85] = 
                                            {
                                                ["y"] = 102366.69788277,
                                                ["x"] = 191402.79534803,
                                            }, -- end of [85]
                                            [22] = 
                                            {
                                                ["y"] = 104778.66811231,
                                                ["x"] = 193297.57814812,
                                            }, -- end of [22]
                                            [23] = 
                                            {
                                                ["y"] = 104649.93861125,
                                                ["x"] = 193144.55380773,
                                            }, -- end of [23]
                                            [6] = 
                                            {
                                                ["y"] = 108317.58762777,
                                                ["x"] = 196027.33521466,
                                            }, -- end of [6]
                                            [24] = 
                                            {
                                                ["y"] = 104618.67614151,
                                                ["x"] = 193105.54012725,
                                            }, -- end of [24]
                                            [25] = 
                                            {
                                                ["y"] = 104154.72201684,
                                                ["x"] = 192548.48851199,
                                            }, -- end of [25]
                                            [26] = 
                                            {
                                                ["y"] = 104146.19232587,
                                                ["x"] = 192536.15196123,
                                            }, -- end of [26]
                                            [27] = 
                                            {
                                                ["y"] = 104109.56159,
                                                ["x"] = 192476.50419941,
                                            }, -- end of [27]
                                            [7] = 
                                            {
                                                ["y"] = 108308.7169846,
                                                ["x"] = 196015.24266258,
                                            }, -- end of [7]
                                            [28] = 
                                            {
                                                ["y"] = 104105.06062224,
                                                ["x"] = 192467.58222767,
                                            }, -- end of [28]
                                            [83] = 
                                            {
                                                ["y"] = 102392.78363353,
                                                ["x"] = 191428.20973034,
                                            }, -- end of [83]
                                            [79] = 
                                            {
                                                ["y"] = 102913.74719987,
                                                ["x"] = 191806.9152321,
                                            }, -- end of [79]
                                            [78] = 
                                            {
                                                ["y"] = 102918.43753096,
                                                ["x"] = 191808.6451455,
                                            }, -- end of [78]
                                            [29] = 
                                            {
                                                ["y"] = 104073.19564885,
                                                ["x"] = 192394.21808227,
                                            }, -- end of [29]
                                            [75] = 
                                            {
                                                ["y"] = 102933.13198362,
                                                ["x"] = 191811.36044924,
                                            }, -- end of [75]
                                            [71] = 
                                            {
                                                ["y"] = 102962.9190443,
                                                ["x"] = 191808.50400977,
                                            }, -- end of [71]
                                            [67] = 
                                            {
                                                ["y"] = 102981.57128489,
                                                ["x"] = 191801.45829379,
                                            }, -- end of [67]
                                            [30] = 
                                            {
                                                ["y"] = 104037.53053324,
                                                ["x"] = 192328.24761507,
                                            }, -- end of [30]
                                            [63] = 
                                            {
                                                ["y"] = 103009.49335735,
                                                ["x"] = 191780.71361018,
                                            }, -- end of [63]
                                            [47] = 
                                            {
                                                ["y"] = 103558.91512258,
                                                ["x"] = 191848.80649476,
                                            }, -- end of [47]
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            [1] = 
                                            {
                                                ["y"] = 102449.43293873,
                                                ["x"] = 191701.93642791,
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["y"] = 102449.43293873,
                                                ["x"] = 191701.93642791,
                                            }, -- end of [2]
                                        }, -- end of [2]
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 24,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 108444.73216494,
                                            ["x"] = 196187.25738747,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 7,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2899.92309184,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 102367.93620984,
                                            ["x"] = 191401.55524881,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 2.7777777777778,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 1,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 6,
                                        ["y"] = 108444.73216494,
                                        ["x"] = 196187.25738747,
                                        ["name"] = "Ground-1-6",
                                        ["heading"] = 3.8775198539248,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Gepard",
                                        ["unitId"] = 5,
                                        ["y"] = 108464.7776283,
                                        ["x"] = 196209.57793942,
                                        ["name"] = "Ground-1-5",
                                        ["heading"] = 3.8733415558597,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 4,
                                        ["y"] = 108485.15002397,
                                        ["x"] = 196231.82821314,
                                        ["name"] = "Ground-1-4",
                                        ["heading"] = 3.8829610923182,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [3]
                                    [4] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "T-90",
                                        ["unitId"] = 3,
                                        ["y"] = 108505.4109915,
                                        ["x"] = 196253.95272737,
                                        ["name"] = "Ground-1-3",
                                        ["heading"] = 3.883052486497,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [4]
                                    [5] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 2,
                                        ["y"] = 108525.11226319,
                                        ["x"] = 196276.55820047,
                                        ["name"] = "Ground-1-2",
                                        ["heading"] = 3.8584520427876,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [5]
                                    [6] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 1,
                                        ["y"] = 108547.55971807,
                                        ["x"] = 196302.67937414,
                                        ["name"] = "Ground-1-1",
                                        ["heading"] = 3.8514948308686,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [6]
                                }, -- end of ["units"]
                                ["y"] = 108444.73216494,
                                ["x"] = 196187.25738747,
                                ["name"] = "Invaders Two",
                                ["start_time"] = 0,
                            }, -- end of [1]
                            [2] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                        [1] = 
                                        {
                                            [127] = 
                                            {
                                                ["y"] = 106434.16021884,
                                                ["x"] = 190205.19971379,
                                            }, -- end of [127]
                                            [158] = 
                                            {
                                                ["y"] = 106459.00260717,
                                                ["x"] = 189955.96051746,
                                            }, -- end of [158]
                                            [190] = 
                                            {
                                                ["y"] = 106454.58333629,
                                                ["x"] = 189816.65784388,
                                            }, -- end of [190]
                                            [222] = 
                                            {
                                                ["y"] = 105797.16953924,
                                                ["x"] = 189939.62384652,
                                            }, -- end of [222]
                                            [1] = 
                                            {
                                                ["y"] = 107237.29675671,
                                                ["x"] = 191288.4005362,
                                            }, -- end of [1]
                                            [316] = 
                                            {
                                                ["y"] = 104005.99364028,
                                                ["x"] = 191102.20227088,
                                            }, -- end of [316]
                                            [380] = 
                                            {
                                                ["y"] = 103805.82777682,
                                                ["x"] = 191415.29336896,
                                            }, -- end of [380]
                                            [444] = 
                                            {
                                                ["y"] = 102935.38743573,
                                                ["x"] = 191811.41857013,
                                            }, -- end of [444]
                                            [2] = 
                                            {
                                                ["y"] = 107238.12485974,
                                                ["x"] = 191283.47527419,
                                            }, -- end of [2]
                                            [3] = 
                                            {
                                                ["y"] = 107238.50890074,
                                                ["x"] = 191278.49309695,
                                            }, -- end of [3]
                                            [4] = 
                                            {
                                                ["y"] = 107238.32123796,
                                                ["x"] = 191273.50006754,
                                            }, -- end of [4]
                                            [5] = 
                                            {
                                                ["y"] = 107237.38595351,
                                                ["x"] = 191268.59473047,
                                            }, -- end of [5]
                                            [6] = 
                                            {
                                                ["y"] = 107235.6951605,
                                                ["x"] = 191263.89572949,
                                            }, -- end of [6]
                                            [7] = 
                                            {
                                                ["y"] = 107233.3749541,
                                                ["x"] = 191259.47093657,
                                            }, -- end of [7]
                                            [8] = 
                                            {
                                                ["y"] = 107230.16404546,
                                                ["x"] = 191255.65142424,
                                            }, -- end of [8]
                                            [10] = 
                                            {
                                                ["y"] = 107221.88976191,
                                                ["x"] = 191250.10823482,
                                            }, -- end of [10]
                                            [12] = 
                                            {
                                                ["y"] = 107185.1501377,
                                                ["x"] = 191234.31132094,
                                            }, -- end of [12]
                                            [14] = 
                                            {
                                                ["y"] = 107167.86821242,
                                                ["x"] = 191224.27600306,
                                            }, -- end of [14]
                                            [16] = 
                                            {
                                                ["y"] = 107160.09570454,
                                                ["x"] = 191218.00129373,
                                            }, -- end of [16]
                                            [20] = 
                                            {
                                                ["y"] = 107148.45843277,
                                                ["x"] = 191201.87923662,
                                            }, -- end of [20]
                                            [24] = 
                                            {
                                                ["y"] = 107136.65247989,
                                                ["x"] = 191163.7973237,
                                            }, -- end of [24]
                                            [28] = 
                                            {
                                                ["y"] = 107128.12320717,
                                                ["x"] = 191109.53065784,
                                            }, -- end of [28]
                                            [32] = 
                                            {
                                                ["y"] = 107107.20881396,
                                                ["x"] = 191069.78018096,
                                            }, -- end of [32]
                                            [40] = 
                                            {
                                                ["y"] = 107074.21352859,
                                                ["x"] = 191039.73258044,
                                            }, -- end of [40]
                                            [48] = 
                                            {
                                                ["y"] = 107036.7086097,
                                                ["x"] = 190953.57738648,
                                            }, -- end of [48]
                                            [56] = 
                                            {
                                                ["y"] = 107080.52358444,
                                                ["x"] = 190876.14102369,
                                            }, -- end of [56]
                                            [64] = 
                                            {
                                                ["y"] = 107102.00334282,
                                                ["x"] = 190785.10059277,
                                            }, -- end of [64]
                                            [80] = 
                                            {
                                                ["y"] = 106955.98794332,
                                                ["x"] = 190594.70606688,
                                            }, -- end of [80]
                                            [96] = 
                                            {
                                                ["y"] = 106585.37199908,
                                                ["x"] = 190352.955117,
                                            }, -- end of [96]
                                            [112] = 
                                            {
                                                ["y"] = 106511.11549907,
                                                ["x"] = 190232.57070029,
                                            }, -- end of [112]
                                            [128] = 
                                            {
                                                ["y"] = 106434.38836244,
                                                ["x"] = 190195.20368024,
                                            }, -- end of [128]
                                            [160] = 
                                            {
                                                ["y"] = 106450.68384957,
                                                ["x"] = 189950.43921162,
                                            }, -- end of [160]
                                            [192] = 
                                            {
                                                ["y"] = 106452.88493928,
                                                ["x"] = 189806.82750216,
                                            }, -- end of [192]
                                            [224] = 
                                            {
                                                ["y"] = 105727.7937322,
                                                ["x"] = 189968.00525018,
                                            }, -- end of [224]
                                            [256] = 
                                            {
                                                ["y"] = 104594.0365802,
                                                ["x"] = 190051.87819999,
                                            }, -- end of [256]
                                            [320] = 
                                            {
                                                ["y"] = 103986.82385811,
                                                ["x"] = 191097.69213869,
                                            }, -- end of [320]
                                            [384] = 
                                            {
                                                ["y"] = 103791.66823852,
                                                ["x"] = 191439.70110613,
                                            }, -- end of [384]
                                            [448] = 
                                            {
                                                ["y"] = 102915.85263791,
                                                ["x"] = 191807.72558979,
                                            }, -- end of [448]
                                            [257] = 
                                            {
                                                ["y"] = 104589.97050618,
                                                ["x"] = 190054.76313871,
                                            }, -- end of [257]
                                            [321] = 
                                            {
                                                ["y"] = 103978.28496573,
                                                ["x"] = 191092.49748089,
                                            }, -- end of [321]
                                            [385] = 
                                            {
                                                ["y"] = 103788.37401294,
                                                ["x"] = 191443.4443908,
                                            }, -- end of [385]
                                            [449] = 
                                            {
                                                ["y"] = 102892.69444218,
                                                ["x"] = 191798.31336027,
                                            }, -- end of [449]
                                            [129] = 
                                            {
                                                ["y"] = 106436.99834178,
                                                ["x"] = 190150.29178565,
                                            }, -- end of [129]
                                            [161] = 
                                            {
                                                ["y"] = 106446.13900773,
                                                ["x"] = 189948.36276818,
                                            }, -- end of [161]
                                            [193] = 
                                            {
                                                ["y"] = 106447.57970267,
                                                ["x"] = 189787.56931942,
                                            }, -- end of [193]
                                            [225] = 
                                            {
                                                ["y"] = 105665.70804145,
                                                ["x"] = 190000.30676732,
                                            }, -- end of [225]
                                            [258] = 
                                            {
                                                ["y"] = 104586.99261084,
                                                ["x"] = 190058.75392476,
                                            }, -- end of [258]
                                            [322] = 
                                            {
                                                ["y"] = 103969.41017932,
                                                ["x"] = 191087.89214512,
                                            }, -- end of [322]
                                            [386] = 
                                            {
                                                ["y"] = 103783.8376172,
                                                ["x"] = 191445.38211225,
                                            }, -- end of [386]
                                            [450] = 
                                            {
                                                ["y"] = 102888.46483695,
                                                ["x"] = 191795.64952704,
                                            }, -- end of [450]
                                            [65] = 
                                            {
                                                ["y"] = 107100.95097016,
                                                ["x"] = 190780.21374385,
                                            }, -- end of [65]
                                            [81] = 
                                            {
                                                ["y"] = 106899.32987214,
                                                ["x"] = 190562.88957706,
                                            }, -- end of [81]
                                            [97] = 
                                            {
                                                ["y"] = 106582.13086951,
                                                ["x"] = 190343.49674963,
                                            }, -- end of [97]
                                            [113] = 
                                            {
                                                ["y"] = 106501.12037784,
                                                ["x"] = 190232.73468993,
                                            }, -- end of [113]
                                            [130] = 
                                            {
                                                ["y"] = 106438.06344974,
                                                ["x"] = 190145.41101099,
                                            }, -- end of [130]
                                            [162] = 
                                            {
                                                ["y"] = 106441.40981548,
                                                ["x"] = 189946.74191726,
                                            }, -- end of [162]
                                            [194] = 
                                            {
                                                ["y"] = 106444.50690023,
                                                ["x"] = 189783.67019043,
                                            }, -- end of [194]
                                            [226] = 
                                            {
                                                ["y"] = 105651.74510675,
                                                ["x"] = 190005.78101157,
                                            }, -- end of [226]
                                            [260] = 
                                            {
                                                ["y"] = 104588.73529735,
                                                ["x"] = 190068.07319641,
                                            }, -- end of [260]
                                            [324] = 
                                            {
                                                ["y"] = 103960.57745125,
                                                ["x"] = 191087.11132661,
                                            }, -- end of [324]
                                            [388] = 
                                            {
                                                ["y"] = 103768.86274841,
                                                ["x"] = 191445.26277769,
                                            }, -- end of [388]
                                            [452] = 
                                            {
                                                ["y"] = 102524.70529937,
                                                ["x"] = 191531.00497759,
                                            }, -- end of [452]
                                            [261] = 
                                            {
                                                ["y"] = 104591.04958383,
                                                ["x"] = 190072.50528786,
                                            }, -- end of [261]
                                            [325] = 
                                            {
                                                ["y"] = 103958.05374894,
                                                ["x"] = 191091.35596938,
                                            }, -- end of [325]
                                            [389] = 
                                            {
                                                ["y"] = 103763.96968691,
                                                ["x"] = 191446.20395058,
                                            }, -- end of [389]
                                            [453] = 
                                            {
                                                ["y"] = 102519.98149285,
                                                ["x"] = 191530.81006981,
                                            }, -- end of [453]
                                            [131] = 
                                            {
                                                ["y"] = 106439.81701819,
                                                ["x"] = 190140.7326351,
                                            }, -- end of [131]
                                            [163] = 
                                            {
                                                ["y"] = 106436.59517054,
                                                ["x"] = 189945.39460495,
                                            }, -- end of [163]
                                            [195] = 
                                            {
                                                ["y"] = 106440.50397634,
                                                ["x"] = 189780.67871005,
                                            }, -- end of [195]
                                            [227] = 
                                            {
                                                ["y"] = 105623.2323778,
                                                ["x"] = 190015.10082684,
                                            }, -- end of [227]
                                            [262] = 
                                            {
                                                ["y"] = 104592.96847427,
                                                ["x"] = 190077.1183846,
                                            }, -- end of [262]
                                            [326] = 
                                            {
                                                ["y"] = 103958.95388039,
                                                ["x"] = 191096.13570279,
                                            }, -- end of [326]
                                            [390] = 
                                            {
                                                ["y"] = 103759.66801777,
                                                ["x"] = 191448.70205958,
                                            }, -- end of [390]
                                            [454] = 
                                            {
                                                ["y"] = 102516.35962798,
                                                ["x"] = 191534.23085738,
                                            }, -- end of [454]
                                            [33] = 
                                            {
                                                ["y"] = 107104.08427606,
                                                ["x"] = 191065.8835738,
                                            }, -- end of [33]
                                            [41] = 
                                            {
                                                ["y"] = 107071.58957307,
                                                ["x"] = 191035.47475134,
                                            }, -- end of [41]
                                            [49] = 
                                            {
                                                ["y"] = 107037.26441526,
                                                ["x"] = 190948.61069632,
                                            }, -- end of [49]
                                            [57] = 
                                            {
                                                ["y"] = 107085.39955713,
                                                ["x"] = 190867.41524585,
                                            }, -- end of [57]
                                            [66] = 
                                            {
                                                ["y"] = 107098.2707506,
                                                ["x"] = 190770.58094865,
                                            }, -- end of [66]
                                            [82] = 
                                            {
                                                ["y"] = 106881.0533834,
                                                ["x"] = 190554.77456279,
                                            }, -- end of [82]
                                            [98] = 
                                            {
                                                ["y"] = 106578.06809126,
                                                ["x"] = 190329.05896501,
                                            }, -- end of [98]
                                            [114] = 
                                            {
                                                ["y"] = 106491.17645009,
                                                ["x"] = 190233.77824954,
                                            }, -- end of [114]
                                            [132] = 
                                            {
                                                ["y"] = 106442.12890757,
                                                ["x"] = 190136.30134481,
                                            }, -- end of [132]
                                            [164] = 
                                            {
                                                ["y"] = 106431.71334922,
                                                ["x"] = 189944.32135578,
                                            }, -- end of [164]
                                            [196] = 
                                            {
                                                ["y"] = 106382.36184074,
                                                ["x"] = 189741.72005883,
                                            }, -- end of [196]
                                            [228] = 
                                            {
                                                ["y"] = 105536.6602843,
                                                ["x"] = 190039.67914118,
                                            }, -- end of [228]
                                            [264] = 
                                            {
                                                ["y"] = 104599.77498599,
                                                ["x"] = 190101.16299453,
                                            }, -- end of [264]
                                            [328] = 
                                            {
                                                ["y"] = 103966.57433112,
                                                ["x"] = 191102.55902221,
                                            }, -- end of [328]
                                            [392] = 
                                            {
                                                ["y"] = 103752.67801835,
                                                ["x"] = 191455.81864396,
                                            }, -- end of [392]
                                            [456] = 
                                            {
                                                ["y"] = 102489.08722246,
                                                ["x"] = 191569.9229757,
                                            }, -- end of [456]
                                            [265] = 
                                            {
                                                ["y"] = 104600.58002751,
                                                ["x"] = 190106.09668425,
                                            }, -- end of [265]
                                            [329] = 
                                            {
                                                ["y"] = 103969.6879596,
                                                ["x"] = 191106.4588757,
                                            }, -- end of [329]
                                            [393] = 
                                            {
                                                ["y"] = 103749.78872871,
                                                ["x"] = 191459.89774091,
                                            }, -- end of [393]
                                            [457] = 
                                            {
                                                ["y"] = 102490.131357,
                                                ["x"] = 191574.67177331,
                                            }, -- end of [457]
                                            [133] = 
                                            {
                                                ["y"] = 106444.84476071,
                                                ["x"] = 190132.10301476,
                                            }, -- end of [133]
                                            [165] = 
                                            {
                                                ["y"] = 106421.93424823,
                                                ["x"] = 189942.27741774,
                                            }, -- end of [165]
                                            [197] = 
                                            {
                                                ["y"] = 106377.82350063,
                                                ["x"] = 189739.63505048,
                                            }, -- end of [197]
                                            [229] = 
                                            {
                                                ["y"] = 105507.44639466,
                                                ["x"] = 190046.48902845,
                                            }, -- end of [229]
                                            [266] = 
                                            {
                                                ["y"] = 104601.06504021,
                                                ["x"] = 190111.07243256,
                                            }, -- end of [266]
                                            [330] = 
                                            {
                                                ["y"] = 103972.20290726,
                                                ["x"] = 191110.7796717,
                                            }, -- end of [330]
                                            [394] = 
                                            {
                                                ["y"] = 103744.62953039,
                                                ["x"] = 191468.46197926,
                                            }, -- end of [394]
                                            [458] = 
                                            {
                                                ["y"] = 102490.67400894,
                                                ["x"] = 191575.67164749,
                                            }, -- end of [458]
                                            [67] = 
                                            {
                                                ["y"] = 107095.06241608,
                                                ["x"] = 190761.11103123,
                                            }, -- end of [67]
                                            [83] = 
                                            {
                                                ["y"] = 106752.20654638,
                                                ["x"] = 190500.09010391,
                                            }, -- end of [83]
                                            [99] = 
                                            {
                                                ["y"] = 106563.09529773,
                                                ["x"] = 190270.96987637,
                                            }, -- end of [99]
                                            [115] = 
                                            {
                                                ["y"] = 106476.28698955,
                                                ["x"] = 190235.57824088,
                                            }, -- end of [115]
                                            [134] = 
                                            {
                                                ["y"] = 106447.99319923,
                                                ["x"] = 190128.22469815,
                                            }, -- end of [134]
                                            [166] = 
                                            {
                                                ["y"] = 106417.24958115,
                                                ["x"] = 189940.53490058,
                                            }, -- end of [166]
                                            [198] = 
                                            {
                                                ["y"] = 106363.67162176,
                                                ["x"] = 189734.65375642,
                                            }, -- end of [198]
                                            [230] = 
                                            {
                                                ["y"] = 105492.67908378,
                                                ["x"] = 190049.11057844,
                                            }, -- end of [230]
                                            [268] = 
                                            {
                                                ["y"] = 104600.44056285,
                                                ["x"] = 190151.05243338,
                                            }, -- end of [268]
                                            [332] = 
                                            {
                                                ["y"] = 103981.30600504,
                                                ["x"] = 191128.55509704,
                                            }, -- end of [332]
                                            [396] = 
                                            {
                                                ["y"] = 103713.38981327,
                                                ["x"] = 191525.39028262,
                                            }, -- end of [396]
                                            [269] = 
                                            {
                                                ["y"] = 104599.68978179,
                                                ["x"] = 190155.9894568,
                                            }, -- end of [269]
                                            [333] = 
                                            {
                                                ["y"] = 103982.48149865,
                                                ["x"] = 191133.4069852,
                                            }, -- end of [333]
                                            [397] = 
                                            {
                                                ["y"] = 103701.27763449,
                                                ["x"] = 191541.29240655,
                                            }, -- end of [397]
                                            [135] = 
                                            {
                                                ["y"] = 106451.53885492,
                                                ["x"] = 190124.7037387,
                                            }, -- end of [135]
                                            [167] = 
                                            {
                                                ["y"] = 106412.72274894,
                                                ["x"] = 189938.41449945,
                                            }, -- end of [167]
                                            [199] = 
                                            {
                                                ["y"] = 106354.03890395,
                                                ["x"] = 189731.98708744,
                                            }, -- end of [199]
                                            [231] = 
                                            {
                                                ["y"] = 105482.74331811,
                                                ["x"] = 190050.21541374,
                                            }, -- end of [231]
                                            [17] = 
                                            {
                                                ["y"] = 107156.63112096,
                                                ["x"] = 191214.39892828,
                                            }, -- end of [17]
                                            [21] = 
                                            {
                                                ["y"] = 107144.46034822,
                                                ["x"] = 191192.71598733,
                                            }, -- end of [21]
                                            [25] = 
                                            {
                                                ["y"] = 107134.46410717,
                                                ["x"] = 191148.9601972,
                                            }, -- end of [25]
                                            [29] = 
                                            {
                                                ["y"] = 107126.41465114,
                                                ["x"] = 191104.83316551,
                                            }, -- end of [29]
                                            [34] = 
                                            {
                                                ["y"] = 107100.51180592,
                                                ["x"] = 191062.38752072,
                                            }, -- end of [34]
                                            [42] = 
                                            {
                                                ["y"] = 107047.82860656,
                                                ["x"] = 190991.48290522,
                                            }, -- end of [42]
                                            [50] = 
                                            {
                                                ["y"] = 107038.31541499,
                                                ["x"] = 190943.7241847,
                                            }, -- end of [50]
                                            [58] = 
                                            {
                                                ["y"] = 107087.40714198,
                                                ["x"] = 190862.83822901,
                                            }, -- end of [58]
                                            [68] = 
                                            {
                                                ["y"] = 107061.13137159,
                                                ["x"] = 190672.38390071,
                                            }, -- end of [68]
                                            [84] = 
                                            {
                                                ["y"] = 106698.4878521,
                                                ["x"] = 190473.36863613,
                                            }, -- end of [84]
                                            [100] = 
                                            {
                                                ["y"] = 106559.70295807,
                                                ["x"] = 190261.56538986,
                                            }, -- end of [100]
                                            [116] = 
                                            {
                                                ["y"] = 106471.29193618,
                                                ["x"] = 190235.74899848,
                                            }, -- end of [116]
                                            [136] = 
                                            {
                                                ["y"] = 106459.13816165,
                                                ["x"] = 190118.20237153,
                                            }, -- end of [136]
                                            [168] = 
                                            {
                                                ["y"] = 106408.37707547,
                                                ["x"] = 189935.94457023,
                                            }, -- end of [168]
                                            [200] = 
                                            {
                                                ["y"] = 106344.22279591,
                                                ["x"] = 189730.08885039,
                                            }, -- end of [200]
                                            [232] = 
                                            {
                                                ["y"] = 105472.75029228,
                                                ["x"] = 190050.50474712,
                                            }, -- end of [232]
                                            [272] = 
                                            {
                                                ["y"] = 104576.72313237,
                                                ["x"] = 190232.58851422,
                                            }, -- end of [272]
                                            [336] = 
                                            {
                                                ["y"] = 103982.18706152,
                                                ["x"] = 191148.34859383,
                                            }, -- end of [336]
                                            [400] = 
                                            {
                                                ["y"] = 103608.54898625,
                                                ["x"] = 191695.45838111,
                                            }, -- end of [400]
                                            [273] = 
                                            {
                                                ["y"] = 104574.67643594,
                                                ["x"] = 190237.14980132,
                                            }, -- end of [273]
                                            [337] = 
                                            {
                                                ["y"] = 103981.25758233,
                                                ["x"] = 191153.26009212,
                                            }, -- end of [337]
                                            [401] = 
                                            {
                                                ["y"] = 103544.58379834,
                                                ["x"] = 191784.93654616,
                                            }, -- end of [401]
                                            [137] = 
                                            {
                                                ["y"] = 106466.63560283,
                                                ["x"] = 190111.59070408,
                                            }, -- end of [137]
                                            [169] = 
                                            {
                                                ["y"] = 106404.38268126,
                                                ["x"] = 189932.94600035,
                                            }, -- end of [169]
                                            [201] = 
                                            {
                                                ["y"] = 106334.31042868,
                                                ["x"] = 189728.77594705,
                                            }, -- end of [201]
                                            [233] = 
                                            {
                                                ["y"] = 105462.7638436,
                                                ["x"] = 190050.01175814,
                                            }, -- end of [233]
                                            [274] = 
                                            {
                                                ["y"] = 104569.97403821,
                                                ["x"] = 190245.97408934,
                                            }, -- end of [274]
                                            [338] = 
                                            {
                                                ["y"] = 103979.9519598,
                                                ["x"] = 191158.08542627,
                                            }, -- end of [338]
                                            [402] = 
                                            {
                                                ["y"] = 103542.17506122,
                                                ["x"] = 191789.31597154,
                                            }, -- end of [402]
                                            [69] = 
                                            {
                                                ["y"] = 107056.94717361,
                                                ["x"] = 190663.30309733,
                                            }, -- end of [69]
                                            [85] = 
                                            {
                                                ["y"] = 106672.56808619,
                                                ["x"] = 190458.26745779,
                                            }, -- end of [85]
                                            [101] = 
                                            {
                                                ["y"] = 106557.62060568,
                                                ["x"] = 190257.02008877,
                                            }, -- end of [101]
                                            [117] = 
                                            {
                                                ["y"] = 106466.29363159,
                                                ["x"] = 190235.61031636,
                                            }, -- end of [117]
                                            [138] = 
                                            {
                                                ["y"] = 106477.09809571,
                                                ["x"] = 190100.84490695,
                                            }, -- end of [138]
                                            [170] = 
                                            {
                                                ["y"] = 106400.88621884,
                                                ["x"] = 189929.3776364,
                                            }, -- end of [170]
                                            [202] = 
                                            {
                                                ["y"] = 106319.35682891,
                                                ["x"] = 189727.62448714,
                                            }, -- end of [202]
                                            [234] = 
                                            {
                                                ["y"] = 105447.85652519,
                                                ["x"] = 190048.4333728,
                                            }, -- end of [234]
                                            [276] = 
                                            {
                                                ["y"] = 104554.09096489,
                                                ["x"] = 190271.40386324,
                                            }, -- end of [276]
                                            [340] = 
                                            {
                                                ["y"] = 103976.21114469,
                                                ["x"] = 191167.34768794,
                                            }, -- end of [340]
                                            [404] = 
                                            {
                                                ["y"] = 103532.61791373,
                                                ["x"] = 191812.40722436,
                                            }, -- end of [404]
                                            [277] = 
                                            {
                                                ["y"] = 104548.12716448,
                                                ["x"] = 190279.43053592,
                                            }, -- end of [277]
                                            [341] = 
                                            {
                                                ["y"] = 103973.78231157,
                                                ["x"] = 191171.71653958,
                                            }, -- end of [341]
                                            [405] = 
                                            {
                                                ["y"] = 103531.07265301,
                                                ["x"] = 191817.16092424,
                                            }, -- end of [405]
                                            [139] = 
                                            {
                                                ["y"] = 106480.15835979,
                                                ["x"] = 190096.89273141,
                                            }, -- end of [139]
                                            [171] = 
                                            {
                                                ["y"] = 106397.76705481,
                                                ["x"] = 189925.47091187,
                                            }, -- end of [171]
                                            [203] = 
                                            {
                                                ["y"] = 106309.36179936,
                                                ["x"] = 189727.39515532,
                                            }, -- end of [203]
                                            [235] = 
                                            {
                                                ["y"] = 105442.99026377,
                                                ["x"] = 190047.29367689,
                                            }, -- end of [235]
                                            [278] = 
                                            {
                                                ["y"] = 104538.49247322,
                                                ["x"] = 190290.92267617,
                                            }, -- end of [278]
                                            [342] = 
                                            {
                                                ["y"] = 103970.98866709,
                                                ["x"] = 191175.86121769,
                                            }, -- end of [342]
                                            [406] = 
                                            {
                                                ["y"] = 103530.03647804,
                                                ["x"] = 191822.04978687,
                                            }, -- end of [406]
                                            [35] = 
                                            {
                                                ["y"] = 107096.62623282,
                                                ["x"] = 191059.24379797,
                                            }, -- end of [35]
                                            [43] = 
                                            {
                                                ["y"] = 107043.41817947,
                                                ["x"] = 190982.50941682,
                                            }, -- end of [43]
                                            [51] = 
                                            {
                                                ["y"] = 107039.81365228,
                                                ["x"] = 190938.95568663,
                                            }, -- end of [51]
                                            [59] = 
                                            {
                                                ["y"] = 107089.07844365,
                                                ["x"] = 190858.12633087,
                                            }, -- end of [59]
                                            [70] = 
                                            {
                                                ["y"] = 107052.18484356,
                                                ["x"] = 190654.51238908,
                                            }, -- end of [70]
                                            [86] = 
                                            {
                                                ["y"] = 106655.67575213,
                                                ["x"] = 190447.56458307,
                                            }, -- end of [86]
                                            [102] = 
                                            {
                                                ["y"] = 106555.061095,
                                                ["x"] = 190252.73072748,
                                            }, -- end of [102]
                                            [118] = 
                                            {
                                                ["y"] = 106461.319754,
                                                ["x"] = 190235.12297611,
                                            }, -- end of [118]
                                            [140] = 
                                            {
                                                ["y"] = 106482.6642625,
                                                ["x"] = 190092.5730299,
                                            }, -- end of [140]
                                            [172] = 
                                            {
                                                ["y"] = 106392.14060061,
                                                ["x"] = 189917.20712632,
                                            }, -- end of [172]
                                            [204] = 
                                            {
                                                ["y"] = 106304.36465258,
                                                ["x"] = 189727.57469481,
                                            }, -- end of [204]
                                            [236] = 
                                            {
                                                ["y"] = 105438.22363273,
                                                ["x"] = 190045.78759376,
                                            }, -- end of [236]
                                            [280] = 
                                            {
                                                ["y"] = 104467.28532731,
                                                ["x"] = 190368.06946531,
                                            }, -- end of [280]
                                            [344] = 
                                            {
                                                ["y"] = 103964.42058028,
                                                ["x"] = 191183.38886234,
                                            }, -- end of [344]
                                            [408] = 
                                            {
                                                ["y"] = 103529.07356747,
                                                ["x"] = 191836.98465321,
                                            }, -- end of [408]
                                            [281] = 
                                            {
                                                ["y"] = 104454.21706676,
                                                ["x"] = 190383.20738813,
                                            }, -- end of [281]
                                            [345] = 
                                            {
                                                ["y"] = 103960.77516217,
                                                ["x"] = 191186.80982087,
                                            }, -- end of [345]
                                            [409] = 
                                            {
                                                ["y"] = 103527.50387354,
                                                ["x"] = 191841.74832096,
                                            }, -- end of [409]
                                            [141] = 
                                            {
                                                ["y"] = 106484.60769408,
                                                ["x"] = 190087.96884857,
                                            }, -- end of [141]
                                            [173] = 
                                            {
                                                ["y"] = 106389.67181282,
                                                ["x"] = 189912.8603785,
                                            }, -- end of [173]
                                            [205] = 
                                            {
                                                ["y"] = 106289.42999221,
                                                ["x"] = 189728.89935615,
                                            }, -- end of [205]
                                            [237] = 
                                            {
                                                ["y"] = 105433.5540023,
                                                ["x"] = 190044.00133735,
                                            }, -- end of [237]
                                            [282] = 
                                            {
                                                ["y"] = 104253.75057596,
                                                ["x"] = 190632.57645854,
                                            }, -- end of [282]
                                            [346] = 
                                            {
                                                ["y"] = 103956.95599989,
                                                ["x"] = 191190.0364264,
                                            }, -- end of [346]
                                            [410] = 
                                            {
                                                ["y"] = 103524.79839398,
                                                ["x"] = 191845.89080793,
                                            }, -- end of [410]
                                            [455] = 
                                            {
                                                ["y"] = 102491.49977903,
                                                ["x"] = 191565.56313072,
                                            }, -- end of [455]
                                            [443] = 
                                            {
                                                ["y"] = 102945.37800939,
                                                ["x"] = 191811.05221947,
                                            }, -- end of [443]
                                            [379] = 
                                            {
                                                ["y"] = 103809.22717213,
                                                ["x"] = 191411.73447241,
                                            }, -- end of [379]
                                            [71] = 
                                            {
                                                ["y"] = 107049.49783095,
                                                ["x"] = 190650.29718565,
                                            }, -- end of [71]
                                            [87] = 
                                            {
                                                ["y"] = 106643.53710025,
                                                ["x"] = 190438.75648541,
                                            }, -- end of [87]
                                            [103] = 
                                            {
                                                ["y"] = 106551.8947347,
                                                ["x"] = 190248.86802916,
                                            }, -- end of [103]
                                            [119] = 
                                            {
                                                ["y"] = 106456.44394537,
                                                ["x"] = 190234.02907994,
                                            }, -- end of [119]
                                            [142] = 
                                            {
                                                ["y"] = 106486.11247673,
                                                ["x"] = 190083.20184824,
                                            }, -- end of [142]
                                            [174] = 
                                            {
                                                ["y"] = 106387.6150014,
                                                ["x"] = 189908.30472302,
                                            }, -- end of [174]
                                            [206] = 
                                            {
                                                ["y"] = 106284.53075877,
                                                ["x"] = 189729.89012067,
                                            }, -- end of [206]
                                            [238] = 
                                            {
                                                ["y"] = 105424.50041235,
                                                ["x"] = 190039.76306389,
                                            }, -- end of [238]
                                            [284] = 
                                            {
                                                ["y"] = 104213.15979593,
                                                ["x"] = 190689.58547134,
                                            }, -- end of [284]
                                            [348] = 
                                            {
                                                ["y"] = 103927.94875613,
                                                ["x"] = 191209.59012656,
                                            }, -- end of [348]
                                            [412] = 
                                            {
                                                ["y"] = 103516.13285266,
                                                ["x"] = 191850.63151057,
                                            }, -- end of [412]
                                            [315] = 
                                            {
                                                ["y"] = 104010.94258899,
                                                ["x"] = 191101.51297198,
                                            }, -- end of [315]
                                            [445] = 
                                            {
                                                ["y"] = 102930.3931609,
                                                ["x"] = 191811.18877446,
                                            }, -- end of [445]
                                            [451] = 
                                            {
                                                ["y"] = 102780.47374232,
                                                ["x"] = 191723.29203047,
                                            }, -- end of [451]
                                            [263] = 
                                            {
                                                ["y"] = 104595.94795974,
                                                ["x"] = 190086.66353648,
                                            }, -- end of [263]
                                            [15] = 
                                            {
                                                ["y"] = 107163.85323617,
                                                ["x"] = 191221.29842967,
                                            }, -- end of [15]
                                            [285] = 
                                            {
                                                ["y"] = 104210.81686566,
                                                ["x"] = 190694.00065507,
                                            }, -- end of [285]
                                            [349] = 
                                            {
                                                ["y"] = 103914.91540563,
                                                ["x"] = 191217.00774959,
                                            }, -- end of [349]
                                            [413] = 
                                            {
                                                ["y"] = 103511.24821019,
                                                ["x"] = 191851.68443883,
                                            }, -- end of [413]
                                            [72] = 
                                            {
                                                ["y"] = 107046.55736834,
                                                ["x"] = 190646.2542524,
                                            }, -- end of [72]
                                            [143] = 
                                            {
                                                ["y"] = 106487.26026256,
                                                ["x"] = 190078.33630239,
                                            }, -- end of [143]
                                            [175] = 
                                            {
                                                ["y"] = 106386.23410492,
                                                ["x"] = 189903.50698911,
                                            }, -- end of [175]
                                            [207] = 
                                            {
                                                ["y"] = 106279.70552138,
                                                ["x"] = 189731.19723531,
                                            }, -- end of [207]
                                            [239] = 
                                            {
                                                ["y"] = 105415.81719918,
                                                ["x"] = 190034.80654308,
                                            }, -- end of [239]
                                            [18] = 
                                            {
                                                ["y"] = 107153.5176491,
                                                ["x"] = 191210.48886184,
                                            }, -- end of [18]
                                            [22] = 
                                            {
                                                ["y"] = 107141.2252445,
                                                ["x"] = 191183.25744965,
                                            }, -- end of [22]
                                            [26] = 
                                            {
                                                ["y"] = 107130.56857791,
                                                ["x"] = 191119.22081918,
                                            }, -- end of [26]
                                            [30] = 
                                            {
                                                ["y"] = 107124.35488251,
                                                ["x"] = 191100.27933088,
                                            }, -- end of [30]
                                            [36] = 
                                            {
                                                ["y"] = 107092.53231105,
                                                ["x"] = 191056.37332268,
                                            }, -- end of [36]
                                            [44] = 
                                            {
                                                ["y"] = 107039.72082696,
                                                ["x"] = 190973.22264433,
                                            }, -- end of [44]
                                            [52] = 
                                            {
                                                ["y"] = 107041.72620026,
                                                ["x"] = 190934.337944,
                                            }, -- end of [52]
                                            [60] = 
                                            {
                                                ["y"] = 107094.44858234,
                                                ["x"] = 190838.86222794,
                                            }, -- end of [60]
                                            [287] = 
                                            {
                                                ["y"] = 104192.38685566,
                                                ["x"] = 190734.97316244,
                                            }, -- end of [287]
                                            [88] = 
                                            {
                                                ["y"] = 106635.84298052,
                                                ["x"] = 190432.37206344,
                                            }, -- end of [88]
                                            [104] = 
                                            {
                                                ["y"] = 106548.18678445,
                                                ["x"] = 190245.52022311,
                                            }, -- end of [104]
                                            [120] = 
                                            {
                                                ["y"] = 106451.71488316,
                                                ["x"] = 190232.40949502,
                                            }, -- end of [120]
                                            [144] = 
                                            {
                                                ["y"] = 106488.09858808,
                                                ["x"] = 190073.40792017,
                                            }, -- end of [144]
                                            [176] = 
                                            {
                                                ["y"] = 106385.96683469,
                                                ["x"] = 189898.53001826,
                                            }, -- end of [176]
                                            [208] = 
                                            {
                                                ["y"] = 106270.24112382,
                                                ["x"] = 189734.41989244,
                                            }, -- end of [208]
                                            [240] = 
                                            {
                                                ["y"] = 105262.89273073,
                                                ["x"] = 189939.90735278,
                                            }, -- end of [240]
                                            [288] = 
                                            {
                                                ["y"] = 104182.56057567,
                                                ["x"] = 190768.56394205,
                                            }, -- end of [288]
                                            [352] = 
                                            {
                                                ["y"] = 103878.78392162,
                                                ["x"] = 191234.05534522,
                                            }, -- end of [352]
                                            [416] = 
                                            {
                                                ["y"] = 103422.35187628,
                                                ["x"] = 191865.33157821,
                                            }, -- end of [416]
                                            [319] = 
                                            {
                                                ["y"] = 103991.26626446,
                                                ["x"] = 191099.95314718,
                                            }, -- end of [319]
                                            [343] = 
                                            {
                                                ["y"] = 103967.84747321,
                                                ["x"] = 191179.74875528,
                                            }, -- end of [343]
                                            [351] = 
                                            {
                                                ["y"] = 103883.5017244,
                                                ["x"] = 191232.40193699,
                                            }, -- end of [351]
                                            [347] = 
                                            {
                                                ["y"] = 103948.92490591,
                                                ["x"] = 191195.99096352,
                                            }, -- end of [347]
                                            [323] = 
                                            {
                                                ["y"] = 103965.0815623,
                                                ["x"] = 191085.42050446,
                                            }, -- end of [323]
                                            [289] = 
                                            {
                                                ["y"] = 104178.53762533,
                                                ["x"] = 190788.15393634,
                                            }, -- end of [289]
                                            [353] = 
                                            {
                                                ["y"] = 103869.16751434,
                                                ["x"] = 191236.7926929,
                                            }, -- end of [353]
                                            [417] = 
                                            {
                                                ["y"] = 103324.18913037,
                                                ["x"] = 191884.34295133,
                                            }, -- end of [417]
                                            [254] = 
                                            {
                                                ["y"] = 104961.51242234,
                                                ["x"] = 189907.31581757,
                                            }, -- end of [254]
                                            [145] = 
                                            {
                                                ["y"] = 106489.05284705,
                                                ["x"] = 190063.4562033,
                                            }, -- end of [145]
                                            [177] = 
                                            {
                                                ["y"] = 106387.09647667,
                                                ["x"] = 189893.67536719,
                                            }, -- end of [177]
                                            [209] = 
                                            {
                                                ["y"] = 106261.01229813,
                                                ["x"] = 189738.26802995,
                                            }, -- end of [209]
                                            [241] = 
                                            {
                                                ["y"] = 105245.06748549,
                                                ["x"] = 189930.84334877,
                                            }, -- end of [241]
                                            [290] = 
                                            {
                                                ["y"] = 104175.29123224,
                                                ["x"] = 190807.88461573,
                                            }, -- end of [290]
                                            [354] = 
                                            {
                                                ["y"] = 103849.6320293,
                                                ["x"] = 191241.07084826,
                                            }, -- end of [354]
                                            [418] = 
                                            {
                                                ["y"] = 103304.32713993,
                                                ["x"] = 191886.6619933,
                                            }, -- end of [418]
                                            [391] = 
                                            {
                                                ["y"] = 103755.95589136,
                                                ["x"] = 191452.04700646,
                                            }, -- end of [391]
                                            [398] = 
                                            {
                                                ["y"] = 103670.77407959,
                                                ["x"] = 191592.95752448,
                                            }, -- end of [398]
                                            [415] = 
                                            {
                                                ["y"] = 103466.56942111,
                                                ["x"] = 191857.00083426,
                                            }, -- end of [415]
                                            [271] = 
                                            {
                                                ["y"] = 104580.1667235,
                                                ["x"] = 190223.20281237,
                                            }, -- end of [271]
                                            [105] = 
                                            {
                                                ["y"] = 106544.12406568,
                                                ["x"] = 190242.60910375,
                                            }, -- end of [105]
                                            [73] = 
                                            {
                                                ["y"] = 107043.33297355,
                                                ["x"] = 190642.43440574,
                                            }, -- end of [73]
                                            [89] = 
                                            {
                                                ["y"] = 106628.58456786,
                                                ["x"] = 190425.49608472,
                                            }, -- end of [89]
                                            [419] = 
                                            {
                                                ["y"] = 103289.3501956,
                                                ["x"] = 191887.44503696,
                                            }, -- end of [419]
                                            [121] = 
                                            {
                                                ["y"] = 106447.18388094,
                                                ["x"] = 190230.3033419,
                                            }, -- end of [121]
                                            [146] = 
                                            {
                                                ["y"] = 106489.27797168,
                                                ["x"] = 190053.46030499,
                                            }, -- end of [146]
                                            [178] = 
                                            {
                                                ["y"] = 106389.10681174,
                                                ["x"] = 189889.09942201,
                                            }, -- end of [178]
                                            [210] = 
                                            {
                                                ["y"] = 106247.49067979,
                                                ["x"] = 189744.75339244,
                                            }, -- end of [210]
                                            [242] = 
                                            {
                                                ["y"] = 105222.41127626,
                                                ["x"] = 189920.28206905,
                                            }, -- end of [242]
                                            [292] = 
                                            {
                                                ["y"] = 104173.41230522,
                                                ["x"] = 190837.81391619,
                                            }, -- end of [292]
                                            [356] = 
                                            {
                                                ["y"] = 103834.79657259,
                                                ["x"] = 191243.14285637,
                                            }, -- end of [356]
                                            [420] = 
                                            {
                                                ["y"] = 103279.35149266,
                                                ["x"] = 191887.37343313,
                                            }, -- end of [420]
                                            [414] = 
                                            {
                                                ["y"] = 103506.29150465,
                                                ["x"] = 191852.33009119,
                                            }, -- end of [414]
                                            [411] = 
                                            {
                                                ["y"] = 103520.8118245,
                                                ["x"] = 191848.82644706,
                                            }, -- end of [411]
                                            [407] = 
                                            {
                                                ["y"] = 103529.63806187,
                                                ["x"] = 191827.02923953,
                                            }, -- end of [407]
                                            [403] = 
                                            {
                                                ["y"] = 103538.10488633,
                                                ["x"] = 191798.44822889,
                                            }, -- end of [403]
                                            [399] = 
                                            {
                                                ["y"] = 103630.75372714,
                                                ["x"] = 191662.19720923,
                                            }, -- end of [399]
                                            [293] = 
                                            {
                                                ["y"] = 104173.39820565,
                                                ["x"] = 190852.81234029,
                                            }, -- end of [293]
                                            [357] = 
                                            {
                                                ["y"] = 103829.80570661,
                                                ["x"] = 191242.91678009,
                                            }, -- end of [357]
                                            [421] = 
                                            {
                                                ["y"] = 103269.37202118,
                                                ["x"] = 191886.75717949,
                                            }, -- end of [421]
                                            [387] = 
                                            {
                                                ["y"] = 103778.86150771,
                                                ["x"] = 191445.60737265,
                                            }, -- end of [387]
                                            [147] = 
                                            {
                                                ["y"] = 106488.76135337,
                                                ["x"] = 190033.46754246,
                                            }, -- end of [147]
                                            [179] = 
                                            {
                                                ["y"] = 106396.37684851,
                                                ["x"] = 189875.98141067,
                                            }, -- end of [179]
                                            [211] = 
                                            {
                                                ["y"] = 106238.82040692,
                                                ["x"] = 189749.73374811,
                                            }, -- end of [211]
                                            [243] = 
                                            {
                                                ["y"] = 105189.82683366,
                                                ["x"] = 189907.5049119,
                                            }, -- end of [243]
                                            [294] = 
                                            {
                                                ["y"] = 104174.15526194,
                                                ["x"] = 190867.79151176,
                                            }, -- end of [294]
                                            [358] = 
                                            {
                                                ["y"] = 103824.88690556,
                                                ["x"] = 191242.03902216,
                                            }, -- end of [358]
                                            [422] = 
                                            {
                                                ["y"] = 103259.44414772,
                                                ["x"] = 191885.57046644,
                                            }, -- end of [422]
                                            [423] = 
                                            {
                                                ["y"] = 103249.59273174,
                                                ["x"] = 191883.85851804,
                                            }, -- end of [423]
                                            [37] = 
                                            {
                                                ["y"] = 107084.26014871,
                                                ["x"] = 191050.75710983,
                                            }, -- end of [37]
                                            [45] = 
                                            {
                                                ["y"] = 107038.29614903,
                                                ["x"] = 190968.43086043,
                                            }, -- end of [45]
                                            [53] = 
                                            {
                                                ["y"] = 107043.9982637,
                                                ["x"] = 190929.88511993,
                                            }, -- end of [53]
                                            [61] = 
                                            {
                                                ["y"] = 107103.21151506,
                                                ["x"] = 190804.98323919,
                                            }, -- end of [61]
                                            [74] = 
                                            {
                                                ["y"] = 107039.81053749,
                                                ["x"] = 190638.88821089,
                                            }, -- end of [74]
                                            [90] = 
                                            {
                                                ["y"] = 106621.80905715,
                                                ["x"] = 190418.14401951,
                                            }, -- end of [90]
                                            [106] = 
                                            {
                                                ["y"] = 106539.82993045,
                                                ["x"] = 190240.04879886,
                                            }, -- end of [106]
                                            [122] = 
                                            {
                                                ["y"] = 106442.98269886,
                                                ["x"] = 190227.59907081,
                                            }, -- end of [122]
                                            [148] = 
                                            {
                                                ["y"] = 106488.34659467,
                                                ["x"] = 190028.48654382,
                                            }, -- end of [148]
                                            [180] = 
                                            {
                                                ["y"] = 106399.16633991,
                                                ["x"] = 189871.83282487,
                                            }, -- end of [180]
                                            [212] = 
                                            {
                                                ["y"] = 106212.70318133,
                                                ["x"] = 189764.48642121,
                                            }, -- end of [212]
                                            [244] = 
                                            {
                                                ["y"] = 105180.33232102,
                                                ["x"] = 189904.37742108,
                                            }, -- end of [244]
                                            [296] = 
                                            {
                                                ["y"] = 104180.6613628,
                                                ["x"] = 190977.28762992,
                                            }, -- end of [296]
                                            [360] = 
                                            {
                                                ["y"] = 103815.50409888,
                                                ["x"] = 191238.63223425,
                                            }, -- end of [360]
                                            [424] = 
                                            {
                                                ["y"] = 103234.99519612,
                                                ["x"] = 191880.4194466,
                                            }, -- end of [424]
                                            [383] = 
                                            {
                                                ["y"] = 103796.35978837,
                                                ["x"] = 191425.52829742,
                                            }, -- end of [383]
                                            [382] = 
                                            {
                                                ["y"] = 103797.81782428,
                                                ["x"] = 191420.74655589,
                                            }, -- end of [382]
                                            [381] = 
                                            {
                                                ["y"] = 103801.26529851,
                                                ["x"] = 191417.35161422,
                                            }, -- end of [381]
                                            [447] = 
                                            {
                                                ["y"] = 102920.58849749,
                                                ["x"] = 191809.32818991,
                                            }, -- end of [447]
                                            [267] = 
                                            {
                                                ["y"] = 104601.33054566,
                                                ["x"] = 190121.06643924,
                                            }, -- end of [267]
                                            [297] = 
                                            {
                                                ["y"] = 104178.79347142,
                                                ["x"] = 190981.89787114,
                                            }, -- end of [297]
                                            [361] = 
                                            {
                                                ["y"] = 103806.639595,
                                                ["x"] = 191234.00616613,
                                            }, -- end of [361]
                                            [425] = 
                                            {
                                                ["y"] = 103220.64692914,
                                                ["x"] = 191876.05392525,
                                            }, -- end of [425]
                                            [291] = 
                                            {
                                                ["y"] = 104174.31858388,
                                                ["x"] = 190817.83625248,
                                            }, -- end of [291]
                                            [149] = 
                                            {
                                                ["y"] = 106487.63131013,
                                                ["x"] = 190023.54010612,
                                            }, -- end of [149]
                                            [181] = 
                                            {
                                                ["y"] = 106402.33007124,
                                                ["x"] = 189867.96533292,
                                            }, -- end of [181]
                                            [213] = 
                                            {
                                                ["y"] = 106190.68739662,
                                                ["x"] = 189776.32286916,
                                            }, -- end of [213]
                                            [245] = 
                                            {
                                                ["y"] = 105112.59822478,
                                                ["x"] = 189886.72068357,
                                            }, -- end of [245]
                                            [298] = 
                                            {
                                                ["y"] = 104175.07446555,
                                                ["x"] = 190985.19763159,
                                            }, -- end of [298]
                                            [362] = 
                                            {
                                                ["y"] = 103793.30815734,
                                                ["x"] = 191227.13725251,
                                            }, -- end of [362]
                                            [426] = 
                                            {
                                                ["y"] = 103206.57822611,
                                                ["x"] = 191870.85669905,
                                            }, -- end of [426]
                                            [439] = 
                                            {
                                                ["y"] = 102969.89491953,
                                                ["x"] = 191806.51706554,
                                            }, -- end of [439]
                                            [375] = 
                                            {
                                                ["y"] = 103816.50690556,
                                                ["x"] = 191353.15132379,
                                            }, -- end of [375]
                                            [311] = 
                                            {
                                                ["y"] = 104056.94603214,
                                                ["x"] = 191082.8313097,
                                            }, -- end of [311]
                                            [295] = 
                                            {
                                                ["y"] = 104181.83770352,
                                                ["x"] = 190952.41962176,
                                            }, -- end of [295]
                                            [427] = 
                                            {
                                                ["y"] = 103192.81517127,
                                                ["x"] = 191864.89637534,
                                            }, -- end of [427]
                                            [75] = 
                                            {
                                                ["y"] = 107036.00735872,
                                                ["x"] = 190635.64653746,
                                            }, -- end of [75]
                                            [91] = 
                                            {
                                                ["y"] = 106615.56809341,
                                                ["x"] = 190410.33335425,
                                            }, -- end of [91]
                                            [107] = 
                                            {
                                                ["y"] = 106535.35962588,
                                                ["x"] = 190237.81149562,
                                            }, -- end of [107]
                                            [123] = 
                                            {
                                                ["y"] = 106439.42049672,
                                                ["x"] = 190224.11201507,
                                            }, -- end of [123]
                                            [150] = 
                                            {
                                                ["y"] = 106481.48418719,
                                                ["x"] = 189994.17716184,
                                            }, -- end of [150]
                                            [182] = 
                                            {
                                                ["y"] = 106405.86010449,
                                                ["x"] = 189864.42612006,
                                            }, -- end of [182]
                                            [214] = 
                                            {
                                                ["y"] = 106118.71204267,
                                                ["x"] = 189821.53112118,
                                            }, -- end of [214]
                                            [246] = 
                                            {
                                                ["y"] = 105107.68684074,
                                                ["x"] = 189885.79237922,
                                            }, -- end of [246]
                                            [300] = 
                                            {
                                                ["y"] = 104165.5566135,
                                                ["x"] = 190987.83623002,
                                            }, -- end of [300]
                                            [364] = 
                                            {
                                                ["y"] = 103779.28230504,
                                                ["x"] = 191221.87423825,
                                            }, -- end of [364]
                                            [428] = 
                                            {
                                                ["y"] = 103174.90970352,
                                                ["x"] = 191855.99128206,
                                            }, -- end of [428]
                                            [299] = 
                                            {
                                                ["y"] = 104170.50265261,
                                                ["x"] = 190987.16511002,
                                            }, -- end of [299]
                                            [355] = 
                                            {
                                                ["y"] = 103839.78166041,
                                                ["x"] = 191242.77883502,
                                            }, -- end of [355]
                                            [430] = 
                                            {
                                                ["y"] = 103011.71190555,
                                                ["x"] = 191780.454674,
                                            }, -- end of [430]
                                            [76] = 
                                            {
                                                ["y"] = 107031.97355963,
                                                ["x"] = 190632.69235507,
                                            }, -- end of [76]
                                            [92] = 
                                            {
                                                ["y"] = 106609.8908739,
                                                ["x"] = 190402.1035474,
                                            }, -- end of [92]
                                            [301] = 
                                            {
                                                ["y"] = 104155.6495915,
                                                ["x"] = 190988.8415495,
                                            }, -- end of [301]
                                            [365] = 
                                            {
                                                ["y"] = 103774.38892161,
                                                ["x"] = 191220.88271027,
                                            }, -- end of [365]
                                            [429] = 
                                            {
                                                ["y"] = 103112.65811839,
                                                ["x"] = 191824.00885758,
                                            }, -- end of [429]
                                            [431] = 
                                            {
                                                ["y"] = 103006.93640578,
                                                ["x"] = 191781.6780699,
                                            }, -- end of [431]
                                            [151] = 
                                            {
                                                ["y"] = 106480.18329639,
                                                ["x"] = 189989.34968059,
                                            }, -- end of [151]
                                            [183] = 
                                            {
                                                ["y"] = 106409.64725852,
                                                ["x"] = 189861.16328655,
                                            }, -- end of [183]
                                            [215] = 
                                            {
                                                ["y"] = 106073.66367333,
                                                ["x"] = 189853.05894288,
                                            }, -- end of [215]
                                            [247] = 
                                            {
                                                ["y"] = 105102.72313401,
                                                ["x"] = 189885.19476756,
                                            }, -- end of [247]
                                            [19] = 
                                            {
                                                ["y"] = 107150.78884366,
                                                ["x"] = 191206.30138708,
                                            }, -- end of [19]
                                            [23] = 
                                            {
                                                ["y"] = 107138.67019203,
                                                ["x"] = 191173.59050861,
                                            }, -- end of [23]
                                            [27] = 
                                            {
                                                ["y"] = 107129.48924238,
                                                ["x"] = 191114.33974178,
                                            }, -- end of [27]
                                            [31] = 
                                            {
                                                ["y"] = 107119.56437288,
                                                ["x"] = 191091.50257844,
                                            }, -- end of [31]
                                            [38] = 
                                            {
                                                ["y"] = 107080.46400651,
                                                ["x"] = 191047.50590253,
                                            }, -- end of [38]
                                            [46] = 
                                            {
                                                ["y"] = 107037.26228144,
                                                ["x"] = 190963.5406147,
                                            }, -- end of [46]
                                            [54] = 
                                            {
                                                ["y"] = 107046.53552656,
                                                ["x"] = 190925.57709422,
                                            }, -- end of [54]
                                            [62] = 
                                            {
                                                ["y"] = 107103.57691099,
                                                ["x"] = 190800.00276858,
                                            }, -- end of [62]
                                            [303] = 
                                            {
                                                ["y"] = 104131.95754527,
                                                ["x"] = 190996.79330626,
                                            }, -- end of [303]
                                            [367] = 
                                            {
                                                ["y"] = 103766.48652199,
                                                ["x"] = 191225.41664178,
                                            }, -- end of [367]
                                            [108] = 
                                            {
                                                ["y"] = 106530.73265832,
                                                ["x"] = 190235.92044848,
                                            }, -- end of [108]
                                            [124] = 
                                            {
                                                ["y"] = 106436.82492275,
                                                ["x"] = 190219.85213886,
                                            }, -- end of [124]
                                            [152] = 
                                            {
                                                ["y"] = 106478.54838098,
                                                ["x"] = 189984.62676111,
                                            }, -- end of [152]
                                            [184] = 
                                            {
                                                ["y"] = 106421.64036604,
                                                ["x"] = 189852.15586803,
                                            }, -- end of [184]
                                            [216] = 
                                            {
                                                ["y"] = 106069.28661655,
                                                ["x"] = 189855.47234243,
                                            }, -- end of [216]
                                            [248] = 
                                            {
                                                ["y"] = 105057.80594425,
                                                ["x"] = 189882.50393431,
                                            }, -- end of [248]
                                            [304] = 
                                            {
                                                ["y"] = 104127.57029979,
                                                ["x"] = 190999.17447457,
                                            }, -- end of [304]
                                            [368] = 
                                            {
                                                ["y"] = 103766.66748924,
                                                ["x"] = 191230.36027489,
                                            }, -- end of [368]
                                            [432] = 
                                            {
                                                ["y"] = 103002.709672,
                                                ["x"] = 191784.35552622,
                                            }, -- end of [432]
                                            [366] = 
                                            {
                                                ["y"] = 103769.50242832,
                                                ["x"] = 191221.64711357,
                                            }, -- end of [366]
                                            [363] = 
                                            {
                                                ["y"] = 103784.06103543,
                                                ["x"] = 191223.34367497,
                                            }, -- end of [363]
                                            [359] = 
                                            {
                                                ["y"] = 103820.10880625,
                                                ["x"] = 191240.57513572,
                                            }, -- end of [359]
                                            [350] = 
                                            {
                                                ["y"] = 103888.1265746,
                                                ["x"] = 191230.50378319,
                                            }, -- end of [350]
                                            [339] = 
                                            {
                                                ["y"] = 103978.26833587,
                                                ["x"] = 191162.79200467,
                                            }, -- end of [339]
                                            [305] = 
                                            {
                                                ["y"] = 104123.72601873,
                                                ["x"] = 191002.36017238,
                                            }, -- end of [305]
                                            [369] = 
                                            {
                                                ["y"] = 103767.80918652,
                                                ["x"] = 191235.23738138,
                                            }, -- end of [369]
                                            [433] = 
                                            {
                                                ["y"] = 102998.9603959,
                                                ["x"] = 191787.66082982,
                                            }, -- end of [433]
                                            [334] = 
                                            {
                                                ["y"] = 103982.90567209,
                                                ["x"] = 191138.38600937,
                                            }, -- end of [334]
                                            [153] = 
                                            {
                                                ["y"] = 106476.52757648,
                                                ["x"] = 189980.05437595,
                                            }, -- end of [153]
                                            [185] = 
                                            {
                                                ["y"] = 106441.50950012,
                                                ["x"] = 189836.99370255,
                                            }, -- end of [185]
                                            [217] = 
                                            {
                                                ["y"] = 106064.77909224,
                                                ["x"] = 189857.6318882,
                                            }, -- end of [217]
                                            [249] = 
                                            {
                                                ["y"] = 105052.80619258,
                                                ["x"] = 189882.49720699,
                                            }, -- end of [249]
                                            [306] = 
                                            {
                                                ["y"] = 104120.3553255,
                                                ["x"] = 191006.05226422,
                                            }, -- end of [306]
                                            [370] = 
                                            {
                                                ["y"] = 103786.18185667,
                                                ["x"] = 191307.95045403,
                                            }, -- end of [370]
                                            [434] = 
                                            {
                                                ["y"] = 102991.54397531,
                                                ["x"] = 191794.36819374,
                                            }, -- end of [434]
                                            [331] = 
                                            {
                                                ["y"] = 103979.41615985,
                                                ["x"] = 191123.92839553,
                                            }, -- end of [331]
                                            [270] = 
                                            {
                                                ["y"] = 104598.44766661,
                                                ["x"] = 190160.83283195,
                                            }, -- end of [270]
                                            [327] = 
                                            {
                                                ["y"] = 103962.75002791,
                                                ["x"] = 191099.3466699,
                                            }, -- end of [327]
                                            [93] = 
                                            {
                                                ["y"] = 106604.73059009,
                                                ["x"] = 190393.53922747,
                                            }, -- end of [93]
                                            [109] = 
                                            {
                                                ["y"] = 106525.96064673,
                                                ["x"] = 190234.43420452,
                                            }, -- end of [109]
                                            [307] = 
                                            {
                                                ["y"] = 104114.08485614,
                                                ["x"] = 191013.83868003,
                                            }, -- end of [307]
                                            [371] = 
                                            {
                                                ["y"] = 103787.8181183,
                                                ["x"] = 191312.67310681,
                                            }, -- end of [371]
                                            [435] = 
                                            {
                                                ["y"] = 102987.6433175,
                                                ["x"] = 191797.49523055,
                                            }, -- end of [435]
                                            [125] = 
                                            {
                                                ["y"] = 106435.22751628,
                                                ["x"] = 190215.12377656,
                                            }, -- end of [125]
                                            [154] = 
                                            {
                                                ["y"] = 106474.18278493,
                                                ["x"] = 189975.63944581,
                                            }, -- end of [154]
                                            [186] = 
                                            {
                                                ["y"] = 106445.22555932,
                                                ["x"] = 189833.64775397,
                                            }, -- end of [186]
                                            [218] = 
                                            {
                                                ["y"] = 106060.16174856,
                                                ["x"] = 189859.54980441,
                                            }, -- end of [218]
                                            [250] = 
                                            {
                                                ["y"] = 105047.81691648,
                                                ["x"] = 189882.80011129,
                                            }, -- end of [250]
                                            [308] = 
                                            {
                                                ["y"] = 104093.42852242,
                                                ["x"] = 191042.06780561,
                                            }, -- end of [308]
                                            [372] = 
                                            {
                                                ["y"] = 103789.9478253,
                                                ["x"] = 191317.19162801,
                                            }, -- end of [372]
                                            [436] = 
                                            {
                                                ["y"] = 102983.51410931,
                                                ["x"] = 191800.31103792,
                                            }, -- end of [436]
                                            [318] = 
                                            {
                                                ["y"] = 103996.06599413,
                                                ["x"] = 191101.34997916,
                                            }, -- end of [318]
                                            [317] = 
                                            {
                                                ["y"] = 104000.99899838,
                                                ["x"] = 191102.14112132,
                                            }, -- end of [317]
                                            [77] = 
                                            {
                                                ["y"] = 107027.76392866,
                                                ["x"] = 190629.99492193,
                                            }, -- end of [77]
                                            [446] = 
                                            {
                                                ["y"] = 102925.44087158,
                                                ["x"] = 191810.52177671,
                                            }, -- end of [446]
                                            [255] = 
                                            {
                                                ["y"] = 104607.41765271,
                                                ["x"] = 190045.10489444,
                                            }, -- end of [255]
                                            [309] = 
                                            {
                                                ["y"] = 104064.95880577,
                                                ["x"] = 191076.9013007,
                                            }, -- end of [309]
                                            [373] = 
                                            {
                                                ["y"] = 103792.80985848,
                                                ["x"] = 191321.28264734,
                                            }, -- end of [373]
                                            [437] = 
                                            {
                                                ["y"] = 102979.14954094,
                                                ["x"] = 191802.74750027,
                                            }, -- end of [437]
                                            [335] = 
                                            {
                                                ["y"] = 103982.75376077,
                                                ["x"] = 191143.38144385,
                                            }, -- end of [335]
                                            [155] = 
                                            {
                                                ["y"] = 106468.91821021,
                                                ["x"] = 189967.13867596,
                                            }, -- end of [155]
                                            [187] = 
                                            {
                                                ["y"] = 106448.71104517,
                                                ["x"] = 189830.06639113,
                                            }, -- end of [187]
                                            [219] = 
                                            {
                                                ["y"] = 106050.71278562,
                                                ["x"] = 189862.81886897,
                                            }, -- end of [219]
                                            [251] = 
                                            {
                                                ["y"] = 105042.86155247,
                                                ["x"] = 189883.46026933,
                                            }, -- end of [251]
                                            [310] = 
                                            {
                                                ["y"] = 104061.15718289,
                                                ["x"] = 191080.13941958,
                                            }, -- end of [310]
                                            [374] = 
                                            {
                                                ["y"] = 103814.78970233,
                                                ["x"] = 191348.46504794,
                                            }, -- end of [374]
                                            [438] = 
                                            {
                                                ["y"] = 102974.58332312,
                                                ["x"] = 191804.78150388,
                                            }, -- end of [438]
                                            [302] = 
                                            {
                                                ["y"] = 104146.09768144,
                                                ["x"] = 190991.80462226,
                                            }, -- end of [302]
                                            [39] = 
                                            {
                                                ["y"] = 107077.12013458,
                                                ["x"] = 191043.79782682,
                                            }, -- end of [39]
                                            [47] = 
                                            {
                                                ["y"] = 107036.7076821,
                                                ["x"] = 190958.57366761,
                                            }, -- end of [47]
                                            [55] = 
                                            {
                                                ["y"] = 107060.5233288,
                                                ["x"] = 190904.85848443,
                                            }, -- end of [55]
                                            [63] = 
                                            {
                                                ["y"] = 107103.31543718,
                                                ["x"] = 190795.01100506,
                                            }, -- end of [63]
                                            [78] = 
                                            {
                                                ["y"] = 107023.41165756,
                                                ["x"] = 190627.5355138,
                                            }, -- end of [78]
                                            [94] = 
                                            {
                                                ["y"] = 106597.69888684,
                                                ["x"] = 190380.29136523,
                                            }, -- end of [94]
                                            [110] = 
                                            {
                                                ["y"] = 106521.07434359,
                                                ["x"] = 190233.38049557,
                                            }, -- end of [110]
                                            [126] = 
                                            {
                                                ["y"] = 106434.42805685,
                                                ["x"] = 190210.19161741,
                                            }, -- end of [126]
                                            [156] = 
                                            {
                                                ["y"] = 106465.97936211,
                                                ["x"] = 189963.09605324,
                                            }, -- end of [156]
                                            [188] = 
                                            {
                                                ["y"] = 106451.73540865,
                                                ["x"] = 189826.09086063,
                                            }, -- end of [188]
                                            [220] = 
                                            {
                                                ["y"] = 105940.45933171,
                                                ["x"] = 189895.46330703,
                                            }, -- end of [220]
                                            [252] = 
                                            {
                                                ["y"] = 105008.57225305,
                                                ["x"] = 189890.46819464,
                                            }, -- end of [252]
                                            [312] = 
                                            {
                                                ["y"] = 104039.48314911,
                                                ["x"] = 191092.53803086,
                                            }, -- end of [312]
                                            [376] = 
                                            {
                                                ["y"] = 103817.63677283,
                                                ["x"] = 191358.02150089,
                                            }, -- end of [376]
                                            [440] = 
                                            {
                                                ["y"] = 102965.10758071,
                                                ["x"] = 191807.95580295,
                                            }, -- end of [440]
                                            [395] = 
                                            {
                                                ["y"] = 103716.32334959,
                                                ["x"] = 191521.34314131,
                                            }, -- end of [395]
                                            [286] = 
                                            {
                                                ["y"] = 104195.57101458,
                                                ["x"] = 190725.49567297,
                                            }, -- end of [286]
                                            [283] = 
                                            {
                                                ["y"] = 104215.76118683,
                                                ["x"] = 190685.31835406,
                                            }, -- end of [283]
                                            [279] = 
                                            {
                                                ["y"] = 104470.84181746,
                                                ["x"] = 190364.56114998,
                                            }, -- end of [279]
                                            [275] = 
                                            {
                                                ["y"] = 104562.41577066,
                                                ["x"] = 190258.92798858,
                                            }, -- end of [275]
                                            [313] = 
                                            {
                                                ["y"] = 104030.26756651,
                                                ["x"] = 191096.41323193,
                                            }, -- end of [313]
                                            [377] = 
                                            {
                                                ["y"] = 103819.09120481,
                                                ["x"] = 191367.88974446,
                                            }, -- end of [377]
                                            [441] = 
                                            {
                                                ["y"] = 102960.23907343,
                                                ["x"] = 191809.09232559,
                                            }, -- end of [441]
                                            [259] = 
                                            {
                                                ["y"] = 104586.53179151,
                                                ["x"] = 190063.58790892,
                                            }, -- end of [259]
                                            [157] = 
                                            {
                                                ["y"] = 106462.68799297,
                                                ["x"] = 189959.33483196,
                                            }, -- end of [157]
                                            [189] = 
                                            {
                                                ["y"] = 106453.86735999,
                                                ["x"] = 189821.58513293,
                                            }, -- end of [189]
                                            [221] = 
                                            {
                                                ["y"] = 105853.96741773,
                                                ["x"] = 189920.30740876,
                                            }, -- end of [221]
                                            [253] = 
                                            {
                                                ["y"] = 105003.7786344,
                                                ["x"] = 189891.8822574,
                                            }, -- end of [253]
                                            [314] = 
                                            {
                                                ["y"] = 104025.51167711,
                                                ["x"] = 191097.95335782,
                                            }, -- end of [314]
                                            [378] = 
                                            {
                                                ["y"] = 103818.23348606,
                                                ["x"] = 191372.81247561,
                                            }, -- end of [378]
                                            [442] = 
                                            {
                                                ["y"] = 102955.31594735,
                                                ["x"] = 191809.9620991,
                                            }, -- end of [442]
                                            [13] = 
                                            {
                                                ["y"] = 107176.34230514,
                                                ["x"] = 191229.58229458,
                                            }, -- end of [13]
                                            [11] = 
                                            {
                                                ["y"] = 107212.73403833,
                                                ["x"] = 191246.09003466,
                                            }, -- end of [11]
                                            [9] = 
                                            {
                                                ["y"] = 107226.2429198,
                                                ["x"] = 191252.56084825,
                                            }, -- end of [9]
                                            [223] = 
                                            {
                                                ["y"] = 105750.51124472,
                                                ["x"] = 189957.57814189,
                                            }, -- end of [223]
                                            [191] = 
                                            {
                                                ["y"] = 106454.02346174,
                                                ["x"] = 189811.69567612,
                                            }, -- end of [191]
                                            [79] = 
                                            {
                                                ["y"] = 107014.45392106,
                                                ["x"] = 190623.09159991,
                                            }, -- end of [79]
                                            [95] = 
                                            {
                                                ["y"] = 106589.14723805,
                                                ["x"] = 190362.21400865,
                                            }, -- end of [95]
                                            [111] = 
                                            {
                                                ["y"] = 106516.10961599,
                                                ["x"] = 190232.80281829,
                                            }, -- end of [111]
                                            [159] = 
                                            {
                                                ["y"] = 106454.97736846,
                                                ["x"] = 189952.99907361,
                                            }, -- end of [159]
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            [1] = 
                                            {
                                                ["y"] = 102727.27133649,
                                                ["x"] = 188122.08926393,
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["y"] = 102727.27133649,
                                                ["x"] = 188122.08926393,
                                            }, -- end of [2]
                                        }, -- end of [2]
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 60,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 107238.66664164,
                                            ["x"] = 191288.9048466,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 4,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2763.8069431648,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 102489.00258089,
                                            ["x"] = 191576.19013685,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 2.7777777777778,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 2,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 7,
                                        ["y"] = 107238.66664164,
                                        ["x"] = 191288.9048466,
                                        ["name"] = "Ground-2-1",
                                        ["heading"] = 3.2410469744913,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 8,
                                        ["y"] = 107228.58976552,
                                        ["x"] = 191311.44009547,
                                        ["name"] = "Ground-2-2",
                                        ["heading"] = 2.7211024556853,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 9,
                                        ["y"] = 107214.00491178,
                                        ["x"] = 191337.68538785,
                                        ["name"] = "Ground-2-3",
                                        ["heading"] = 2.6343737418253,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [3]
                                    [4] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "T-90",
                                        ["unitId"] = 10,
                                        ["y"] = 107204.5231266,
                                        ["x"] = 191364.81744103,
                                        ["name"] = "Ground-2-4",
                                        ["heading"] = 2.8053918279818,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [4]
                                    [5] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Gepard",
                                        ["unitId"] = 11,
                                        ["y"] = 107205.01334968,
                                        ["x"] = 191390.95190303,
                                        ["name"] = "Ground-2-5",
                                        ["heading"] = 3.1603481800734,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [5]
                                    [6] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 12,
                                        ["y"] = 107209.25805647,
                                        ["x"] = 191420.47457893,
                                        ["name"] = "Ground-2-6",
                                        ["heading"] = 3.2843918821733,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [6]
                                }, -- end of ["units"]
                                ["y"] = 107238.66664164,
                                ["x"] = 191288.9048466,
                                ["name"] = "Invaders One",
                                ["start_time"] = 0,
                            }, -- end of [2]
                            [3] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 68,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 106296.38371362,
                                            ["x"] = 188682.23642538,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "Off Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 5,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland Radar",
                                        ["unitId"] = 17,
                                        ["y"] = 106296.38371362,
                                        ["x"] = 188682.23642538,
                                        ["name"] = "AAA One-3",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland ADS",
                                        ["unitId"] = 16,
                                        ["y"] = 106312.24517535,
                                        ["x"] = 188691.1861887,
                                        ["name"] = "AAA One-2",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland ADS",
                                        ["unitId"] = 15,
                                        ["y"] = 106315.08074392,
                                        ["x"] = 188672.84360447,
                                        ["name"] = "AAA One-1",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [3]
                                }, -- end of ["units"]
                                ["y"] = 106296.38371362,
                                ["x"] = 188682.23642538,
                                ["name"] = "AAA One",
                                ["start_time"] = 0,
                            }, -- end of [3]
                            [4] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 96.138066626282,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 105951.04300932,
                                            ["x"] = 186171.80915035,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "Off Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 6,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland Radar",
                                        ["unitId"] = 18,
                                        ["y"] = 105951.04300932,
                                        ["x"] = 186171.80915035,
                                        ["name"] = "AAA One-1-1",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland ADS",
                                        ["unitId"] = 19,
                                        ["y"] = 105966.90447105,
                                        ["x"] = 186180.75891367,
                                        ["name"] = "AAA One-1-2",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland ADS",
                                        ["unitId"] = 20,
                                        ["y"] = 105969.74003962,
                                        ["x"] = 186162.41632944,
                                        ["name"] = "AAA One-1-3",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [3]
                                }, -- end of ["units"]
                                ["y"] = 105951.04300932,
                                ["x"] = 186171.80915035,
                                ["name"] = "AAA One-1",
                                ["start_time"] = 0,
                            }, -- end of [4]
                            [5] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 96.138066626282,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 100756.76830316,
                                            ["x"] = 191017.81941411,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "Off Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 7,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland Radar",
                                        ["unitId"] = 21,
                                        ["y"] = 100756.76830316,
                                        ["x"] = 191017.81941411,
                                        ["name"] = "AAA One-2-1",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland ADS",
                                        ["unitId"] = 22,
                                        ["y"] = 100772.62976489,
                                        ["x"] = 191026.76917743,
                                        ["name"] = "AAA One-2-2",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland ADS",
                                        ["unitId"] = 23,
                                        ["y"] = 100775.46533346,
                                        ["x"] = 191008.4265932,
                                        ["name"] = "AAA One-2-3",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [3]
                                }, -- end of ["units"]
                                ["y"] = 100756.76830316,
                                ["x"] = 191017.81941411,
                                ["name"] = "AAA One-2",
                                ["start_time"] = 0,
                            }, -- end of [5]
                            [6] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                        [1] = 
                                        {
                                            [1] = 
                                            {
                                                ["y"] = 104819.69841308,
                                                ["x"] = 189413.43700538,
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["y"] = 104837.33809596,
                                                ["x"] = 189404.04754592,
                                            }, -- end of [2]
                                            [4] = 
                                            {
                                                ["y"] = 104870.63921086,
                                                ["x"] = 189373.79727331,
                                            }, -- end of [4]
                                            [8] = 
                                            {
                                                ["y"] = 104881.49132162,
                                                ["x"] = 189357.24877021,
                                            }, -- end of [8]
                                            [16] = 
                                            {
                                                ["y"] = 104924.25619257,
                                                ["x"] = 189198.61794577,
                                            }, -- end of [16]
                                            [32] = 
                                            {
                                                ["y"] = 104981.87447916,
                                                ["x"] = 188809.63696114,
                                            }, -- end of [32]
                                            [64] = 
                                            {
                                                ["y"] = 105036.98184291,
                                                ["x"] = 188211.59202245,
                                            }, -- end of [64]
                                            [128] = 
                                            {
                                                ["y"] = 105025.21440642,
                                                ["x"] = 187230.57886823,
                                            }, -- end of [128]
                                            [256] = 
                                            {
                                                ["y"] = 103213.71612169,
                                                ["x"] = 185440.46524512,
                                            }, -- end of [256]
                                            [512] = 
                                            {
                                                ["y"] = 101367.15411526,
                                                ["x"] = 180945.17026417,
                                            }, -- end of [512]
                                            [513] = 
                                            {
                                                ["y"] = 101340.71557377,
                                                ["x"] = 180910.10035484,
                                            }, -- end of [513]
                                            [257] = 
                                            {
                                                ["y"] = 103209.32222323,
                                                ["x"] = 185438.08584615,
                                            }, -- end of [257]
                                            [129] = 
                                            {
                                                ["y"] = 105020.36540852,
                                                ["x"] = 187229.36574246,
                                            }, -- end of [129]
                                            [258] = 
                                            {
                                                ["y"] = 103205.17470139,
                                                ["x"] = 185435.29895294,
                                            }, -- end of [258]
                                            [259] = 
                                            {
                                                ["y"] = 103201.26606353,
                                                ["x"] = 185432.18120708,
                                            }, -- end of [259]
                                            [65] = 
                                            {
                                                ["y"] = 105030.75227014,
                                                ["x"] = 188203.77110076,
                                            }, -- end of [65]
                                            [130] = 
                                            {
                                                ["y"] = 105015.44475713,
                                                ["x"] = 187228.48112553,
                                            }, -- end of [130]
                                            [260] = 
                                            {
                                                ["y"] = 103197.56098211,
                                                ["x"] = 185428.82468073,
                                            }, -- end of [260]
                                            [261] = 
                                            {
                                                ["y"] = 103190.61178236,
                                                ["x"] = 185421.63623593,
                                            }, -- end of [261]
                                            [131] = 
                                            {
                                                ["y"] = 105010.47903994,
                                                ["x"] = 187227.90504278,
                                            }, -- end of [131]
                                            [262] = 
                                            {
                                                ["y"] = 103184.20471606,
                                                ["x"] = 185413.96233416,
                                            }, -- end of [262]
                                            [263] = 
                                            {
                                                ["y"] = 103181.2874752,
                                                ["x"] = 185409.90220552,
                                            }, -- end of [263]
                                            [33] = 
                                            {
                                                ["y"] = 104978.15634851,
                                                ["x"] = 188769.81794488,
                                            }, -- end of [33]
                                            [66] = 
                                            {
                                                ["y"] = 104966.84795605,
                                                ["x"] = 188133.48132959,
                                            }, -- end of [66]
                                            [132] = 
                                            {
                                                ["y"] = 105005.48899895,
                                                ["x"] = 187227.59601189,
                                            }, -- end of [132]
                                            [264] = 
                                            {
                                                ["y"] = 103178.61078635,
                                                ["x"] = 185405.6801034,
                                            }, -- end of [264]
                                            [265] = 
                                            {
                                                ["y"] = 103176.19679312,
                                                ["x"] = 185401.30225198,
                                            }, -- end of [265]
                                            [133] = 
                                            {
                                                ["y"] = 104995.49067262,
                                                ["x"] = 187227.56581748,
                                            }, -- end of [133]
                                            [266] = 
                                            {
                                                ["y"] = 103174.06021139,
                                                ["x"] = 185396.78275804,
                                            }, -- end of [266]
                                            [267] = 
                                            {
                                                ["y"] = 103172.21659302,
                                                ["x"] = 185392.13584409,
                                            }, -- end of [267]
                                            [67] = 
                                            {
                                                ["y"] = 104893.28096168,
                                                ["x"] = 188051.70952998,
                                            }, -- end of [67]
                                            [134] = 
                                            {
                                                ["y"] = 104985.50624855,
                                                ["x"] = 187228.10630009,
                                            }, -- end of [134]
                                            [268] = 
                                            {
                                                ["y"] = 103170.68364865,
                                                ["x"] = 185387.37780816,
                                            }, -- end of [268]
                                            [269] = 
                                            {
                                                ["y"] = 103169.47218435,
                                                ["x"] = 185382.52794914,
                                            }, -- end of [269]
                                            [135] = 
                                            {
                                                ["y"] = 104831.50320933,
                                                ["x"] = 187245.38396051,
                                            }, -- end of [135]
                                            [270] = 
                                            {
                                                ["y"] = 103168.56318774,
                                                ["x"] = 185377.61175433,
                                            }, -- end of [270]
                                            [17] = 
                                            {
                                                ["y"] = 104929.36348673,
                                                ["x"] = 189190.02232642,
                                            }, -- end of [17]
                                            [34] = 
                                            {
                                                ["y"] = 104964.90076291,
                                                ["x"] = 188625.43224525,
                                            }, -- end of [34]
                                            [68] = 
                                            {
                                                ["y"] = 104872.15957523,
                                                ["x"] = 188023.8043484,
                                            }, -- end of [68]
                                            [136] = 
                                            {
                                                ["y"] = 104821.50473398,
                                                ["x"] = 187245.44604445,
                                            }, -- end of [136]
                                            [272] = 
                                            {
                                                ["y"] = 103167.30978232,
                                                ["x"] = 185362.67486194,
                                            }, -- end of [272]
                                            [273] = 
                                            {
                                                ["y"] = 103167.46382087,
                                                ["x"] = 185347.6780089,
                                            }, -- end of [273]
                                            [137] = 
                                            {
                                                ["y"] = 104811.51836533,
                                                ["x"] = 187244.95149497,
                                            }, -- end of [137]
                                            [274] = 
                                            {
                                                ["y"] = 103171.86586727,
                                                ["x"] = 185282.8309689,
                                            }, -- end of [274]
                                            [275] = 
                                            {
                                                ["y"] = 103175.70024229,
                                                ["x"] = 185248.04551469,
                                            }, -- end of [275]
                                            [69] = 
                                            {
                                                ["y"] = 104849.56526042,
                                                ["x"] = 187990.80977057,
                                            }, -- end of [69]
                                            [138] = 
                                            {
                                                ["y"] = 104801.57745667,
                                                ["x"] = 187243.87933679,
                                            }, -- end of [138]
                                            [276] = 
                                            {
                                                ["y"] = 103180.52793752,
                                                ["x"] = 185218.4401206,
                                            }, -- end of [276]
                                            [277] = 
                                            {
                                                ["y"] = 103183.68065633,
                                                ["x"] = 185203.7758428,
                                            }, -- end of [277]
                                            [139] = 
                                            {
                                                ["y"] = 104791.71187513,
                                                ["x"] = 187242.25205991,
                                            }, -- end of [139]
                                            [278] = 
                                            {
                                                ["y"] = 103186.31445208,
                                                ["x"] = 185194.13133084,
                                            }, -- end of [278]
                                            [279] = 
                                            {
                                                ["y"] = 103189.56020218,
                                                ["x"] = 185184.67535344,
                                            }, -- end of [279]
                                            [35] = 
                                            {
                                                ["y"] = 104959.2929536,
                                                ["x"] = 188570.72553583,
                                            }, -- end of [35]
                                            [70] = 
                                            {
                                                ["y"] = 104847.33141906,
                                                ["x"] = 187986.33710409,
                                            }, -- end of [70]
                                            [140] = 
                                            {
                                                ["y"] = 104781.9503444,
                                                ["x"] = 187240.08765344,
                                            }, -- end of [140]
                                            [280] = 
                                            {
                                                ["y"] = 103193.40065534,
                                                ["x"] = 185175.44387847,
                                            }, -- end of [280]
                                            [281] = 
                                            {
                                                ["y"] = 103195.65185458,
                                                ["x"] = 185170.97998134,
                                            }, -- end of [281]
                                            [141] = 
                                            {
                                                ["y"] = 104772.34794238,
                                                ["x"] = 187237.30306,
                                            }, -- end of [141]
                                            [282] = 
                                            {
                                                ["y"] = 103198.14622372,
                                                ["x"] = 185166.64717808,
                                            }, -- end of [282]
                                            [283] = 
                                            {
                                                ["y"] = 103200.85559875,
                                                ["x"] = 185162.44554196,
                                            }, -- end of [283]
                                            [71] = 
                                            {
                                                ["y"] = 104828.51070013,
                                                ["x"] = 187945.4664273,
                                            }, -- end of [71]
                                            [142] = 
                                            {
                                                ["y"] = 104767.64548171,
                                                ["x"] = 187235.60626993,
                                            }, -- end of [142]
                                            [284] = 
                                            {
                                                ["y"] = 103203.77112857,
                                                ["x"] = 185158.38417855,
                                            }, -- end of [284]
                                            [285] = 
                                            {
                                                ["y"] = 103210.16007202,
                                                ["x"] = 185150.69569001,
                                            }, -- end of [285]
                                            [143] = 
                                            {
                                                ["y"] = 104763.05142692,
                                                ["x"] = 187233.6343414,
                                            }, -- end of [143]
                                            [286] = 
                                            {
                                                ["y"] = 103217.1601509,
                                                ["x"] = 185143.55738882,
                                            }, -- end of [286]
                                            [9] = 
                                            {
                                                ["y"] = 104882.79818577,
                                                ["x"] = 189352.42412378,
                                            }, -- end of [9]
                                            [18] = 
                                            {
                                                ["y"] = 104943.51235889,
                                                ["x"] = 189169.41347537,
                                            }, -- end of [18]
                                            [36] = 
                                            {
                                                ["y"] = 104958.39894711,
                                                ["x"] = 188530.73821384,
                                            }, -- end of [36]
                                            [72] = 
                                            {
                                                ["y"] = 104806.25254408,
                                                ["x"] = 187889.75238613,
                                            }, -- end of [72]
                                            [144] = 
                                            {
                                                ["y"] = 104758.61719801,
                                                ["x"] = 187231.32781063,
                                            }, -- end of [144]
                                            [288] = 
                                            {
                                                ["y"] = 103247.95932739,
                                                ["x"] = 185118.05907989,
                                            }, -- end of [288]
                                            [289] = 
                                            {
                                                ["y"] = 103295.03995748,
                                                ["x"] = 185080.88091944,
                                            }, -- end of [289]
                                            [145] = 
                                            {
                                                ["y"] = 104754.40417917,
                                                ["x"] = 187228.63871536,
                                            }, -- end of [145]
                                            [290] = 
                                            {
                                                ["y"] = 103306.2094817,
                                                ["x"] = 185070.87276335,
                                            }, -- end of [290]
                                            [291] = 
                                            {
                                                ["y"] = 103313.19976385,
                                                ["x"] = 185063.7230204,
                                            }, -- end of [291]
                                            [73] = 
                                            {
                                                ["y"] = 104801.53483602,
                                                ["x"] = 187875.51514195,
                                            }, -- end of [73]
                                            [146] = 
                                            {
                                                ["y"] = 104750.47344739,
                                                ["x"] = 187225.55175692,
                                            }, -- end of [146]
                                            [292] = 
                                            {
                                                ["y"] = 103319.75613993,
                                                ["x"] = 185056.17485951,
                                            }, -- end of [292]
                                            [293] = 
                                            {
                                                ["y"] = 103325.65647824,
                                                ["x"] = 185048.10624922,
                                            }, -- end of [293]
                                            [147] = 
                                            {
                                                ["y"] = 104746.85593493,
                                                ["x"] = 187222.10402098,
                                            }, -- end of [147]
                                            [294] = 
                                            {
                                                ["y"] = 103328.2668323,
                                                ["x"] = 185043.84264739,
                                            }, -- end of [294]
                                            [295] = 
                                            {
                                                ["y"] = 103330.60948712,
                                                ["x"] = 185039.4264742,
                                            }, -- end of [295]
                                            [37] = 
                                            {
                                                ["y"] = 104958.67344192,
                                                ["x"] = 188520.74589313,
                                            }, -- end of [37]
                                            [74] = 
                                            {
                                                ["y"] = 104796.29368112,
                                                ["x"] = 187856.21697082,
                                            }, -- end of [74]
                                            [148] = 
                                            {
                                                ["y"] = 104743.50407853,
                                                ["x"] = 187218.39352327,
                                            }, -- end of [148]
                                            [296] = 
                                            {
                                                ["y"] = 103332.69339487,
                                                ["x"] = 185034.88191108,
                                            }, -- end of [296]
                                            [297] = 
                                            {
                                                ["y"] = 103336.29505911,
                                                ["x"] = 185025.55464132,
                                            }, -- end of [297]
                                            [149] = 
                                            {
                                                ["y"] = 104734.20900223,
                                                ["x"] = 187206.62225607,
                                            }, -- end of [149]
                                            [298] = 
                                            {
                                                ["y"] = 103356.30188138,
                                                ["x"] = 184969.000268,
                                            }, -- end of [298]
                                            [299] = 
                                            {
                                                ["y"] = 103360.63591207,
                                                ["x"] = 184959.99131246,
                                            }, -- end of [299]
                                            [75] = 
                                            {
                                                ["y"] = 104786.77777899,
                                                ["x"] = 187817.36708611,
                                            }, -- end of [75]
                                            [150] = 
                                            {
                                                ["y"] = 104728.34488866,
                                                ["x"] = 187198.52400325,
                                            }, -- end of [150]
                                            [300] = 
                                            {
                                                ["y"] = 103365.69032702,
                                                ["x"] = 184951.36552304,
                                            }, -- end of [300]
                                            [301] = 
                                            {
                                                ["y"] = 103371.40539717,
                                                ["x"] = 184943.16430634,
                                            }, -- end of [301]
                                            [151] = 
                                            {
                                                ["y"] = 104725.67452839,
                                                ["x"] = 187194.29692845,
                                            }, -- end of [151]
                                            [302] = 
                                            {
                                                ["y"] = 103374.61010815,
                                                ["x"] = 184939.32652104,
                                            }, -- end of [302]
                                            [19] = 
                                            {
                                                ["y"] = 104961.03203961,
                                                ["x"] = 189145.06237946,
                                            }, -- end of [19]
                                            [38] = 
                                            {
                                                ["y"] = 104959.18733489,
                                                ["x"] = 188515.77434409,
                                            }, -- end of [38]
                                            [76] = 
                                            {
                                                ["y"] = 104786.01711014,
                                                ["x"] = 187812.42784025,
                                            }, -- end of [76]
                                            [152] = 
                                            {
                                                ["y"] = 104723.26449288,
                                                ["x"] = 187189.91813972,
                                            }, -- end of [152]
                                            [304] = 
                                            {
                                                ["y"] = 103381.82801114,
                                                ["x"] = 184932.42132026,
                                            }, -- end of [304]
                                            [305] = 
                                            {
                                                ["y"] = 103385.8102942,
                                                ["x"] = 184929.39967323,
                                            }, -- end of [305]
                                            [153] = 
                                            {
                                                ["y"] = 104721.14479106,
                                                ["x"] = 187185.39108946,
                                            }, -- end of [153]
                                            [306] = 
                                            {
                                                ["y"] = 103389.98616682,
                                                ["x"] = 184926.65109629,
                                            }, -- end of [306]
                                            [307] = 
                                            {
                                                ["y"] = 103394.31444001,
                                                ["x"] = 184924.14953988,
                                            }, -- end of [307]
                                            [77] = 
                                            {
                                                ["y"] = 104785.75489727,
                                                ["x"] = 187807.43968536,
                                            }, -- end of [77]
                                            [154] = 
                                            {
                                                ["y"] = 104719.28849837,
                                                ["x"] = 187180.74871303,
                                            }, -- end of [154]
                                            [308] = 
                                            {
                                                ["y"] = 103403.30084234,
                                                ["x"] = 184919.76887864,
                                            }, -- end of [308]
                                            [309] = 
                                            {
                                                ["y"] = 103412.56986088,
                                                ["x"] = 184916.0208152,
                                            }, -- end of [309]
                                            [155] = 
                                            {
                                                ["y"] = 104717.66905242,
                                                ["x"] = 187176.01870389,
                                            }, -- end of [155]
                                            [310] = 
                                            {
                                                ["y"] = 103436.22585357,
                                                ["x"] = 184907.93951449,
                                            }, -- end of [310]
                                            [311] = 
                                            {
                                                ["y"] = 103526.00439964,
                                                ["x"] = 184876.92793725,
                                            }, -- end of [311]
                                            [39] = 
                                            {
                                                ["y"] = 104963.05992457,
                                                ["x"] = 188491.07528575,
                                            }, -- end of [39]
                                            [78] = 
                                            {
                                                ["y"] = 104786.02312087,
                                                ["x"] = 187802.44843469,
                                            }, -- end of [78]
                                            [156] = 
                                            {
                                                ["y"] = 104715.07754358,
                                                ["x"] = 187166.36347606,
                                            }, -- end of [156]
                                            [312] = 
                                            {
                                                ["y"] = 103539.85856697,
                                                ["x"] = 184871.19360003,
                                            }, -- end of [312]
                                            [313] = 
                                            {
                                                ["y"] = 103562.03203111,
                                                ["x"] = 184859.64872663,
                                            }, -- end of [313]
                                            [157] = 
                                            {
                                                ["y"] = 104713.36789713,
                                                ["x"] = 187156.51469133,
                                            }, -- end of [157]
                                            [314] = 
                                            {
                                                ["y"] = 103566.22777338,
                                                ["x"] = 184856.93600155,
                                            }, -- end of [314]
                                            [315] = 
                                            {
                                                ["y"] = 103578.58811436,
                                                ["x"] = 184848.4450274,
                                            }, -- end of [315]
                                            [79] = 
                                            {
                                                ["y"] = 104786.69952973,
                                                ["x"] = 187797.49480346,
                                            }, -- end of [79]
                                            [158] = 
                                            {
                                                ["y"] = 104712.90919586,
                                                ["x"] = 187151.53659178,
                                            }, -- end of [158]
                                            [316] = 
                                            {
                                                ["y"] = 103595.20677068,
                                                ["x"] = 184837.32415774,
                                            }, -- end of [316]
                                            [317] = 
                                            {
                                                ["y"] = 103599.00434725,
                                                ["x"] = 184834.07715337,
                                            }, -- end of [317]
                                            [159] = 
                                            {
                                                ["y"] = 104712.73345571,
                                                ["x"] = 187146.54023741,
                                            }, -- end of [159]
                                            [318] = 
                                            {
                                                ["y"] = 103602.38274027,
                                                ["x"] = 184830.39445268,
                                            }, -- end of [318]
                                            [5] = 
                                            {
                                                ["y"] = 104874.07852723,
                                                ["x"] = 189370.16989854,
                                            }, -- end of [5]
                                            [10] = 
                                            {
                                                ["y"] = 104884.70783719,
                                                ["x"] = 189342.61044444,
                                            }, -- end of [10]
                                            [20] = 
                                            {
                                                ["y"] = 104964.2123345,
                                                ["x"] = 189141.20514499,
                                            }, -- end of [20]
                                            [40] = 
                                            {
                                                ["y"] = 104964.15776581,
                                                ["x"] = 188486.19936041,
                                            }, -- end of [40]
                                            [80] = 
                                            {
                                                ["y"] = 104795.72771089,
                                                ["x"] = 187753.41039918,
                                            }, -- end of [80]
                                            [160] = 
                                            {
                                                ["y"] = 104712.83393456,
                                                ["x"] = 187141.54201864,
                                            }, -- end of [160]
                                            [320] = 
                                            {
                                                ["y"] = 103608.15799632,
                                                ["x"] = 184822.23854764,
                                            }, -- end of [320]
                                            [321] = 
                                            {
                                                ["y"] = 103610.70017149,
                                                ["x"] = 184817.93367532,
                                            }, -- end of [321]
                                            [161] = 
                                            {
                                                ["y"] = 104713.74020038,
                                                ["x"] = 187131.5866324,
                                            }, -- end of [161]
                                            [322] = 
                                            {
                                                ["y"] = 103615.15261611,
                                                ["x"] = 184808.98482594,
                                            }, -- end of [322]
                                            [323] = 
                                            {
                                                ["y"] = 103616.97744211,
                                                ["x"] = 184804.33050759,
                                            }, -- end of [323]
                                            [81] = 
                                            {
                                                ["y"] = 104798.25954019,
                                                ["x"] = 187743.74054432,
                                            }, -- end of [81]
                                            [162] = 
                                            {
                                                ["y"] = 104716.09316673,
                                                ["x"] = 187116.7733938,
                                            }, -- end of [162]
                                            [324] = 
                                            {
                                                ["y"] = 103618.532879,
                                                ["x"] = 184799.57932763,
                                            }, -- end of [324]
                                            [325] = 
                                            {
                                                ["y"] = 103620.98444064,
                                                ["x"] = 184789.887369,
                                            }, -- end of [325]
                                            [163] = 
                                            {
                                                ["y"] = 104721.95950478,
                                                ["x"] = 187087.35621788,
                                            }, -- end of [163]
                                            [326] = 
                                            {
                                                ["y"] = 103624.43845227,
                                                ["x"] = 184770.18949688,
                                            }, -- end of [326]
                                            [327] = 
                                            {
                                                ["y"] = 103629.48007704,
                                                ["x"] = 184735.55813228,
                                            }, -- end of [327]
                                            [41] = 
                                            {
                                                ["y"] = 104965.62205728,
                                                ["x"] = 188481.41938385,
                                            }, -- end of [41]
                                            [82] = 
                                            {
                                                ["y"] = 104809.15127086,
                                                ["x"] = 187710.48271619,
                                            }, -- end of [82]
                                            [164] = 
                                            {
                                                ["y"] = 104736.70824603,
                                                ["x"] = 187029.21700538,
                                            }, -- end of [164]
                                            [328] = 
                                            {
                                                ["y"] = 103630.17628236,
                                                ["x"] = 184725.58474921,
                                            }, -- end of [328]
                                            [329] = 
                                            {
                                                ["y"] = 103630.18991354,
                                                ["x"] = 184715.58644998,
                                            }, -- end of [329]
                                            [165] = 
                                            {
                                                ["y"] = 104738.26774078,
                                                ["x"] = 187019.34063139,
                                            }, -- end of [165]
                                            [330] = 
                                            {
                                                ["y"] = 103629.2542647,
                                                ["x"] = 184700.61795584,
                                            }, -- end of [330]
                                            [331] = 
                                            {
                                                ["y"] = 103626.93294998,
                                                ["x"] = 184680.75542742,
                                            }, -- end of [331]
                                            [83] = 
                                            {
                                                ["y"] = 104811.10432073,
                                                ["x"] = 187705.88085273,
                                            }, -- end of [83]
                                            [166] = 
                                            {
                                                ["y"] = 104739.22129607,
                                                ["x"] = 187009.38809183,
                                            }, -- end of [166]
                                            [332] = 
                                            {
                                                ["y"] = 103624.43368259,
                                                ["x"] = 184665.96674531,
                                            }, -- end of [332]
                                            [333] = 
                                            {
                                                ["y"] = 103621.02831788,
                                                ["x"] = 184651.36181467,
                                            }, -- end of [333]
                                            [167] = 
                                            {
                                                ["y"] = 104739.55278418,
                                                ["x"] = 186999.39489245,
                                            }, -- end of [167]
                                            [334] = 
                                            {
                                                ["y"] = 103618.10510208,
                                                ["x"] = 184641.80014232,
                                            }, -- end of [334]
                                            [21] = 
                                            {
                                                ["y"] = 104973.87911253,
                                                ["x"] = 189129.7660753,
                                            }, -- end of [21]
                                            [42] = 
                                            {
                                                ["y"] = 104969.20156904,
                                                ["x"] = 188472.08319311,
                                            }, -- end of [42]
                                            [84] = 
                                            {
                                                ["y"] = 104813.33435444,
                                                ["x"] = 187701.4075054,
                                            }, -- end of [84]
                                            [168] = 
                                            {
                                                ["y"] = 104739.20559292,
                                                ["x"] = 186984.40097179,
                                            }, -- end of [168]
                                            [336] = 
                                            {
                                                ["y"] = 103610.12344006,
                                                ["x"] = 184623.49079594,
                                            }, -- end of [336]
                                            [337] = 
                                            {
                                                ["y"] = 103607.59947313,
                                                ["x"] = 184619.17510354,
                                            }, -- end of [337]
                                            [169] = 
                                            {
                                                ["y"] = 104737.97302549,
                                                ["x"] = 186969.45426097,
                                            }, -- end of [169]
                                            [338] = 
                                            {
                                                ["y"] = 103604.86832125,
                                                ["x"] = 184614.98753977,
                                            }, -- end of [338]
                                            [339] = 
                                            {
                                                ["y"] = 103601.9337273,
                                                ["x"] = 184610.93992601,
                                            }, -- end of [339]
                                            [85] = 
                                            {
                                                ["y"] = 104815.82902525,
                                                ["x"] = 187697.07501848,
                                            }, -- end of [85]
                                            [170] = 
                                            {
                                                ["y"] = 104736.48169597,
                                                ["x"] = 186959.56719742,
                                            }, -- end of [170]
                                            [340] = 
                                            {
                                                ["y"] = 103598.79913352,
                                                ["x"] = 184607.04547901,
                                            }, -- end of [340]
                                            [341] = 
                                            {
                                                ["y"] = 103592.07863897,
                                                ["x"] = 184599.6423645,
                                            }, -- end of [341]
                                            [171] = 
                                            {
                                                ["y"] = 104735.4083709,
                                                ["x"] = 186954.68541972,
                                            }, -- end of [171]
                                            [342] = 
                                            {
                                                ["y"] = 103539.76036082,
                                                ["x"] = 184545.90770931,
                                            }, -- end of [342]
                                            [343] = 
                                            {
                                                ["y"] = 103513.40380603,
                                                ["x"] = 184522.88240019,
                                            }, -- end of [343]
                                            [43] = 
                                            {
                                                ["y"] = 104975.04126825,
                                                ["x"] = 188458.26899675,
                                            }, -- end of [43]
                                            [86] = 
                                            {
                                                ["y"] = 104821.35361598,
                                                ["x"] = 187688.74171323,
                                            }, -- end of [86]
                                            [172] = 
                                            {
                                                ["y"] = 104734.09201498,
                                                ["x"] = 186949.86259523,
                                            }, -- end of [172]
                                            [344] = 
                                            {
                                                ["y"] = 103501.80611733,
                                                ["x"] = 184513.37152678,
                                            }, -- end of [344]
                                            [345] = 
                                            {
                                                ["y"] = 103493.7350754,
                                                ["x"] = 184507.47048587,
                                            }, -- end of [345]
                                            [173] = 
                                            {
                                                ["y"] = 104730.84426738,
                                                ["x"] = 186940.40732778,
                                            }, -- end of [173]
                                            [346] = 
                                            {
                                                ["y"] = 103481.09365989,
                                                ["x"] = 184499.39981822,
                                            }, -- end of [346]
                                            [347] = 
                                            {
                                                ["y"] = 103451.6102891,
                                                ["x"] = 184480.55125896,
                                            }, -- end of [347]
                                            [87] = 
                                            {
                                                ["y"] = 104851.19972144,
                                                ["x"] = 187648.63059764,
                                            }, -- end of [87]
                                            [174] = 
                                            {
                                                ["y"] = 104724.9814168,
                                                ["x"] = 186926.6035572,
                                            }, -- end of [174]
                                            [348] = 
                                            {
                                                ["y"] = 103372.73118613,
                                                ["x"] = 184427.64169695,
                                            }, -- end of [348]
                                            [349] = 
                                            {
                                                ["y"] = 103353.65359537,
                                                ["x"] = 184411.4850177,
                                            }, -- end of [349]
                                            [175] = 
                                            {
                                                ["y"] = 104714.01914606,
                                                ["x"] = 186904.13711748,
                                            }, -- end of [175]
                                            [350] = 
                                            {
                                                ["y"] = 103339.05844724,
                                                ["x"] = 184397.81605874,
                                            }, -- end of [350]
                                            [11] = 
                                            {
                                                ["y"] = 104890.56084733,
                                                ["x"] = 189303.05408886,
                                            }, -- end of [11]
                                            [22] = 
                                            {
                                                ["y"] = 104976.29372956,
                                                ["x"] = 189125.39334574,
                                            }, -- end of [22]
                                            [44] = 
                                            {
                                                ["y"] = 104979.68552339,
                                                ["x"] = 188449.41677006,
                                            }, -- end of [44]
                                            [88] = 
                                            {
                                                ["y"] = 104882.08423753,
                                                ["x"] = 187609.32107282,
                                            }, -- end of [88]
                                            [176] = 
                                            {
                                                ["y"] = 104704.49938631,
                                                ["x"] = 186886.5501516,
                                            }, -- end of [176]
                                            [352] = 
                                            {
                                                ["y"] = 103229.12674083,
                                                ["x"] = 184274.78816015,
                                            }, -- end of [352]
                                            [353] = 
                                            {
                                                ["y"] = 103225.95576679,
                                                ["x"] = 184270.92376662,
                                            }, -- end of [353]
                                            [177] = 
                                            {
                                                ["y"] = 104699.2786207,
                                                ["x"] = 186878.02273881,
                                            }, -- end of [177]
                                            [354] = 
                                            {
                                                ["y"] = 103222.45894645,
                                                ["x"] = 184267.35108574,
                                            }, -- end of [354]
                                            [355] = 
                                            {
                                                ["y"] = 103165.03491553,
                                                ["x"] = 184211.66491845,
                                            }, -- end of [355]
                                            [89] = 
                                            {
                                                ["y"] = 104885.65891461,
                                                ["x"] = 187605.82738438,
                                            }, -- end of [89]
                                            [178] = 
                                            {
                                                ["y"] = 104693.46535934,
                                                ["x"] = 186869.88888884,
                                            }, -- end of [178]
                                            [356] = 
                                            {
                                                ["y"] = 103005.71597716,
                                                ["x"] = 184067.30263624,
                                            }, -- end of [356]
                                            [357] = 
                                            {
                                                ["y"] = 103002.25259674,
                                                ["x"] = 184063.6997554,
                                            }, -- end of [357]
                                            [179] = 
                                            {
                                                ["y"] = 104681.25208559,
                                                ["x"] = 186854.05394706,
                                            }, -- end of [179]
                                            [358] = 
                                            {
                                                ["y"] = 102982.28093828,
                                                ["x"] = 184041.33869192,
                                            }, -- end of [358]
                                            [359] = 
                                            {
                                                ["y"] = 102964.25904597,
                                                ["x"] = 184017.36899521,
                                            }, -- end of [359]
                                            [45] = 
                                            {
                                                ["y"] = 104984.9360717,
                                                ["x"] = 188440.90731508,
                                            }, -- end of [45]
                                            [90] = 
                                            {
                                                ["y"] = 104889.5009567,
                                                ["x"] = 187602.62929948,
                                            }, -- end of [90]
                                            [180] = 
                                            {
                                                ["y"] = 104677.8325666,
                                                ["x"] = 186850.40712965,
                                            }, -- end of [180]
                                            [360] = 
                                            {
                                                ["y"] = 102926.57441614,
                                                ["x"] = 183958.39215396,
                                            }, -- end of [360]
                                            [361] = 
                                            {
                                                ["y"] = 102922.21838018,
                                                ["x"] = 183949.39465912,
                                            }, -- end of [361]
                                            [181] = 
                                            {
                                                ["y"] = 104674.44150176,
                                                ["x"] = 186846.73370164,
                                            }, -- end of [181]
                                            [362] = 
                                            {
                                                ["y"] = 102850.64951962,
                                                ["x"] = 183778.81708681,
                                            }, -- end of [362]
                                            [363] = 
                                            {
                                                ["y"] = 102810.77559646,
                                                ["x"] = 183698.16106319,
                                            }, -- end of [363]
                                            [91] = 
                                            {
                                                ["y"] = 104893.56952123,
                                                ["x"] = 187599.72653661,
                                            }, -- end of [91]
                                            [182] = 
                                            {
                                                ["y"] = 104473.82372292,
                                                ["x"] = 186617.05493058,
                                            }, -- end of [182]
                                            [364] = 
                                            {
                                                ["y"] = 102807.8228804,
                                                ["x"] = 183694.12835551,
                                            }, -- end of [364]
                                            [365] = 
                                            {
                                                ["y"] = 102773.72043362,
                                                ["x"] = 183651.01734302,
                                            }, -- end of [365]
                                            [183] = 
                                            {
                                                ["y"] = 104417.56094935,
                                                ["x"] = 186560.19351461,
                                            }, -- end of [183]
                                            [366] = 
                                            {
                                                ["y"] = 102758.79742522,
                                                ["x"] = 183637.703696,
                                            }, -- end of [366]
                                            [23] = 
                                            {
                                                ["y"] = 104978.31880009,
                                                ["x"] = 189120.82191627,
                                            }, -- end of [23]
                                            [46] = 
                                            {
                                                ["y"] = 105020.7749453,
                                                ["x"] = 188386.69058357,
                                            }, -- end of [46]
                                            [92] = 
                                            {
                                                ["y"] = 104936.01662491,
                                                ["x"] = 187573.30358522,
                                            }, -- end of [92]
                                            [184] = 
                                            {
                                                ["y"] = 104406.29736634,
                                                ["x"] = 186550.29051075,
                                            }, -- end of [184]
                                            [368] = 
                                            {
                                                ["y"] = 102733.66501168,
                                                ["x"] = 183621.33502239,
                                            }, -- end of [368]
                                            [369] = 
                                            {
                                                ["y"] = 102408.21926819,
                                                ["x"] = 183445.32080122,
                                            }, -- end of [369]
                                            [185] = 
                                            {
                                                ["y"] = 104355.16068669,
                                                ["x"] = 186510.16881795,
                                            }, -- end of [185]
                                            [370] = 
                                            {
                                                ["y"] = 102381.1699745,
                                                ["x"] = 183432.35463399,
                                            }, -- end of [370]
                                            [371] = 
                                            {
                                                ["y"] = 102367.33959752,
                                                ["x"] = 183426.55126569,
                                            }, -- end of [371]
                                            [93] = 
                                            {
                                                ["y"] = 104962.20093233,
                                                ["x"] = 187558.66512055,
                                            }, -- end of [93]
                                            [186] = 
                                            {
                                                ["y"] = 104350.99362948,
                                                ["x"] = 186507.40723891,
                                            }, -- end of [186]
                                            [372] = 
                                            {
                                                ["y"] = 102357.91422746,
                                                ["x"] = 183423.21393702,
                                            }, -- end of [372]
                                            [373] = 
                                            {
                                                ["y"] = 102348.28774656,
                                                ["x"] = 183420.51612608,
                                            }, -- end of [373]
                                            [187] = 
                                            {
                                                ["y"] = 104346.83462734,
                                                ["x"] = 186504.63416538,
                                            }, -- end of [187]
                                            [374] = 
                                            {
                                                ["y"] = 102338.49899784,
                                                ["x"] = 183418.47951741,
                                            }, -- end of [374]
                                            [375] = 
                                            {
                                                ["y"] = 102328.60597422,
                                                ["x"] = 183417.02967472,
                                            }, -- end of [375]
                                            [47] = 
                                            {
                                                ["y"] = 105046.54605416,
                                                ["x"] = 188349.81898528,
                                            }, -- end of [47]
                                            [94] = 
                                            {
                                                ["y"] = 104971.22801868,
                                                ["x"] = 187554.37048474,
                                            }, -- end of [94]
                                            [188] = 
                                            {
                                                ["y"] = 104338.97925385,
                                                ["x"] = 186498.44716763,
                                            }, -- end of [188]
                                            [376] = 
                                            {
                                                ["y"] = 102318.64211028,
                                                ["x"] = 183416.20689503,
                                            }, -- end of [376]
                                            [377] = 
                                            {
                                                ["y"] = 102308.64457212,
                                                ["x"] = 183416.13080643,
                                            }, -- end of [377]
                                            [189] = 
                                            {
                                                ["y"] = 104272.97964946,
                                                ["x"] = 186444.89837692,
                                            }, -- end of [189]
                                            [378] = 
                                            {
                                                ["y"] = 102278.70591784,
                                                ["x"] = 183418.02674431,
                                            }, -- end of [378]
                                            [379] = 
                                            {
                                                ["y"] = 102268.77738998,
                                                ["x"] = 183419.19918951,
                                            }, -- end of [379]
                                            [95] = 
                                            {
                                                ["y"] = 104975.91614136,
                                                ["x"] = 187552.63867082,
                                            }, -- end of [95]
                                            [190] = 
                                            {
                                                ["y"] = 104202.72066992,
                                                ["x"] = 186380.97877378,
                                            }, -- end of [190]
                                            [380] = 
                                            {
                                                ["y"] = 102243.93476926,
                                                ["x"] = 183421.97501084,
                                            }, -- end of [380]
                                            [381] = 
                                            {
                                                ["y"] = 102239.30011713,
                                                ["x"] = 183423.44993044,
                                            }, -- end of [381]
                                            [191] = 
                                            {
                                                ["y"] = 104002.86088243,
                                                ["x"] = 186214.71462118,
                                            }, -- end of [191]
                                            [382] = 
                                            {
                                                ["y"] = 102236.72388514,
                                                ["x"] = 183427.69753019,
                                            }, -- end of [382]
                                            [3] = 
                                            {
                                                ["y"] = 104841.19924895,
                                                ["x"] = 189400.87431671,
                                            }, -- end of [3]
                                            [6] = 
                                            {
                                                ["y"] = 104877.12514196,
                                                ["x"] = 189366.20850316,
                                            }, -- end of [6]
                                            [12] = 
                                            {
                                                ["y"] = 104895.22206628,
                                                ["x"] = 189283.60656089,
                                            }, -- end of [12]
                                            [24] = 
                                            {
                                                ["y"] = 104981.80676974,
                                                ["x"] = 189111.45070042,
                                            }, -- end of [24]
                                            [48] = 
                                            {
                                                ["y"] = 105054.36119576,
                                                ["x"] = 188337.02140274,
                                            }, -- end of [48]
                                            [96] = 
                                            {
                                                ["y"] = 104980.71391106,
                                                ["x"] = 187551.2317245,
                                            }, -- end of [96]
                                            [192] = 
                                            {
                                                ["y"] = 103975.11373579,
                                                ["x"] = 186193.39265603,
                                            }, -- end of [192]
                                            [384] = 
                                            {
                                                ["y"] = 102236.64498008,
                                                ["x"] = 183437.43242509,
                                            }, -- end of [384]
                                            [385] = 
                                            {
                                                ["y"] = 102237.17201974,
                                                ["x"] = 183442.40310304,
                                            }, -- end of [385]
                                            [193] = 
                                            {
                                                ["y"] = 103940.20460804,
                                                ["x"] = 186165.01289096,
                                            }, -- end of [193]
                                            [386] = 
                                            {
                                                ["y"] = 102242.23900199,
                                                ["x"] = 183502.17197457,
                                            }, -- end of [386]
                                            [387] = 
                                            {
                                                ["y"] = 102243.52221483,
                                                ["x"] = 183506.98893523,
                                            }, -- end of [387]
                                            [97] = 
                                            {
                                                ["y"] = 105000.12899622,
                                                ["x"] = 187546.45089445,
                                            }, -- end of [97]
                                            [194] = 
                                            {
                                                ["y"] = 103932.31804991,
                                                ["x"] = 186158.87350263,
                                            }, -- end of [194]
                                            [388] = 
                                            {
                                                ["y"] = 102246.6824669,
                                                ["x"] = 183510.78422107,
                                            }, -- end of [388]
                                            [389] = 
                                            {
                                                ["y"] = 102251.16070978,
                                                ["x"] = 183512.96877012,
                                            }, -- end of [389]
                                            [195] = 
                                            {
                                                ["y"] = 103928.69188044,
                                                ["x"] = 186155.4326453,
                                            }, -- end of [195]
                                            [390] = 
                                            {
                                                ["y"] = 102255.94105423,
                                                ["x"] = 183514.4315472,
                                            }, -- end of [390]
                                            [391] = 
                                            {
                                                ["y"] = 102270.16682918,
                                                ["x"] = 183518.95395063,
                                            }, -- end of [391]
                                            [49] = 
                                            {
                                                ["y"] = 105056.58808346,
                                                ["x"] = 188332.54502956,
                                            }, -- end of [49]
                                            [98] = 
                                            {
                                                ["y"] = 105004.83346243,
                                                ["x"] = 187544.75727964,
                                            }, -- end of [98]
                                            [196] = 
                                            {
                                                ["y"] = 103921.83403323,
                                                ["x"] = 186148.15550477,
                                            }, -- end of [196]
                                            [392] = 
                                            {
                                                ["y"] = 102273.70822283,
                                                ["x"] = 183522.43745468,
                                            }, -- end of [392]
                                            [393] = 
                                            {
                                                ["y"] = 102275.91185382,
                                                ["x"] = 183526.91093151,
                                            }, -- end of [393]
                                            [197] = 
                                            {
                                                ["y"] = 103892.10885308,
                                                ["x"] = 186114.37601124,
                                            }, -- end of [197]
                                            [394] = 
                                            {
                                                ["y"] = 102276.97190433,
                                                ["x"] = 183531.78595434,
                                            }, -- end of [394]
                                            [395] = 
                                            {
                                                ["y"] = 102276.79885641,
                                                ["x"] = 183536.76976717,
                                            }, -- end of [395]
                                            [99] = 
                                            {
                                                ["y"] = 105009.33846615,
                                                ["x"] = 187542.59787533,
                                            }, -- end of [99]
                                            [198] = 
                                            {
                                                ["y"] = 103886.05235455,
                                                ["x"] = 186106.42075602,
                                            }, -- end of [198]
                                            [396] = 
                                            {
                                                ["y"] = 102275.6223729,
                                                ["x"] = 183541.62409728,
                                            }, -- end of [396]
                                            [397] = 
                                            {
                                                ["y"] = 102272.35401323,
                                                ["x"] = 183551.07397007,
                                            }, -- end of [397]
                                            [199] = 
                                            {
                                                ["y"] = 103880.52783268,
                                                ["x"] = 186098.08895938,
                                            }, -- end of [199]
                                            [398] = 
                                            {
                                                ["y"] = 102270.07225377,
                                                ["x"] = 183555.50356829,
                                            }, -- end of [398]
                                            [25] = 
                                            {
                                                ["y"] = 104994.39085293,
                                                ["x"] = 189073.49415537,
                                            }, -- end of [25]
                                            [50] = 
                                            {
                                                ["y"] = 105060.48002069,
                                                ["x"] = 188323.33577049,
                                            }, -- end of [50]
                                            [100] = 
                                            {
                                                ["y"] = 105013.52148588,
                                                ["x"] = 187539.87046074,
                                            }, -- end of [100]
                                            [200] = 
                                            {
                                                ["y"] = 103864.86212409,
                                                ["x"] = 186072.52735988,
                                            }, -- end of [200]
                                            [400] = 
                                            {
                                                ["y"] = 102250.04141042,
                                                ["x"] = 183570.35560235,
                                            }, -- end of [400]
                                            [401] = 
                                            {
                                                ["y"] = 102245.41987663,
                                                ["x"] = 183572.2553635,
                                            }, -- end of [401]
                                            [201] = 
                                            {
                                                ["y"] = 103861.9735031,
                                                ["x"] = 186068.45713504,
                                            }, -- end of [201]
                                            [402] = 
                                            {
                                                ["y"] = 102226.3775104,
                                                ["x"] = 183578.35584269,
                                            }, -- end of [402]
                                            [403] = 
                                            {
                                                ["y"] = 102221.55545587,
                                                ["x"] = 183579.67340262,
                                            }, -- end of [403]
                                            [101] = 
                                            {
                                                ["y"] = 105017.36695878,
                                                ["x"] = 187536.67514328,
                                            }, -- end of [101]
                                            [202] = 
                                            {
                                                ["y"] = 103808.26901892,
                                                ["x"] = 185972.48023627,
                                            }, -- end of [202]
                                            [404] = 
                                            {
                                                ["y"] = 102211.89239783,
                                                ["x"] = 183582.245051,
                                            }, -- end of [404]
                                            [405] = 
                                            {
                                                ["y"] = 102206.99587366,
                                                ["x"] = 183583.25048195,
                                            }, -- end of [405]
                                            [203] = 
                                            {
                                                ["y"] = 103802.38924725,
                                                ["x"] = 185964.39451296,
                                            }, -- end of [203]
                                            [406] = 
                                            {
                                                ["y"] = 102202.02517411,
                                                ["x"] = 183583.77328139,
                                            }, -- end of [406]
                                            [407] = 
                                            {
                                                ["y"] = 102192.03177422,
                                                ["x"] = 183584.09820456,
                                            }, -- end of [407]
                                            [51] = 
                                            {
                                                ["y"] = 105063.66543975,
                                                ["x"] = 188313.85994894,
                                            }, -- end of [51]
                                            [102] = 
                                            {
                                                ["y"] = 105020.95682403,
                                                ["x"] = 187533.19610581,
                                            }, -- end of [102]
                                            [204] = 
                                            {
                                                ["y"] = 103718.85531054,
                                                ["x"] = 185858.36838314,
                                            }, -- end of [204]
                                            [408] = 
                                            {
                                                ["y"] = 102122.04621573,
                                                ["x"] = 183583.34417272,
                                            }, -- end of [408]
                                            [409] = 
                                            {
                                                ["y"] = 102117.17541523,
                                                ["x"] = 183584.41440135,
                                            }, -- end of [409]
                                            [205] = 
                                            {
                                                ["y"] = 103715.34094121,
                                                ["x"] = 185854.81663141,
                                            }, -- end of [205]
                                            [410] = 
                                            {
                                                ["y"] = 102112.67613233,
                                                ["x"] = 183586.57555622,
                                            }, -- end of [410]
                                            [411] = 
                                            {
                                                ["y"] = 102108.52442545,
                                                ["x"] = 183589.35825448,
                                            }, -- end of [411]
                                            [103] = 
                                            {
                                                ["y"] = 105055.37156298,
                                                ["x"] = 187496.94067837,
                                            }, -- end of [103]
                                            [206] = 
                                            {
                                                ["y"] = 103708.32423484,
                                                ["x"] = 185847.70078633,
                                            }, -- end of [206]
                                            [412] = 
                                            {
                                                ["y"] = 102088.19310978,
                                                ["x"] = 183603.89832245,
                                            }, -- end of [412]
                                            [413] = 
                                            {
                                                ["y"] = 102083.92526312,
                                                ["x"] = 183606.49797321,
                                            }, -- end of [413]
                                            [207] = 
                                            {
                                                ["y"] = 103685.71088258,
                                                ["x"] = 185820.99416015,
                                            }, -- end of [207]
                                            [414] = 
                                            {
                                                ["y"] = 102079.36986771,
                                                ["x"] = 183608.54220196,
                                            }, -- end of [414]
                                            [13] = 
                                            {
                                                ["y"] = 104903.10285698,
                                                ["x"] = 189254.66493091,
                                            }, -- end of [13]
                                            [26] = 
                                            {
                                                ["y"] = 104995.54712458,
                                                ["x"] = 189068.63033976,
                                            }, -- end of [26]
                                            [52] = 
                                            {
                                                ["y"] = 105066.11266413,
                                                ["x"] = 188304.1658559,
                                            }, -- end of [52]
                                            [104] = 
                                            {
                                                ["y"] = 105068.22873675,
                                                ["x"] = 187481.62711637,
                                            }, -- end of [104]
                                            [208] = 
                                            {
                                                ["y"] = 103679.90303282,
                                                ["x"] = 185812.85606088,
                                            }, -- end of [208]
                                            [416] = 
                                            {
                                                ["y"] = 102070.45922536,
                                                ["x"] = 183605.30249744,
                                            }, -- end of [416]
                                            [417] = 
                                            {
                                                ["y"] = 102068.06261814,
                                                ["x"] = 183600.92959132,
                                            }, -- end of [417]
                                            [209] = 
                                            {
                                                ["y"] = 103637.00685593,
                                                ["x"] = 185745.36655059,
                                            }, -- end of [209]
                                            [418] = 
                                            {
                                                ["y"] = 102066.48274837,
                                                ["x"] = 183596.19483293,
                                            }, -- end of [418]
                                            [419] = 
                                            {
                                                ["y"] = 102066.10939193,
                                                ["x"] = 183591.22309674,
                                            }, -- end of [419]
                                            [105] = 
                                            {
                                                ["y"] = 105070.79842798,
                                                ["x"] = 187477.34093832,
                                            }, -- end of [105]
                                            [210] = 
                                            {
                                                ["y"] = 103630.42474298,
                                                ["x"] = 185737.8417261,
                                            }, -- end of [210]
                                            [420] = 
                                            {
                                                ["y"] = 102067.72314318,
                                                ["x"] = 183586.55393355,
                                            }, -- end of [420]
                                            [421] = 
                                            {
                                                ["y"] = 102071.12951154,
                                                ["x"] = 183582.93467766,
                                            }, -- end of [421]
                                            [211] = 
                                            {
                                                ["y"] = 103623.28359032,
                                                ["x"] = 185730.84483432,
                                            }, -- end of [211]
                                            [422] = 
                                            {
                                                ["y"] = 102085.9939936,
                                                ["x"] = 183569.5294805,
                                            }, -- end of [422]
                                            [423] = 
                                            {
                                                ["y"] = 102088.84481744,
                                                ["x"] = 183565.45236936,
                                            }, -- end of [423]
                                            [53] = 
                                            {
                                                ["y"] = 105066.96532131,
                                                ["x"] = 188299.24115972,
                                            }, -- end of [53]
                                            [106] = 
                                            {
                                                ["y"] = 105091.30984205,
                                                ["x"] = 187437.29089077,
                                            }, -- end of [106]
                                            [212] = 
                                            {
                                                ["y"] = 103615.60656528,
                                                ["x"] = 185724.44145659,
                                            }, -- end of [212]
                                            [424] = 
                                            {
                                                ["y"] = 102091.05592198,
                                                ["x"] = 183560.97731807,
                                            }, -- end of [424]
                                            [425] = 
                                            {
                                                ["y"] = 102100.58119683,
                                                ["x"] = 183537.85803982,
                                            }, -- end of [425]
                                            [213] = 
                                            {
                                                ["y"] = 103611.56102746,
                                                ["x"] = 185721.50401135,
                                            }, -- end of [213]
                                            [426] = 
                                            {
                                                ["y"] = 102105.36538114,
                                                ["x"] = 183523.64284203,
                                            }, -- end of [426]
                                            [427] = 
                                            {
                                                ["y"] = 102115.3168486,
                                                ["x"] = 183490.0921169,
                                            }, -- end of [427]
                                            [107] = 
                                            {
                                                ["y"] = 105093.16232652,
                                                ["x"] = 187432.64896905,
                                            }, -- end of [107]
                                            [214] = 
                                            {
                                                ["y"] = 103607.37376696,
                                                ["x"] = 185718.77239838,
                                            }, -- end of [214]
                                            [428] = 
                                            {
                                                ["y"] = 102117.39817498,
                                                ["x"] = 183480.31242391,
                                            }, -- end of [428]
                                            [429] = 
                                            {
                                                ["y"] = 102118.79437568,
                                                ["x"] = 183470.4136125,
                                            }, -- end of [429]
                                            [215] = 
                                            {
                                                ["y"] = 103603.04371485,
                                                ["x"] = 185716.27372508,
                                            }, -- end of [215]
                                            [430] = 
                                            {
                                                ["y"] = 102119.90638884,
                                                ["x"] = 183455.45639149,
                                            }, -- end of [430]
                                            [27] = 
                                            {
                                                ["y"] = 104996.455687,
                                                ["x"] = 189063.71413003,
                                            }, -- end of [27]
                                            [54] = 
                                            {
                                                ["y"] = 105067.49789046,
                                                ["x"] = 188294.27105771,
                                            }, -- end of [54]
                                            [108] = 
                                            {
                                                ["y"] = 105094.6826024,
                                                ["x"] = 187427.88602626,
                                            }, -- end of [108]
                                            [216] = 
                                            {
                                                ["y"] = 103598.57962125,
                                                ["x"] = 185714.02314569,
                                            }, -- end of [216]
                                            [432] = 
                                            {
                                                ["y"] = 102129.25466735,
                                                ["x"] = 183280.81426237,
                                            }, -- end of [432]
                                            [433] = 
                                            {
                                                ["y"] = 102172.16591417,
                                                ["x"] = 183009.19736596,
                                            }, -- end of [433]
                                            [217] = 
                                            {
                                                ["y"] = 103594.00029965,
                                                ["x"] = 185712.01705604,
                                            }, -- end of [217]
                                            [434] = 
                                            {
                                                ["y"] = 102174.14400323,
                                                ["x"] = 182984.27808259,
                                            }, -- end of [434]
                                            [435] = 
                                            {
                                                ["y"] = 102175.0991618,
                                                ["x"] = 182959.29899133,
                                            }, -- end of [435]
                                            [109] = 
                                            {
                                                ["y"] = 105109.9824173,
                                                ["x"] = 187369.87124126,
                                            }, -- end of [109]
                                            [218] = 
                                            {
                                                ["y"] = 103584.58528861,
                                                ["x"] = 185708.65609491,
                                            }, -- end of [218]
                                            [436] = 
                                            {
                                                ["y"] = 102174.1006102,
                                                ["x"] = 182924.3158526,
                                            }, -- end of [436]
                                            [437] = 
                                            {
                                                ["y"] = 102173.40207851,
                                                ["x"] = 182914.34234643,
                                            }, -- end of [437]
                                            [219] = 
                                            {
                                                ["y"] = 103574.92634711,
                                                ["x"] = 185706.07726595,
                                            }, -- end of [219]
                                            [438] = 
                                            {
                                                ["y"] = 102171.95062752,
                                                ["x"] = 182904.45058852,
                                            }, -- end of [438]
                                            [439] = 
                                            {
                                                ["y"] = 102165.79807853,
                                                ["x"] = 182875.09255838,
                                            }, -- end of [439]
                                            [55] = 
                                            {
                                                ["y"] = 105067.73124091,
                                                ["x"] = 188289.27654926,
                                            }, -- end of [55]
                                            [110] = 
                                            {
                                                ["y"] = 105113.05444489,
                                                ["x"] = 187355.19222697,
                                            }, -- end of [110]
                                            [220] = 
                                            {
                                                ["y"] = 103565.07830571,
                                                ["x"] = 185704.36374522,
                                            }, -- end of [220]
                                            [440] = 
                                            {
                                                ["y"] = 102162.83209185,
                                                ["x"] = 182865.5452945,
                                            }, -- end of [440]
                                            [441] = 
                                            {
                                                ["y"] = 102139.18318534,
                                                ["x"] = 182799.66571564,
                                            }, -- end of [441]
                                            [221] = 
                                            {
                                                ["y"] = 103560.10203095,
                                                ["x"] = 185703.8837073,
                                            }, -- end of [221]
                                            [442] = 
                                            {
                                                ["y"] = 102133.31716959,
                                                ["x"] = 182785.86096558,
                                            }, -- end of [442]
                                            [443] = 
                                            {
                                                ["y"] = 102128.93876187,
                                                ["x"] = 182776.87285586,
                                            }, -- end of [443]
                                            [111] = 
                                            {
                                                ["y"] = 105114.26186493,
                                                ["x"] = 187345.26990486,
                                            }, -- end of [111]
                                            [222] = 
                                            {
                                                ["y"] = 103550.10844686,
                                                ["x"] = 185703.6244383,
                                            }, -- end of [222]
                                            [444] = 
                                            {
                                                ["y"] = 102123.98323872,
                                                ["x"] = 182768.19090251,
                                            }, -- end of [444]
                                            [445] = 
                                            {
                                                ["y"] = 102118.45124305,
                                                ["x"] = 182759.86100361,
                                            }, -- end of [445]
                                            [223] = 
                                            {
                                                ["y"] = 103540.11796987,
                                                ["x"] = 185704.03768268,
                                            }, -- end of [223]
                                            [446] = 
                                            {
                                                ["y"] = 102085.03797712,
                                                ["x"] = 182716.17635591,
                                            }, -- end of [446]
                                            [7] = 
                                            {
                                                ["y"] = 104879.62302173,
                                                ["x"] = 189361.8826032,
                                            }, -- end of [7]
                                            [14] = 
                                            {
                                                ["y"] = 104915.91630417,
                                                ["x"] = 189216.77666904,
                                            }, -- end of [14]
                                            [28] = 
                                            {
                                                ["y"] = 104997.10822576,
                                                ["x"] = 189058.75768381,
                                            }, -- end of [28]
                                            [56] = 
                                            {
                                                ["y"] = 105067.68341816,
                                                ["x"] = 188284.27783254,
                                            }, -- end of [56]
                                            [112] = 
                                            {
                                                ["y"] = 105114.42423357,
                                                ["x"] = 187340.27340219,
                                            }, -- end of [112]
                                            [224] = 
                                            {
                                                ["y"] = 103520.21110939,
                                                ["x"] = 185705.94101983,
                                            }, -- end of [224]
                                            [448] = 
                                            {
                                                ["y"] = 102075.30546742,
                                                ["x"] = 182704.77571918,
                                            }, -- end of [448]
                                            [449] = 
                                            {
                                                ["y"] = 101995.23476555,
                                                ["x"] = 182622.26664979,
                                            }, -- end of [449]
                                            [225] = 
                                            {
                                                ["y"] = 103460.60978335,
                                                ["x"] = 185712.73795719,
                                            }, -- end of [225]
                                            [450] = 
                                            {
                                                ["y"] = 101986.55853863,
                                                ["x"] = 182610.02938298,
                                            }, -- end of [450]
                                            [451] = 
                                            {
                                                ["y"] = 101983.89033229,
                                                ["x"] = 182605.80168821,
                                            }, -- end of [451]
                                            [113] = 
                                            {
                                                ["y"] = 105114.2267261,
                                                ["x"] = 187335.27975881,
                                            }, -- end of [113]
                                            [226] = 
                                            {
                                                ["y"] = 103455.61073048,
                                                ["x"] = 185712.7967774,
                                            }, -- end of [226]
                                            [452] = 
                                            {
                                                ["y"] = 101981.50388652,
                                                ["x"] = 182601.41059745,
                                            }, -- end of [452]
                                            [453] = 
                                            {
                                                ["y"] = 101977.26635252,
                                                ["x"] = 182592.35477538,
                                            }, -- end of [453]
                                            [227] = 
                                            {
                                                ["y"] = 103450.61789477,
                                                ["x"] = 185712.55069623,
                                            }, -- end of [227]
                                            [454] = 
                                            {
                                                ["y"] = 101964.30820102,
                                                ["x"] = 182559.84477372,
                                            }, -- end of [454]
                                            [455] = 
                                            {
                                                ["y"] = 101952.37513745,
                                                ["x"] = 182526.94642647,
                                            }, -- end of [455]
                                            [57] = 
                                            {
                                                ["y"] = 105066.91154034,
                                                ["x"] = 188274.30951593,
                                            }, -- end of [57]
                                            [114] = 
                                            {
                                                ["y"] = 105113.70435402,
                                                ["x"] = 187330.30628889,
                                            }, -- end of [114]
                                            [228] = 
                                            {
                                                ["y"] = 103445.65631179,
                                                ["x"] = 185711.94171662,
                                            }, -- end of [228]
                                            [456] = 
                                            {
                                                ["y"] = 101945.38168261,
                                                ["x"] = 182502.94726267,
                                            }, -- end of [456]
                                            [457] = 
                                            {
                                                ["y"] = 101808.87461961,
                                                ["x"] = 182016.7806696,
                                            }, -- end of [457]
                                            [229] = 
                                            {
                                                ["y"] = 103440.75429961,
                                                ["x"] = 185710.96084332,
                                            }, -- end of [229]
                                            [458] = 
                                            {
                                                ["y"] = 101801.57817646,
                                                ["x"] = 181977.46343101,
                                            }, -- end of [458]
                                            [459] = 
                                            {
                                                ["y"] = 101800.84610481,
                                                ["x"] = 181967.49418603,
                                            }, -- end of [459]
                                            [115] = 
                                            {
                                                ["y"] = 105112.07374705,
                                                ["x"] = 187320.44207726,
                                            }, -- end of [115]
                                            [230] = 
                                            {
                                                ["y"] = 103435.94962844,
                                                ["x"] = 185709.58405307,
                                            }, -- end of [230]
                                            [460] = 
                                            {
                                                ["y"] = 101796.24763662,
                                                ["x"] = 181917.71182311,
                                            }, -- end of [460]
                                            [461] = 
                                            {
                                                ["y"] = 101795.24181195,
                                                ["x"] = 181902.75148939,
                                            }, -- end of [461]
                                            [231] = 
                                            {
                                                ["y"] = 103431.29435617,
                                                ["x"] = 185707.7639733,
                                            }, -- end of [231]
                                            [462] = 
                                            {
                                                ["y"] = 101793.73722599,
                                                ["x"] = 181892.86568717,
                                            }, -- end of [462]
                                            [29] = 
                                            {
                                                ["y"] = 104997.83943877,
                                                ["x"] = 189048.78544928,
                                            }, -- end of [29]
                                            [58] = 
                                            {
                                                ["y"] = 105066.14857573,
                                                ["x"] = 188269.36960229,
                                            }, -- end of [58]
                                            [116] = 
                                            {
                                                ["y"] = 105109.7516145,
                                                ["x"] = 187310.71785089,
                                            }, -- end of [116]
                                            [232] = 
                                            {
                                                ["y"] = 103426.86031894,
                                                ["x"] = 185705.46048299,
                                            }, -- end of [232]
                                            [464] = 
                                            {
                                                ["y"] = 101746.18122411,
                                                ["x"] = 181591.75026274,
                                            }, -- end of [464]
                                            [465] = 
                                            {
                                                ["y"] = 101745.87231043,
                                                ["x"] = 181581.75619011,
                                            }, -- end of [465]
                                            [233] = 
                                            {
                                                ["y"] = 103422.70483093,
                                                ["x"] = 185702.68422293,
                                            }, -- end of [233]
                                            [466] = 
                                            {
                                                ["y"] = 101746.14885973,
                                                ["x"] = 181571.76133087,
                                            }, -- end of [466]
                                            [467] = 
                                            {
                                                ["y"] = 101747.44786543,
                                                ["x"] = 181556.81918139,
                                            }, -- end of [467]
                                            [117] = 
                                            {
                                                ["y"] = 105102.34862084,
                                                ["x"] = 187286.84112941,
                                            }, -- end of [117]
                                            [234] = 
                                            {
                                                ["y"] = 103418.82876171,
                                                ["x"] = 185699.52799644,
                                            }, -- end of [234]
                                            [468] = 
                                            {
                                                ["y"] = 101749.11055641,
                                                ["x"] = 181546.96330456,
                                            }, -- end of [468]
                                            [469] = 
                                            {
                                                ["y"] = 101750.38098769,
                                                ["x"] = 181542.12850915,
                                            }, -- end of [469]
                                            [235] = 
                                            {
                                                ["y"] = 103415.2060991,
                                                ["x"] = 185696.08297778,
                                            }, -- end of [235]
                                            [470] = 
                                            {
                                                ["y"] = 101751.96131005,
                                                ["x"] = 181537.38629689,
                                            }, -- end of [470]
                                            [471] = 
                                            {
                                                ["y"] = 101755.80722028,
                                                ["x"] = 181528.15821445,
                                            }, -- end of [471]
                                            [59] = 
                                            {
                                                ["y"] = 105064.90381953,
                                                ["x"] = 188264.52891356,
                                            }, -- end of [59]
                                            [118] = 
                                            {
                                                ["y"] = 105098.90779832,
                                                ["x"] = 187277.45324329,
                                            }, -- end of [118]
                                            [236] = 
                                            {
                                                ["y"] = 103411.79977737,
                                                ["x"] = 185692.42344428,
                                            }, -- end of [236]
                                            [472] = 
                                            {
                                                ["y"] = 101769.21620021,
                                                ["x"] = 181501.32361578,
                                            }, -- end of [472]
                                            [473] = 
                                            {
                                                ["y"] = 101778.82925726,
                                                ["x"] = 181483.78913624,
                                            }, -- end of [473]
                                            [237] = 
                                            {
                                                ["y"] = 103408.59887448,
                                                ["x"] = 185688.58316132,
                                            }, -- end of [237]
                                            [474] = 
                                            {
                                                ["y"] = 101804.37294394,
                                                ["x"] = 181440.81022354,
                                            }, -- end of [474]
                                            [475] = 
                                            {
                                                ["y"] = 101806.51254483,
                                                ["x"] = 181436.29193383,
                                            }, -- end of [475]
                                            [119] = 
                                            {
                                                ["y"] = 105096.79945682,
                                                ["x"] = 187272.92204141,
                                            }, -- end of [119]
                                            [238] = 
                                            {
                                                ["y"] = 103405.61518906,
                                                ["x"] = 185684.57168701,
                                            }, -- end of [238]
                                            [476] = 
                                            {
                                                ["y"] = 101808.3461527,
                                                ["x"] = 181431.64167806,
                                            }, -- end of [476]
                                            [477] = 
                                            {
                                                ["y"] = 101809.91541897,
                                                ["x"] = 181426.89490564,
                                            }, -- end of [477]
                                            [239] = 
                                            {
                                                ["y"] = 103402.86961982,
                                                ["x"] = 185680.39396567,
                                            }, -- end of [239]
                                            [478] = 
                                            {
                                                ["y"] = 101812.46073587,
                                                ["x"] = 181417.22644096,
                                            }, -- end of [478]
                                            [15] = 
                                            {
                                                ["y"] = 104919.76419921,
                                                ["x"] = 189207.54903514,
                                            }, -- end of [15]
                                            [30] = 
                                            {
                                                ["y"] = 104999.48205026,
                                                ["x"] = 189008.82500052,
                                            }, -- end of [30]
                                            [60] = 
                                            {
                                                ["y"] = 105063.23278903,
                                                ["x"] = 188259.81815873,
                                            }, -- end of [60]
                                            [120] = 
                                            {
                                                ["y"] = 105094.30098032,
                                                ["x"] = 187268.59338954,
                                            }, -- end of [120]
                                            [240] = 
                                            {
                                                ["y"] = 103400.38444739,
                                                ["x"] = 185676.0564728,
                                            }, -- end of [240]
                                            [480] = 
                                            {
                                                ["y"] = 101815.52468049,
                                                ["x"] = 181397.47885788,
                                            }, -- end of [480]
                                            [481] = 
                                            {
                                                ["y"] = 101815.97578354,
                                                ["x"] = 181387.49125534,
                                            }, -- end of [481]
                                            [241] = 
                                            {
                                                ["y"] = 103398.14068152,
                                                ["x"] = 185671.58847921,
                                            }, -- end of [241]
                                            [482] = 
                                            {
                                                ["y"] = 101815.72383191,
                                                ["x"] = 181377.49657793,
                                            }, -- end of [482]
                                            [483] = 
                                            {
                                                ["y"] = 101814.44105314,
                                                ["x"] = 181362.55317683,
                                            }, -- end of [483]
                                            [121] = 
                                            {
                                                ["y"] = 105091.44631056,
                                                ["x"] = 187264.49031703,
                                            }, -- end of [121]
                                            [242] = 
                                            {
                                                ["y"] = 103394.26017504,
                                                ["x"] = 185662.37464405,
                                            }, -- end of [242]
                                            [484] = 
                                            {
                                                ["y"] = 101811.79598172,
                                                ["x"] = 181342.73061668,
                                            }, -- end of [484]
                                            [485] = 
                                            {
                                                ["y"] = 101809.88326952,
                                                ["x"] = 181332.91664458,
                                            }, -- end of [485]
                                            [243] = 
                                            {
                                                ["y"] = 103348.57589412,
                                                ["x"] = 185540.68642777,
                                            }, -- end of [243]
                                            [486] = 
                                            {
                                                ["y"] = 101807.35744327,
                                                ["x"] = 181323.2427746,
                                            }, -- end of [486]
                                            [487] = 
                                            {
                                                ["y"] = 101804.26716738,
                                                ["x"] = 181313.7335954,
                                            }, -- end of [487]
                                            [61] = 
                                            {
                                                ["y"] = 105061.25494684,
                                                ["x"] = 188255.22707932,
                                            }, -- end of [61]
                                            [122] = 
                                            {
                                                ["y"] = 105088.04356085,
                                                ["x"] = 187260.83480516,
                                            }, -- end of [122]
                                            [244] = 
                                            {
                                                ["y"] = 103341.99587887,
                                                ["x"] = 185527.20854368,
                                            }, -- end of [244]
                                            [488] = 
                                            {
                                                ["y"] = 101800.62836693,
                                                ["x"] = 181304.42020201,
                                            }, -- end of [488]
                                            [489] = 
                                            {
                                                ["y"] = 101796.3536352,
                                                ["x"] = 181295.38356888,
                                            }, -- end of [489]
                                            [245] = 
                                            {
                                                ["y"] = 103334.6465195,
                                                ["x"] = 185514.1355046,
                                            }, -- end of [245]
                                            [490] = 
                                            {
                                                ["y"] = 101791.2989327,
                                                ["x"] = 181286.76026084,
                                            }, -- end of [490]
                                            [491] = 
                                            {
                                                ["y"] = 101785.51788721,
                                                ["x"] = 181278.60336379,
                                            }, -- end of [491]
                                            [123] = 
                                            {
                                                ["y"] = 105084.15187401,
                                                ["x"] = 187257.70100318,
                                            }, -- end of [123]
                                            [246] = 
                                            {
                                                ["y"] = 103329.26144624,
                                                ["x"] = 185505.7101599,
                                            }, -- end of [246]
                                            [492] = 
                                            {
                                                ["y"] = 101779.13120025,
                                                ["x"] = 181270.91079203,
                                            }, -- end of [492]
                                            [493] = 
                                            {
                                                ["y"] = 101772.21265165,
                                                ["x"] = 181263.69365901,
                                            }, -- end of [493]
                                            [247] = 
                                            {
                                                ["y"] = 103326.29309639,
                                                ["x"] = 185501.68811559,
                                            }, -- end of [247]
                                            [494] = 
                                            {
                                                ["y"] = 101746.38347431,
                                                ["x"] = 181240.07771203,
                                            }, -- end of [494]
                                            [31] = 
                                            {
                                                ["y"] = 104998.91122354,
                                                ["x"] = 188993.83870292,
                                            }, -- end of [31]
                                            [62] = 
                                            {
                                                ["y"] = 105054.5757208,
                                                ["x"] = 188241.79744495,
                                            }, -- end of [62]
                                            [124] = 
                                            {
                                                ["y"] = 105079.94801333,
                                                ["x"] = 187254.99663301,
                                            }, -- end of [124]
                                            [248] = 
                                            {
                                                ["y"] = 103323.06348918,
                                                ["x"] = 185497.87166011,
                                            }, -- end of [248]
                                            [496] = 
                                            {
                                                ["y"] = 101738.00294134,
                                                ["x"] = 181234.64106296,
                                            }, -- end of [496]
                                            [497] = 
                                            {
                                                ["y"] = 101724.70713845,
                                                ["x"] = 181227.70132526,
                                            }, -- end of [497]
                                            [249] = 
                                            {
                                                ["y"] = 103319.58362183,
                                                ["x"] = 185494.28308084,
                                            }, -- end of [249]
                                            [498] = 
                                            {
                                                ["y"] = 101706.52239314,
                                                ["x"] = 181219.38081785,
                                            }, -- end of [498]
                                            [499] = 
                                            {
                                                ["y"] = 101692.58513796,
                                                ["x"] = 181213.8408745,
                                            }, -- end of [499]
                                            [125] = 
                                            {
                                                ["y"] = 105075.56220094,
                                                ["x"] = 187252.59734192,
                                            }, -- end of [125]
                                            [250] = 
                                            {
                                                ["y"] = 103315.86938473,
                                                ["x"] = 185490.93806239,
                                            }, -- end of [250]
                                            [500] = 
                                            {
                                                ["y"] = 101668.89794362,
                                                ["x"] = 181205.85400479,
                                            }, -- end of [500]
                                            [501] = 
                                            {
                                                ["y"] = 101621.13647368,
                                                ["x"] = 181191.10971313,
                                            }, -- end of [501]
                                            [251] = 
                                            {
                                                ["y"] = 103307.97911964,
                                                ["x"] = 185484.79730654,
                                            }, -- end of [251]
                                            [502] = 
                                            {
                                                ["y"] = 101577.5997515,
                                                ["x"] = 181179.74224156,
                                            }, -- end of [502]
                                            [255] = 
                                            {
                                                ["y"] = 103265.67733409,
                                                ["x"] = 185458.42463929,
                                            }, -- end of [255]
                                            [271] = 
                                            {
                                                ["y"] = 103167.92469333,
                                                ["x"] = 185372.65345978,
                                            }, -- end of [271]
                                            [287] = 
                                            {
                                                ["y"] = 103224.58679309,
                                                ["x"] = 185136.86261979,
                                            }, -- end of [287]
                                            [503] = 
                                            {
                                                ["y"] = 101563.3902192,
                                                ["x"] = 181174.95321709,
                                            }, -- end of [503]
                                            [63] = 
                                            {
                                                ["y"] = 105042.60968216,
                                                ["x"] = 188219.85330147,
                                            }, -- end of [63]
                                            [126] = 
                                            {
                                                ["y"] = 105043.85218085,
                                                ["x"] = 187237.78684939,
                                            }, -- end of [126]
                                            [252] = 
                                            {
                                                ["y"] = 103279.12549507,
                                                ["x"] = 185464.99056826,
                                            }, -- end of [252]
                                            [504] = 
                                            {
                                                ["y"] = 101554.30255804,
                                                ["x"] = 181170.79002941,
                                            }, -- end of [504]
                                            [367] = 
                                            {
                                                ["y"] = 102754.69124926,
                                                ["x"] = 183634.85434238,
                                            }, -- end of [367]
                                            [319] = 
                                            {
                                                ["y"] = 103605.39407825,
                                                ["x"] = 184826.40478059,
                                            }, -- end of [319]
                                            [335] = 
                                            {
                                                ["y"] = 103614.52142241,
                                                ["x"] = 184632.46715297,
                                            }, -- end of [335]
                                            [505] = 
                                            {
                                                ["y"] = 101549.93969694,
                                                ["x"] = 181168.3491099,
                                            }, -- end of [505]
                                            [351] = 
                                            {
                                                ["y"] = 103325.36786452,
                                                ["x"] = 184383.23958056,
                                            }, -- end of [351]
                                            [479] = 
                                            {
                                                ["y"] = 101814.33615736,
                                                ["x"] = 181407.4056309,
                                            }, -- end of [479]
                                            [253] = 
                                            {
                                                ["y"] = 103274.81861771,
                                                ["x"] = 185462.45142901,
                                            }, -- end of [253]
                                            [506] = 
                                            {
                                                ["y"] = 101545.70583849,
                                                ["x"] = 181165.68991886,
                                            }, -- end of [506]
                                            [447] = 
                                            {
                                                ["y"] = 102078.70851189,
                                                ["x"] = 182708.43725605,
                                            }, -- end of [447]
                                            [431] = 
                                            {
                                                ["y"] = 102126.48681776,
                                                ["x"] = 183300.61904396,
                                            }, -- end of [431]
                                            [383] = 
                                            {
                                                ["y"] = 102235.62270398,
                                                ["x"] = 183432.5455041,
                                            }, -- end of [383]
                                            [507] = 
                                            {
                                                ["y"] = 101537.61100465,
                                                ["x"] = 181159.82222859,
                                            }, -- end of [507]
                                            [415] = 
                                            {
                                                ["y"] = 102074.50184,
                                                ["x"] = 183608.19100734,
                                            }, -- end of [415]
                                            [127] = 
                                            {
                                                ["y"] = 105029.97445333,
                                                ["x"] = 187232.10389741,
                                            }, -- end of [127]
                                            [254] = 
                                            {
                                                ["y"] = 103270.32904275,
                                                ["x"] = 185460.25632592,
                                            }, -- end of [254]
                                            [508] = 
                                            {
                                                ["y"] = 101514.24451081,
                                                ["x"] = 181141.01117376,
                                            }, -- end of [508]
                                            [495] = 
                                            {
                                                ["y"] = 101742.29538199,
                                                ["x"] = 181237.2041875,
                                            }, -- end of [495]
                                            [463] = 
                                            {
                                                ["y"] = 101749.85151264,
                                                ["x"] = 181636.59885713,
                                            }, -- end of [463]
                                            [399] = 
                                            {
                                                ["y"] = 102266.33648675,
                                                ["x"] = 183558.79830947,
                                            }, -- end of [399]
                                            [509] = 
                                            {
                                                ["y"] = 101510.7810981,
                                                ["x"] = 181137.40928939,
                                            }, -- end of [509]
                                            [303] = 
                                            {
                                                ["y"] = 103378.0844252,
                                                ["x"] = 184935.7332463,
                                            }, -- end of [303]
                                            [510] = 
                                            {
                                                ["y"] = 101507.61042901,
                                                ["x"] = 181133.54407875,
                                            }, -- end of [510]
                                            [511] = 
                                            {
                                                ["y"] = 101498.80851461,
                                                ["x"] = 181121.40010998,
                                            }, -- end of [511]
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            [1] = 
                                            {
                                                ["y"] = 98472.262463564,
                                                ["x"] = 184734.96370404,
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["y"] = 98472.262463564,
                                                ["x"] = 184734.96370404,
                                            }, -- end of [2]
                                        }, -- end of [2]
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 185,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 104820.77081702,
                                            ["x"] = 189415.41499635,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 63,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 4195.3150156188,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 101342.11765435,
                                            ["x"] = 180909.05313324,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 2.7777777777778,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 10,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 26,
                                        ["y"] = 104820.77081702,
                                        ["x"] = 189415.41499635,
                                        ["name"] = "Invaders One-1-1",
                                        ["heading"] = 2.1721586677857,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Gepard",
                                        ["unitId"] = 27,
                                        ["y"] = 104794.14188936,
                                        ["x"] = 189428.44769613,
                                        ["name"] = "Invaders One-1-2",
                                        ["heading"] = 2.025943259939,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR_D",
                                        ["unitId"] = 28,
                                        ["y"] = 104765.49412311,
                                        ["x"] = 189439.81194188,
                                        ["name"] = "Invaders One-1-3",
                                        ["heading"] = 1.9484448975703,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [3]
                                    [4] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "T-90",
                                        ["unitId"] = 29,
                                        ["y"] = 104732.92042059,
                                        ["x"] = 189449.54685039,
                                        ["name"] = "Invaders One-1-4",
                                        ["heading"] = 1.8612049992178,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [4]
                                    [5] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 30,
                                        ["y"] = 104703.8893262,
                                        ["x"] = 189455.96424092,
                                        ["name"] = "Invaders One-1-5",
                                        ["heading"] = 1.788350140956,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [5]
                                    [6] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 31,
                                        ["y"] = 104674.14912754,
                                        ["x"] = 189460.23776296,
                                        ["name"] = "Invaders One-1-6",
                                        ["heading"] = 1.7135145232905,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [6]
                                }, -- end of ["units"]
                                ["y"] = 104820.77081702,
                                ["x"] = 189415.41499635,
                                ["name"] = "Airfield Stormers",
                                ["start_time"] = 0,
                            }, -- end of [6]
                            [7] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                        [1] = 
                                        {
                                            [33] = 
                                            {
                                                ["y"] = 100319.12905107,
                                                ["x"] = 185419.92465411,
                                            }, -- end of [33]
                                            [35] = 
                                            {
                                                ["y"] = 100269.92613973,
                                                ["x"] = 185356.91877305,
                                            }, -- end of [35]
                                            [37] = 
                                            {
                                                ["y"] = 100254.89990794,
                                                ["x"] = 185343.72690564,
                                            }, -- end of [37]
                                            [39] = 
                                            {
                                                ["y"] = 100249.19668398,
                                                ["x"] = 185335.56591369,
                                            }, -- end of [39]
                                            [41] = 
                                            {
                                                ["y"] = 100248.74786628,
                                                ["x"] = 185325.82175012,
                                            }, -- end of [41]
                                            [43] = 
                                            {
                                                ["y"] = 100253.07618965,
                                                ["x"] = 185316.83297959,
                                            }, -- end of [43]
                                            [45] = 
                                            {
                                                ["y"] = 100265.04185775,
                                                ["x"] = 185300.80874183,
                                            }, -- end of [45]
                                            [47] = 
                                            {
                                                ["y"] = 100282.27904891,
                                                ["x"] = 185276.27156325,
                                            }, -- end of [47]
                                            [49] = 
                                            {
                                                ["y"] = 100320.80903972,
                                                ["x"] = 185211.94839728,
                                            }, -- end of [49]
                                            [51] = 
                                            {
                                                ["y"] = 100349.03466502,
                                                ["x"] = 185153.47035505,
                                            }, -- end of [51]
                                            [53] = 
                                            {
                                                ["y"] = 100554.89368587,
                                                ["x"] = 184687.16265574,
                                            }, -- end of [53]
                                            [55] = 
                                            {
                                                ["y"] = 100609.73813019,
                                                ["x"] = 184603.57437361,
                                            }, -- end of [55]
                                            [57] = 
                                            {
                                                ["y"] = 101136.89796417,
                                                ["x"] = 183924.12012448,
                                            }, -- end of [57]
                                            [59] = 
                                            {
                                                ["y"] = 101210.48611378,
                                                ["x"] = 183823.13261173,
                                            }, -- end of [59]
                                            [61] = 
                                            {
                                                ["y"] = 101217.68387243,
                                                ["x"] = 183816.20111343,
                                            }, -- end of [61]
                                            [63] = 
                                            {
                                                ["y"] = 101225.6323623,
                                                ["x"] = 183810.14084196,
                                            }, -- end of [63]
                                            [66] = 
                                            {
                                                ["y"] = 101238.7049785,
                                                ["x"] = 183802.83000524,
                                            }, -- end of [66]
                                            [70] = 
                                            {
                                                ["y"] = 101403.37509571,
                                                ["x"] = 183760.95105122,
                                            }, -- end of [70]
                                            [74] = 
                                            {
                                                ["y"] = 101529.65792741,
                                                ["x"] = 183731.50080097,
                                            }, -- end of [74]
                                            [78] = 
                                            {
                                                ["y"] = 101565.34478597,
                                                ["x"] = 183696.89282436,
                                            }, -- end of [78]
                                            [82] = 
                                            {
                                                ["y"] = 101747.73439884,
                                                ["x"] = 183393.49542336,
                                            }, -- end of [82]
                                            [86] = 
                                            {
                                                ["y"] = 101390.66535884,
                                                ["x"] = 182949.4754476,
                                            }, -- end of [86]
                                            [90] = 
                                            {
                                                ["y"] = 101150.15580161,
                                                ["x"] = 182668.41053779,
                                            }, -- end of [90]
                                            [94] = 
                                            {
                                                ["y"] = 101076.32496004,
                                                ["x"] = 182538.55342394,
                                            }, -- end of [94]
                                            [98] = 
                                            {
                                                ["y"] = 100973.66211357,
                                                ["x"] = 182158.27864585,
                                            }, -- end of [98]
                                            [102] = 
                                            {
                                                ["y"] = 100996.71779733,
                                                ["x"] = 182132.0874179,
                                            }, -- end of [102]
                                            [106] = 
                                            {
                                                ["y"] = 101106.46191507,
                                                ["x"] = 181983.30543311,
                                            }, -- end of [106]
                                            [110] = 
                                            {
                                                ["y"] = 101167.36000049,
                                                ["x"] = 181883.96596083,
                                            }, -- end of [110]
                                            [114] = 
                                            {
                                                ["y"] = 100995.38357271,
                                                ["x"] = 181755.03418668,
                                            }, -- end of [114]
                                            [118] = 
                                            {
                                                ["y"] = 100973.15152566,
                                                ["x"] = 181728.14685178,
                                            }, -- end of [118]
                                            [122] = 
                                            {
                                                ["y"] = 100975.87847009,
                                                ["x"] = 181708.96927622,
                                            }, -- end of [122]
                                            [126] = 
                                            {
                                                ["y"] = 101264.83575381,
                                                ["x"] = 181301.09844909,
                                            }, -- end of [126]
                                            [132] = 
                                            {
                                                ["y"] = 101364.92330878,
                                                ["x"] = 181135.24504268,
                                            }, -- end of [132]
                                            [140] = 
                                            {
                                                ["y"] = 101258.74078296,
                                                ["x"] = 181047.34212741,
                                            }, -- end of [140]
                                            [148] = 
                                            {
                                                ["y"] = 101126.21708636,
                                                ["x"] = 180750.85466591,
                                            }, -- end of [148]
                                            [156] = 
                                            {
                                                ["y"] = 101147.76878646,
                                                ["x"] = 180721.5189358,
                                            }, -- end of [156]
                                            [1] = 
                                            {
                                                ["y"] = 101063.22010437,
                                                ["x"] = 189896.42183867,
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["y"] = 101012.83637251,
                                                ["x"] = 189771.20473963,
                                            }, -- end of [2]
                                            [133] = 
                                            {
                                                ["y"] = 101322.60486243,
                                                ["x"] = 181108.65705504,
                                            }, -- end of [133]
                                            [141] = 
                                            {
                                                ["y"] = 101256.03519865,
                                                ["x"] = 181043.13853123,
                                            }, -- end of [141]
                                            [149] = 
                                            {
                                                ["y"] = 101125.45527253,
                                                ["x"] = 180745.97410385,
                                            }, -- end of [149]
                                            [157] = 
                                            {
                                                ["y"] = 101156.45316195,
                                                ["x"] = 180716.56398619,
                                            }, -- end of [157]
                                            [3] = 
                                            {
                                                ["y"] = 101006.60303278,
                                                ["x"] = 189752.20323002,
                                            }, -- end of [3]
                                            [4] = 
                                            {
                                                ["y"] = 100955.20163302,
                                                ["x"] = 189579.71152477,
                                            }, -- end of [4]
                                            [67] = 
                                            {
                                                ["y"] = 101243.34702098,
                                                ["x"] = 183800.97582871,
                                            }, -- end of [67]
                                            [71] = 
                                            {
                                                ["y"] = 101408.32706348,
                                                ["x"] = 183760.28185792,
                                            }, -- end of [71]
                                            [75] = 
                                            {
                                                ["y"] = 101533.67360414,
                                                ["x"] = 183728.5321035,
                                            }, -- end of [75]
                                            [5] = 
                                            {
                                                ["y"] = 100939.43602913,
                                                ["x"] = 189501.28836647,
                                            }, -- end of [5]
                                            [83] = 
                                            {
                                                ["y"] = 101533.25828435,
                                                ["x"] = 183116.94492869,
                                            }, -- end of [83]
                                            [87] = 
                                            {
                                                ["y"] = 101367.59318891,
                                                ["x"] = 182923.17008194,
                                            }, -- end of [87]
                                            [91] = 
                                            {
                                                ["y"] = 101100.46241864,
                                                ["x"] = 182593.3875003,
                                            }, -- end of [91]
                                            [6] = 
                                            {
                                                ["y"] = 100938.34127699,
                                                ["x"] = 189496.4138455,
                                            }, -- end of [6]
                                            [99] = 
                                            {
                                                ["y"] = 100976.49380622,
                                                ["x"] = 182154.16215009,
                                            }, -- end of [99]
                                            [103] = 
                                            {
                                                ["y"] = 101002.05049284,
                                                ["x"] = 182123.62941529,
                                            }, -- end of [103]
                                            [107] = 
                                            {
                                                ["y"] = 101114.26483549,
                                                ["x"] = 181970.50458133,
                                            }, -- end of [107]
                                            [7] = 
                                            {
                                                ["y"] = 100922.72840586,
                                                ["x"] = 189382.48329876,
                                            }, -- end of [7]
                                            [115] = 
                                            {
                                                ["y"] = 100991.80643774,
                                                ["x"] = 181751.54217673,
                                            }, -- end of [115]
                                            [119] = 
                                            {
                                                ["y"] = 100971.94406565,
                                                ["x"] = 181723.35193269,
                                            }, -- end of [119]
                                            [123] = 
                                            {
                                                ["y"] = 100978.16083356,
                                                ["x"] = 181704.52111596,
                                            }, -- end of [123]
                                            [8] = 
                                            {
                                                ["y"] = 100912.93433926,
                                                ["x"] = 189257.87710992,
                                            }, -- end of [8]
                                            [134] = 
                                            {
                                                ["y"] = 101304.84314369,
                                                ["x"] = 181099.47921482,
                                            }, -- end of [134]
                                            [9] = 
                                            {
                                                ["y"] = 100907.85530493,
                                                ["x"] = 188992.93497006,
                                            }, -- end of [9]
                                            [150] = 
                                            {
                                                ["y"] = 101126.60287673,
                                                ["x"] = 180741.11967056,
                                            }, -- end of [150]
                                            [10] = 
                                            {
                                                ["y"] = 100908.49627079,
                                                ["x"] = 188977.95296443,
                                            }, -- end of [10]
                                            [11] = 
                                            {
                                                ["y"] = 100908.04298876,
                                                ["x"] = 188932.96385865,
                                            }, -- end of [11]
                                            [12] = 
                                            {
                                                ["y"] = 100910.19992231,
                                                ["x"] = 188883.01904879,
                                            }, -- end of [12]
                                            [13] = 
                                            {
                                                ["y"] = 100909.88324019,
                                                ["x"] = 188858.02426885,
                                            }, -- end of [13]
                                            [14] = 
                                            {
                                                ["y"] = 100909.37804464,
                                                ["x"] = 188848.04202918,
                                            }, -- end of [14]
                                            [15] = 
                                            {
                                                ["y"] = 100906.02481876,
                                                ["x"] = 188558.0769348,
                                            }, -- end of [15]
                                            [16] = 
                                            {
                                                ["y"] = 100905.65909098,
                                                ["x"] = 188548.08554522,
                                            }, -- end of [16]
                                            [17] = 
                                            {
                                                ["y"] = 100906.34164344,
                                                ["x"] = 188358.13637767,
                                            }, -- end of [17]
                                            [18] = 
                                            {
                                                ["y"] = 100837.41837368,
                                                ["x"] = 187495.96831093,
                                            }, -- end of [18]
                                            [19] = 
                                            {
                                                ["y"] = 100819.71608038,
                                                ["x"] = 187316.85479766,
                                            }, -- end of [19]
                                            [20] = 
                                            {
                                                ["y"] = 100796.5374975,
                                                ["x"] = 187007.74487434,
                                            }, -- end of [20]
                                            [21] = 
                                            {
                                                ["y"] = 100782.65263955,
                                                ["x"] = 186898.63994563,
                                            }, -- end of [21]
                                            [22] = 
                                            {
                                                ["y"] = 100714.94750344,
                                                ["x"] = 186111.61800525,
                                            }, -- end of [22]
                                            [23] = 
                                            {
                                                ["y"] = 100714.94684437,
                                                ["x"] = 186106.62018399,
                                            }, -- end of [23]
                                            [24] = 
                                            {
                                                ["y"] = 100714.24496599,
                                                ["x"] = 186101.67114416,
                                            }, -- end of [24]
                                            [25] = 
                                            {
                                                ["y"] = 100702.21364883,
                                                ["x"] = 186037.81429931,
                                            }, -- end of [25]
                                            [26] = 
                                            {
                                                ["y"] = 100693.19035401,
                                                ["x"] = 186004.01051023,
                                            }, -- end of [26]
                                            [27] = 
                                            {
                                                ["y"] = 100686.52998029,
                                                ["x"] = 185985.1574501,
                                            }, -- end of [27]
                                            [28] = 
                                            {
                                                ["y"] = 100668.4238986,
                                                ["x"] = 185943.96371111,
                                            }, -- end of [28]
                                            [29] = 
                                            {
                                                ["y"] = 100661.57665559,
                                                ["x"] = 185930.62031089,
                                            }, -- end of [29]
                                            [30] = 
                                            {
                                                ["y"] = 100653.87852453,
                                                ["x"] = 185917.75043895,
                                            }, -- end of [30]
                                            [31] = 
                                            {
                                                ["y"] = 100328.42807803,
                                                ["x"] = 185431.69043246,
                                            }, -- end of [31]
                                            [32] = 
                                            {
                                                ["y"] = 100325.31217752,
                                                ["x"] = 185427.78162732,
                                            }, -- end of [32]
                                            [34] = 
                                            {
                                                ["y"] = 100276.76447724,
                                                ["x"] = 185364.21131813,
                                            }, -- end of [34]
                                            [36] = 
                                            {
                                                ["y"] = 100262.48855986,
                                                ["x"] = 185350.23857089,
                                            }, -- end of [36]
                                            [38] = 
                                            {
                                                ["y"] = 100251.65149028,
                                                ["x"] = 185339.92252385,
                                            }, -- end of [38]
                                            [40] = 
                                            {
                                                ["y"] = 100248.11770238,
                                                ["x"] = 185330.74075229,
                                            }, -- end of [40]
                                            [42] = 
                                            {
                                                ["y"] = 100250.54823848,
                                                ["x"] = 185321.1357118,
                                            }, -- end of [42]
                                            [44] = 
                                            {
                                                ["y"] = 100256.06440612,
                                                ["x"] = 185312.81865624,
                                            }, -- end of [44]
                                            [46] = 
                                            {
                                                ["y"] = 100279.30691355,
                                                ["x"] = 185280.28804949,
                                            }, -- end of [46]
                                            [48] = 
                                            {
                                                ["y"] = 100300.67633118,
                                                ["x"] = 185246.49764179,
                                            }, -- end of [48]
                                            [50] = 
                                            {
                                                ["y"] = 100347.31398298,
                                                ["x"] = 185158.14755501,
                                            }, -- end of [50]
                                            [52] = 
                                            {
                                                ["y"] = 100517.58938171,
                                                ["x"] = 184757.92737715,
                                            }, -- end of [52]
                                            [54] = 
                                            {
                                                ["y"] = 100581.56634331,
                                                ["x"] = 184644.87521272,
                                            }, -- end of [54]
                                            [56] = 
                                            {
                                                ["y"] = 101109.48351024,
                                                ["x"] = 183959.79927566,
                                            }, -- end of [56]
                                            [58] = 
                                            {
                                                ["y"] = 101207.19395585,
                                                ["x"] = 183826.89619641,
                                            }, -- end of [58]
                                            [60] = 
                                            {
                                                ["y"] = 101213.97856731,
                                                ["x"] = 183819.55692322,
                                            }, -- end of [60]
                                            [62] = 
                                            {
                                                ["y"] = 101221.57610658,
                                                ["x"] = 183813.06349431,
                                            }, -- end of [62]
                                            [64] = 
                                            {
                                                ["y"] = 101229.84117108,
                                                ["x"] = 183807.44205159,
                                            }, -- end of [64]
                                            [68] = 
                                            {
                                                ["y"] = 101248.09013236,
                                                ["x"] = 183799.39214292,
                                            }, -- end of [68]
                                            [72] = 
                                            {
                                                ["y"] = 101427.94825776,
                                                ["x"] = 183756.41436991,
                                            }, -- end of [72]
                                            [76] = 
                                            {
                                                ["y"] = 101552.79051503,
                                                ["x"] = 183712.44655965,
                                            }, -- end of [76]
                                            [80] = 
                                            {
                                                ["y"] = 101753.0183921,
                                                ["x"] = 183401.87194368,
                                            }, -- end of [80]
                                            [84] = 
                                            {
                                                ["y"] = 101530.19467238,
                                                ["x"] = 183112.99758827,
                                            }, -- end of [84]
                                            [88] = 
                                            {
                                                ["y"] = 101274.5042698,
                                                ["x"] = 182812.00289443,
                                            }, -- end of [88]
                                            [92] = 
                                            {
                                                ["y"] = 101095.50238119,
                                                ["x"] = 182584.70632436,
                                            }, -- end of [92]
                                            [96] = 
                                            {
                                                ["y"] = 100972.2412734,
                                                ["x"] = 182167.90465162,
                                            }, -- end of [96]
                                            [100] = 
                                            {
                                                ["y"] = 100979.81100947,
                                                ["x"] = 182150.42090427,
                                            }, -- end of [100]
                                            [104] = 
                                            {
                                                ["y"] = 101012.65968011,
                                                ["x"] = 182106.67865442,
                                            }, -- end of [104]
                                            [108] = 
                                            {
                                                ["y"] = 101168.93808818,
                                                ["x"] = 181892.82566689,
                                            }, -- end of [108]
                                            [112] = 
                                            {
                                                ["y"] = 101138.52717013,
                                                ["x"] = 181864.12971429,
                                            }, -- end of [112]
                                            [116] = 
                                            {
                                                ["y"] = 100985.11652469,
                                                ["x"] = 181744.11163249,
                                            }, -- end of [116]
                                            [120] = 
                                            {
                                                ["y"] = 100972.55788352,
                                                ["x"] = 181718.3810065,
                                            }, -- end of [120]
                                            [124] = 
                                            {
                                                ["y"] = 100980.7170562,
                                                ["x"] = 181700.22486257,
                                            }, -- end of [124]
                                            [128] = 
                                            {
                                                ["y"] = 101382.01534886,
                                                ["x"] = 181151.66396717,
                                            }, -- end of [128]
                                            [136] = 
                                            {
                                                ["y"] = 101296.73076789,
                                                ["x"] = 181093.64820991,
                                            }, -- end of [136]
                                            [144] = 
                                            {
                                                ["y"] = 101195.98641136,
                                                ["x"] = 180911.27391877,
                                            }, -- end of [144]
                                            [152] = 
                                            {
                                                ["y"] = 101131.38017184,
                                                ["x"] = 180732.36357254,
                                            }, -- end of [152]
                                            [160] = 
                                            {
                                                ["y"] = 101198.89171201,
                                                ["x"] = 180678.08210863,
                                            }, -- end of [160]
                                            [129] = 
                                            {
                                                ["y"] = 101381.00652606,
                                                ["x"] = 181147.05507458,
                                            }, -- end of [129]
                                            [137] = 
                                            {
                                                ["y"] = 101293.02700175,
                                                ["x"] = 181090.29077543,
                                            }, -- end of [137]
                                            [145] = 
                                            {
                                                ["y"] = 101137.41314082,
                                                ["x"] = 180773.20310221,
                                            }, -- end of [145]
                                            [153] = 
                                            {
                                                ["y"] = 101134.64200699,
                                                ["x"] = 180728.58188923,
                                            }, -- end of [153]
                                            [65] = 
                                            {
                                                ["y"] = 101234.19805735,
                                                ["x"] = 183804.99107915,
                                            }, -- end of [65]
                                            [69] = 
                                            {
                                                ["y"] = 101257.73718287,
                                                ["x"] = 183796.76322305,
                                            }, -- end of [69]
                                            [73] = 
                                            {
                                                ["y"] = 101525.3490953,
                                                ["x"] = 183734.00791262,
                                            }, -- end of [73]
                                            [77] = 
                                            {
                                                ["y"] = 101562.41290992,
                                                ["x"] = 183700.94021065,
                                            }, -- end of [77]
                                            [81] = 
                                            {
                                                ["y"] = 101750.78633368,
                                                ["x"] = 183397.4570668,
                                            }, -- end of [81]
                                            [85] = 
                                            {
                                                ["y"] = 101396.93414956,
                                                ["x"] = 182957.26336913,
                                            }, -- end of [85]
                                            [89] = 
                                            {
                                                ["y"] = 101155.99154677,
                                                ["x"] = 182676.5295122,
                                            }, -- end of [89]
                                            [93] = 
                                            {
                                                ["y"] = 101091.20156017,
                                                ["x"] = 182575.68162543,
                                            }, -- end of [93]
                                            [97] = 
                                            {
                                                ["y"] = 100971.96639908,
                                                ["x"] = 182162.95053508,
                                            }, -- end of [97]
                                            [101] = 
                                            {
                                                ["y"] = 100993.77112404,
                                                ["x"] = 182136.12490736,
                                            }, -- end of [101]
                                            [105] = 
                                            {
                                                ["y"] = 101021.42795416,
                                                ["x"] = 182094.51001003,
                                            }, -- end of [105]
                                            [109] = 
                                            {
                                                ["y"] = 101170.04087876,
                                                ["x"] = 181888.06543008,
                                            }, -- end of [109]
                                            [113] = 
                                            {
                                                ["y"] = 100999.14501926,
                                                ["x"] = 181758.32738169,
                                            }, -- end of [113]
                                            [117] = 
                                            {
                                                ["y"] = 100975.71214704,
                                                ["x"] = 181732.42222625,
                                            }, -- end of [117]
                                            [121] = 
                                            {
                                                ["y"] = 100973.95543837,
                                                ["x"] = 181713.58160025,
                                            }, -- end of [121]
                                            [125] = 
                                            {
                                                ["y"] = 100986.34383047,
                                                ["x"] = 181691.95924735,
                                            }, -- end of [125]
                                            [130] = 
                                            {
                                                ["y"] = 101377.30523035,
                                                ["x"] = 181143.70057878,
                                            }, -- end of [130]
                                            [138] = 
                                            {
                                                ["y"] = 101289.5360033,
                                                ["x"] = 181086.712032,
                                            }, -- end of [138]
                                            [146] = 
                                            {
                                                ["y"] = 101134.96819406,
                                                ["x"] = 180768.84660934,
                                            }, -- end of [146]
                                            [154] = 
                                            {
                                                ["y"] = 101138.66184689,
                                                ["x"] = 180725.64042233,
                                            }, -- end of [154]
                                            [79] = 
                                            {
                                                ["y"] = 101747.67175275,
                                                ["x"] = 183409.95779964,
                                            }, -- end of [79]
                                            [95] = 
                                            {
                                                ["y"] = 101071.6687638,
                                                ["x"] = 182524.30017011,
                                            }, -- end of [95]
                                            [111] = 
                                            {
                                                ["y"] = 101163.15210014,
                                                ["x"] = 181881.2630586,
                                            }, -- end of [111]
                                            [127] = 
                                            {
                                                ["y"] = 101376.74385946,
                                                ["x"] = 181160.14601809,
                                            }, -- end of [127]
                                            [131] = 
                                            {
                                                ["y"] = 101373.28231886,
                                                ["x"] = 181140.7326433,
                                            }, -- end of [131]
                                            [135] = 
                                            {
                                                ["y"] = 101300.6772928,
                                                ["x"] = 181096.71537865,
                                            }, -- end of [135]
                                            [139] = 
                                            {
                                                ["y"] = 101283.06760791,
                                                ["x"] = 181079.08820481,
                                            }, -- end of [139]
                                            [142] = 
                                            {
                                                ["y"] = 101253.59647114,
                                                ["x"] = 181038.77490509,
                                            }, -- end of [142]
                                            [143] = 
                                            {
                                                ["y"] = 101228.96583817,
                                                ["x"] = 180989.60662041,
                                            }, -- end of [143]
                                            [147] = 
                                            {
                                                ["y"] = 101132.68060973,
                                                ["x"] = 180764.40155423,
                                            }, -- end of [147]
                                            [151] = 
                                            {
                                                ["y"] = 101128.72316112,
                                                ["x"] = 180736.5980941,
                                            }, -- end of [151]
                                            [155] = 
                                            {
                                                ["y"] = 101143.22981128,
                                                ["x"] = 180723.60896874,
                                            }, -- end of [155]
                                            [158] = 
                                            {
                                                ["y"] = 101164.68058725,
                                                ["x"] = 180710.96164146,
                                            }, -- end of [158]
                                            [159] = 
                                            {
                                                ["y"] = 101197.25775839,
                                                ["x"] = 180679.93383787,
                                            }, -- end of [159]
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            [1] = 
                                            {
                                                ["y"] = 98633.86842315,
                                                ["x"] = 182343.1033825,
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["y"] = 98633.86842315,
                                                ["x"] = 182343.1033825,
                                            }, -- end of [2]
                                        }, -- end of [2]
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 12,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 101065.28898071,
                                            ["x"] = 189895.53739009,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 65,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 3837.6119313174,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 101200.17328938,
                                            ["x"] = 180679.26480847,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 2.7777777777778,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 11,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 32,
                                        ["y"] = 101065.28898071,
                                        ["x"] = 189895.53739009,
                                        ["name"] = "Airfield Stormers-1-1",
                                        ["heading"] = 3.5408118615679,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 33,
                                        ["y"] = 101077.06993984,
                                        ["x"] = 189923.12803019,
                                        ["name"] = "Airfield Stormers-1-2",
                                        ["heading"] = 3.5451486129896,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 34,
                                        ["y"] = 101089.13604504,
                                        ["x"] = 189950.58215447,
                                        ["name"] = "Airfield Stormers-1-3",
                                        ["heading"] = 3.5556810868459,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [3]
                                    [4] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "T-90",
                                        ["unitId"] = 35,
                                        ["y"] = 101103.51492259,
                                        ["x"] = 189976.71741203,
                                        ["name"] = "Airfield Stormers-1-4",
                                        ["heading"] = 3.6445676335061,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [4]
                                    [5] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Gepard",
                                        ["unitId"] = 36,
                                        ["y"] = 101117.97832021,
                                        ["x"] = 190003.00070919,
                                        ["name"] = "Airfield Stormers-1-5",
                                        ["heading"] = 3.6446573768469,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [5]
                                    [6] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 37,
                                        ["y"] = 101132.42423581,
                                        ["x"] = 190029.29371735,
                                        ["name"] = "Airfield Stormers-1-6",
                                        ["heading"] = 3.6439907811561,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [6]
                                }, -- end of ["units"]
                                ["y"] = 101065.28898071,
                                ["x"] = 189895.53739009,
                                ["name"] = "Airfield Stormers-1",
                                ["start_time"] = 0,
                            }, -- end of [7]
                            [8] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                        [1] = 
                                        {
                                            [127] = 
                                            {
                                                ["y"] = 103441.11434748,
                                                ["x"] = 188489.12654627,
                                            }, -- end of [127]
                                            [158] = 
                                            {
                                                ["y"] = 103648.36549058,
                                                ["x"] = 189101.51020182,
                                            }, -- end of [158]
                                            [190] = 
                                            {
                                                ["y"] = 104086.3978928,
                                                ["x"] = 189947.10134054,
                                            }, -- end of [190]
                                            [222] = 
                                            {
                                                ["y"] = 104213.14726423,
                                                ["x"] = 190238.92316741,
                                            }, -- end of [222]
                                            [1] = 
                                            {
                                                ["y"] = 102915.42453651,
                                                ["x"] = 187665.56670069,
                                            }, -- end of [1]
                                            [316] = 
                                            {
                                                ["y"] = 103951.40845312,
                                                ["x"] = 191194.24316879,
                                            }, -- end of [316]
                                            [380] = 
                                            {
                                                ["y"] = 103529.57765559,
                                                ["x"] = 191833.99047941,
                                            }, -- end of [380]
                                            [2] = 
                                            {
                                                ["y"] = 102928.53627596,
                                                ["x"] = 187718.97116076,
                                            }, -- end of [2]
                                            [3] = 
                                            {
                                                ["y"] = 102935.2356975,
                                                ["x"] = 187743.04103088,
                                            }, -- end of [3]
                                            [4] = 
                                            {
                                                ["y"] = 102935.38360288,
                                                ["x"] = 187748.02576459,
                                            }, -- end of [4]
                                            [5] = 
                                            {
                                                ["y"] = 102934.1941123,
                                                ["x"] = 187752.8662951,
                                            }, -- end of [5]
                                            [6] = 
                                            {
                                                ["y"] = 102932.10969777,
                                                ["x"] = 187757.40884691,
                                            }, -- end of [6]
                                            [7] = 
                                            {
                                                ["y"] = 102930.04819372,
                                                ["x"] = 187761.96070232,
                                            }, -- end of [7]
                                            [8] = 
                                            {
                                                ["y"] = 102928.90832751,
                                                ["x"] = 187766.81566005,
                                            }, -- end of [8]
                                            [10] = 
                                            {
                                                ["y"] = 102929.47642805,
                                                ["x"] = 187776.76776597,
                                            }, -- end of [10]
                                            [12] = 
                                            {
                                                ["y"] = 102942.90414602,
                                                ["x"] = 187830.090529,
                                            }, -- end of [12]
                                            [14] = 
                                            {
                                                ["y"] = 102948.00161928,
                                                ["x"] = 187844.18739516,
                                            }, -- end of [14]
                                            [16] = 
                                            {
                                                ["y"] = 102948.8632971,
                                                ["x"] = 187854.09235502,
                                            }, -- end of [16]
                                            [20] = 
                                            {
                                                ["y"] = 102942.45607425,
                                                ["x"] = 187872.95526445,
                                            }, -- end of [20]
                                            [24] = 
                                            {
                                                ["y"] = 102928.61168232,
                                                ["x"] = 187909.23216471,
                                            }, -- end of [24]
                                            [28] = 
                                            {
                                                ["y"] = 102939.25489061,
                                                ["x"] = 187925.54892892,
                                            }, -- end of [28]
                                            [32] = 
                                            {
                                                ["y"] = 102951.17507405,
                                                ["x"] = 187941.35573607,
                                            }, -- end of [32]
                                            [40] = 
                                            {
                                                ["y"] = 103001.65728764,
                                                ["x"] = 188001.07831986,
                                            }, -- end of [40]
                                            [48] = 
                                            {
                                                ["y"] = 103083.07560747,
                                                ["x"] = 188023.34959428,
                                            }, -- end of [48]
                                            [56] = 
                                            {
                                                ["y"] = 103140.49872785,
                                                ["x"] = 188007.42052961,
                                            }, -- end of [56]
                                            [64] = 
                                            {
                                                ["y"] = 103156.52372842,
                                                ["x"] = 188037.81376455,
                                            }, -- end of [64]
                                            [80] = 
                                            {
                                                ["y"] = 103208.81342557,
                                                ["x"] = 188115.39544426,
                                            }, -- end of [80]
                                            [96] = 
                                            {
                                                ["y"] = 103305.06737685,
                                                ["x"] = 188286.24261569,
                                            }, -- end of [96]
                                            [112] = 
                                            {
                                                ["y"] = 103367.73851352,
                                                ["x"] = 188406.28673272,
                                            }, -- end of [112]
                                            [128] = 
                                            {
                                                ["y"] = 103443.89995227,
                                                ["x"] = 188493.21426657,
                                            }, -- end of [128]
                                            [160] = 
                                            {
                                                ["y"] = 103667.79149687,
                                                ["x"] = 189136.41479424,
                                            }, -- end of [160]
                                            [192] = 
                                            {
                                                ["y"] = 104091.41398928,
                                                ["x"] = 189955.74016588,
                                            }, -- end of [192]
                                            [224] = 
                                            {
                                                ["y"] = 104203.80794225,
                                                ["x"] = 190267.36378334,
                                            }, -- end of [224]
                                            [256] = 
                                            {
                                                ["y"] = 104176.42807365,
                                                ["x"] = 190799.92938923,
                                            }, -- end of [256]
                                            [320] = 
                                            {
                                                ["y"] = 103886.32177868,
                                                ["x"] = 191231.27641852,
                                            }, -- end of [320]
                                            [384] = 
                                            {
                                                ["y"] = 103519.02373996,
                                                ["x"] = 191849.64903404,
                                            }, -- end of [384]
                                            [257] = 
                                            {
                                                ["y"] = 104175.06220089,
                                                ["x"] = 190809.83435434,
                                            }, -- end of [257]
                                            [321] = 
                                            {
                                                ["y"] = 103881.659446,
                                                ["x"] = 191233.08000286,
                                            }, -- end of [321]
                                            [385] = 
                                            {
                                                ["y"] = 103514.22669459,
                                                ["x"] = 191851.11335374,
                                            }, -- end of [385]
                                            [129] = 
                                            {
                                                ["y"] = 103445.71323702,
                                                ["x"] = 188497.86251683,
                                            }, -- end of [129]
                                            [161] = 
                                            {
                                                ["y"] = 103677.2155988,
                                                ["x"] = 189154.04972663,
                                            }, -- end of [161]
                                            [193] = 
                                            {
                                                ["y"] = 104094.73484486,
                                                ["x"] = 189959.46339446,
                                            }, -- end of [193]
                                            [225] = 
                                            {
                                                ["y"] = 104203.95222164,
                                                ["x"] = 190272.35375235,
                                            }, -- end of [225]
                                            [258] = 
                                            {
                                                ["y"] = 104173.88809592,
                                                ["x"] = 190824.78591969,
                                            }, -- end of [258]
                                            [322] = 
                                            {
                                                ["y"] = 103872.1059901,
                                                ["x"] = 191236.02666836,
                                            }, -- end of [322]
                                            [386] = 
                                            {
                                                ["y"] = 103509.30768135,
                                                ["x"] = 191851.97145397,
                                            }, -- end of [386]
                                            [65] = 
                                            {
                                                ["y"] = 103155.97747626,
                                                ["x"] = 188042.78281324,
                                            }, -- end of [65]
                                            [81] = 
                                            {
                                                ["y"] = 103210.50563631,
                                                ["x"] = 188120.1000523,
                                            }, -- end of [81]
                                            [97] = 
                                            {
                                                ["y"] = 103306.23306455,
                                                ["x"] = 188296.17201124,
                                            }, -- end of [97]
                                            [113] = 
                                            {
                                                ["y"] = 103368.94624673,
                                                ["x"] = 188411.13822826,
                                            }, -- end of [113]
                                            [130] = 
                                            {
                                                ["y"] = 103448.45973777,
                                                ["x"] = 188507.48058874,
                                            }, -- end of [130]
                                            [162] = 
                                            {
                                                ["y"] = 103720.12717577,
                                                ["x"] = 189221.55553129,
                                            }, -- end of [162]
                                            [194] = 
                                            {
                                                ["y"] = 104098.69177765,
                                                ["x"] = 189962.51340649,
                                            }, -- end of [194]
                                            [226] = 
                                            {
                                                ["y"] = 104206.3737535,
                                                ["x"] = 190302.21154002,
                                            }, -- end of [226]
                                            [260] = 
                                            {
                                                ["y"] = 104173.94606441,
                                                ["x"] = 190864.76204249,
                                            }, -- end of [260]
                                            [324] = 
                                            {
                                                ["y"] = 103842.7878067,
                                                ["x"] = 191242.35207124,
                                            }, -- end of [324]
                                            [388] = 
                                            {
                                                ["y"] = 103317.28992162,
                                                ["x"] = 191885.28427032,
                                            }, -- end of [388]
                                            [261] = 
                                            {
                                                ["y"] = 104181.81359829,
                                                ["x"] = 190949.38306668,
                                            }, -- end of [261]
                                            [325] = 
                                            {
                                                ["y"] = 103837.82839116,
                                                ["x"] = 191242.9800177,
                                            }, -- end of [325]
                                            [389] = 
                                            {
                                                ["y"] = 103302.37017341,
                                                ["x"] = 191886.81826625,
                                            }, -- end of [389]
                                            [131] = 
                                            {
                                                ["y"] = 103458.75239781,
                                                ["x"] = 188546.12434319,
                                            }, -- end of [131]
                                            [163] = 
                                            {
                                                ["y"] = 103770.57639559,
                                                ["x"] = 189296.07005986,
                                            }, -- end of [163]
                                            [195] = 
                                            {
                                                ["y"] = 104103.13562331,
                                                ["x"] = 189964.78532437,
                                            }, -- end of [195]
                                            [227] = 
                                            {
                                                ["y"] = 104207.08897705,
                                                ["x"] = 190307.14661379,
                                            }, -- end of [227]
                                            [262] = 
                                            {
                                                ["y"] = 104181.49562747,
                                                ["x"] = 190974.37863415,
                                            }, -- end of [262]
                                            [326] = 
                                            {
                                                ["y"] = 103832.83401135,
                                                ["x"] = 191243.1328544,
                                            }, -- end of [326]
                                            [390] = 
                                            {
                                                ["y"] = 103287.38721447,
                                                ["x"] = 191887.47142623,
                                            }, -- end of [390]
                                            [33] = 
                                            {
                                                ["y"] = 102957.8582619,
                                                ["x"] = 187954.78116424,
                                            }, -- end of [33]
                                            [41] = 
                                            {
                                                ["y"] = 103006.12733165,
                                                ["x"] = 188003.31739857,
                                            }, -- end of [41]
                                            [49] = 
                                            {
                                                ["y"] = 103088.06732375,
                                                ["x"] = 188023.09165939,
                                            }, -- end of [49]
                                            [57] = 
                                            {
                                                ["y"] = 103145.47777178,
                                                ["x"] = 188007.71014721,
                                            }, -- end of [57]
                                            [66] = 
                                            {
                                                ["y"] = 103155.65284505,
                                                ["x"] = 188052.77459527,
                                            }, -- end of [66]
                                            [82] = 
                                            {
                                                ["y"] = 103213.32781175,
                                                ["x"] = 188129.69236051,
                                            }, -- end of [82]
                                            [98] = 
                                            {
                                                ["y"] = 103306.89641019,
                                                ["x"] = 188311.15569166,
                                            }, -- end of [98]
                                            [114] = 
                                            {
                                                ["y"] = 103375.06895999,
                                                ["x"] = 188440.49333797,
                                            }, -- end of [114]
                                            [132] = 
                                            {
                                                ["y"] = 103460.58512445,
                                                ["x"] = 188550.77489484,
                                            }, -- end of [132]
                                            [164] = 
                                            {
                                                ["y"] = 103777.95343349,
                                                ["x"] = 189309.12797291,
                                            }, -- end of [164]
                                            [196] = 
                                            {
                                                ["y"] = 104107.95575634,
                                                ["x"] = 189966.07745973,
                                            }, -- end of [196]
                                            [228] = 
                                            {
                                                ["y"] = 104210.01189843,
                                                ["x"] = 190321.85841404,
                                            }, -- end of [228]
                                            [264] = 
                                            {
                                                ["y"] = 104177.48367415,
                                                ["x"] = 190983.35476243,
                                            }, -- end of [264]
                                            [328] = 
                                            {
                                                ["y"] = 103822.99140747,
                                                ["x"] = 191241.52876825,
                                            }, -- end of [328]
                                            [392] = 
                                            {
                                                ["y"] = 103267.41790825,
                                                ["x"] = 191886.56853827,
                                            }, -- end of [392]
                                            [265] = 
                                            {
                                                ["y"] = 104173.35290012,
                                                ["x"] = 190986.138407,
                                            }, -- end of [265]
                                            [329] = 
                                            {
                                                ["y"] = 103818.27973687,
                                                ["x"] = 191239.86202058,
                                            }, -- end of [329]
                                            [393] = 
                                            {
                                                ["y"] = 103257.50341007,
                                                ["x"] = 191885.2739731,
                                            }, -- end of [393]
                                            [133] = 
                                            {
                                                ["y"] = 103462.71268167,
                                                ["x"] = 188555.29799023,
                                            }, -- end of [133]
                                            [165] = 
                                            {
                                                ["y"] = 103782.21889214,
                                                ["x"] = 189318.17064979,
                                            }, -- end of [165]
                                            [197] = 
                                            {
                                                ["y"] = 104112.94006549,
                                                ["x"] = 189966.20758684,
                                            }, -- end of [197]
                                            [229] = 
                                            {
                                                ["y"] = 104211.41566715,
                                                ["x"] = 190326.65660831,
                                            }, -- end of [229]
                                            [266] = 
                                            {
                                                ["y"] = 104168.58059849,
                                                ["x"] = 190987.56902861,
                                            }, -- end of [266]
                                            [330] = 
                                            {
                                                ["y"] = 103813.73792434,
                                                ["x"] = 191237.77519389,
                                            }, -- end of [330]
                                            [394] = 
                                            {
                                                ["y"] = 103247.66928723,
                                                ["x"] = 191883.46551589,
                                            }, -- end of [394]
                                            [67] = 
                                            {
                                                ["y"] = 103155.94517086,
                                                ["x"] = 188057.76354809,
                                            }, -- end of [67]
                                            [83] = 
                                            {
                                                ["y"] = 103221.42664153,
                                                ["x"] = 188158.56906839,
                                            }, -- end of [83]
                                            [99] = 
                                            {
                                                ["y"] = 103306.9782802,
                                                ["x"] = 188331.15010904,
                                            }, -- end of [99]
                                            [115] = 
                                            {
                                                ["y"] = 103376.80749754,
                                                ["x"] = 188445.17769294,
                                            }, -- end of [115]
                                            [134] = 
                                            {
                                                ["y"] = 103467.58462189,
                                                ["x"] = 188564.02917828,
                                            }, -- end of [134]
                                            [166] = 
                                            {
                                                ["y"] = 103785.77877206,
                                                ["x"] = 189327.51229837,
                                            }, -- end of [166]
                                            [198] = 
                                            {
                                                ["y"] = 104117.8359833,
                                                ["x"] = 189965.22015348,
                                            }, -- end of [198]
                                            [230] = 
                                            {
                                                ["y"] = 104212.5247682,
                                                ["x"] = 190331.52732079,
                                            }, -- end of [230]
                                            [268] = 
                                            {
                                                ["y"] = 104158.61200926,
                                                ["x"] = 190988.17972831,
                                            }, -- end of [268]
                                            [332] = 
                                            {
                                                ["y"] = 103782.19543668,
                                                ["x"] = 191222.7327294,
                                            }, -- end of [332]
                                            [396] = 
                                            {
                                                ["y"] = 103218.7890594,
                                                ["x"] = 191875.41941527,
                                            }, -- end of [396]
                                            [269] = 
                                            {
                                                ["y"] = 104153.7592122,
                                                ["x"] = 190989.37814548,
                                            }, -- end of [269]
                                            [333] = 
                                            {
                                                ["y"] = 103777.37927884,
                                                ["x"] = 191221.37948278,
                                            }, -- end of [333]
                                            [397] = 
                                            {
                                                ["y"] = 103204.75913047,
                                                ["x"] = 191870.11832058,
                                            }, -- end of [397]
                                            [135] = 
                                            {
                                                ["y"] = 103486.27820147,
                                                ["x"] = 188593.61543008,
                                            }, -- end of [135]
                                            [167] = 
                                            {
                                                ["y"] = 103802.96424841,
                                                ["x"] = 189379.75042843,
                                            }, -- end of [167]
                                            [199] = 
                                            {
                                                ["y"] = 104132.12401816,
                                                ["x"] = 189960.65755252,
                                            }, -- end of [199]
                                            [231] = 
                                            {
                                                ["y"] = 104225.67728003,
                                                ["x"] = 190415.48073182,
                                            }, -- end of [231]
                                            [17] = 
                                            {
                                                ["y"] = 102947.87562486,
                                                ["x"] = 187858.98728977,
                                            }, -- end of [17]
                                            [21] = 
                                            {
                                                ["y"] = 102937.68365697,
                                                ["x"] = 187881.74083538,
                                            }, -- end of [21]
                                            [25] = 
                                            {
                                                ["y"] = 102929.96890831,
                                                ["x"] = 187914.0399191,
                                            }, -- end of [25]
                                            [29] = 
                                            {
                                                ["y"] = 102942.94417747,
                                                ["x"] = 187928.92435595,
                                            }, -- end of [29]
                                            [34] = 
                                            {
                                                ["y"] = 102967.67537033,
                                                ["x"] = 187972.20295631,
                                            }, -- end of [34]
                                            [42] = 
                                            {
                                                ["y"] = 103010.71478604,
                                                ["x"] = 188005.30381085,
                                            }, -- end of [42]
                                            [50] = 
                                            {
                                                ["y"] = 103093.01513378,
                                                ["x"] = 188022.3836787,
                                            }, -- end of [50]
                                            [58] = 
                                            {
                                                ["y"] = 103149.99795283,
                                                ["x"] = 188009.75794557,
                                            }, -- end of [58]
                                            [68] = 
                                            {
                                                ["y"] = 103156.87056688,
                                                ["x"] = 188062.67309569,
                                            }, -- end of [68]
                                            [84] = 
                                            {
                                                ["y"] = 103223.34114309,
                                                ["x"] = 188163.18647151,
                                            }, -- end of [84]
                                            [100] = 
                                            {
                                                ["y"] = 103308.04675064,
                                                ["x"] = 188336.01815796,
                                            }, -- end of [100]
                                            [116] = 
                                            {
                                                ["y"] = 103379.18228205,
                                                ["x"] = 188449.57203609,
                                            }, -- end of [116]
                                            [136] = 
                                            {
                                                ["y"] = 103489.25556351,
                                                ["x"] = 188597.63086923,
                                            }, -- end of [136]
                                            [168] = 
                                            {
                                                ["y"] = 103805.00771828,
                                                ["x"] = 189384.31329842,
                                            }, -- end of [168]
                                            [200] = 
                                            {
                                                ["y"] = 104141.47178389,
                                                ["x"] = 189957.1093148,
                                            }, -- end of [200]
                                            [232] = 
                                            {
                                                ["y"] = 104229.72203692,
                                                ["x"] = 190429.92338105,
                                            }, -- end of [232]
                                            [272] = 
                                            {
                                                ["y"] = 104125.98810059,
                                                ["x"] = 191000.33599829,
                                            }, -- end of [272]
                                            [336] = 
                                            {
                                                ["y"] = 103766.29333864,
                                                ["x"] = 191227.361223,
                                            }, -- end of [336]
                                            [400] = 
                                            {
                                                ["y"] = 103115.40909454,
                                                ["x"] = 191825.29496465,
                                            }, -- end of [400]
                                            [273] = 
                                            {
                                                ["y"] = 104122.36957491,
                                                ["x"] = 191003.77884317,
                                            }, -- end of [273]
                                            [337] = 
                                            {
                                                ["y"] = 103767.08431515,
                                                ["x"] = 191232.28113529,
                                            }, -- end of [337]
                                            [401] = 
                                            {
                                                ["y"] = 103014.63460583,
                                                ["x"] = 191781.1472793,
                                            }, -- end of [401]
                                            [137] = 
                                            {
                                                ["y"] = 103492.45028182,
                                                ["x"] = 188601.4760083,
                                            }, -- end of [137]
                                            [169] = 
                                            {
                                                ["y"] = 103821.19778561,
                                                ["x"] = 189415.34159608,
                                            }, -- end of [169]
                                            [201] = 
                                            {
                                                ["y"] = 104169.16549432,
                                                ["x"] = 189945.59887701,
                                            }, -- end of [201]
                                            [233] = 
                                            {
                                                ["y"] = 104233.68348679,
                                                ["x"] = 190444.38841819,
                                            }, -- end of [233]
                                            [274] = 
                                            {
                                                ["y"] = 104115.91829979,
                                                ["x"] = 191011.41898424,
                                            }, -- end of [274]
                                            [338] = 
                                            {
                                                ["y"] = 103785.31134933,
                                                ["x"] = 191305.0410082,
                                            }, -- end of [338]
                                            [402] = 
                                            {
                                                ["y"] = 103009.77612383,
                                                ["x"] = 191780.64527995,
                                            }, -- end of [402]
                                            [69] = 
                                            {
                                                ["y"] = 103158.69952203,
                                                ["x"] = 188067.31440179,
                                            }, -- end of [69]
                                            [85] = 
                                            {
                                                ["y"] = 103225.68402207,
                                                ["x"] = 188167.60092169,
                                            }, -- end of [85]
                                            [101] = 
                                            {
                                                ["y"] = 103310.10492868,
                                                ["x"] = 188340.57066143,
                                            }, -- end of [101]
                                            [117] = 
                                            {
                                                ["y"] = 103382.30387098,
                                                ["x"] = 188453.47080846,
                                            }, -- end of [117]
                                            [138] = 
                                            {
                                                ["y"] = 103499.24910038,
                                                ["x"] = 188608.80843013,
                                            }, -- end of [138]
                                            [170] = 
                                            {
                                                ["y"] = 103853.19978992,
                                                ["x"] = 189477.58288893,
                                            }, -- end of [170]
                                            [202] = 
                                            {
                                                ["y"] = 104178.69822925,
                                                ["x"] = 189942.58077899,
                                            }, -- end of [202]
                                            [234] = 
                                            {
                                                ["y"] = 104242.48838153,
                                                ["x"] = 190483.39628351,
                                            }, -- end of [234]
                                            [276] = 
                                            {
                                                ["y"] = 104101.53805358,
                                                ["x"] = 191031.86113413,
                                            }, -- end of [276]
                                            [340] = 
                                            {
                                                ["y"] = 103790.98330901,
                                                ["x"] = 191318.85950001,
                                            }, -- end of [340]
                                            [404] = 
                                            {
                                                ["y"] = 103001.19945659,
                                                ["x"] = 191785.60634738,
                                            }, -- end of [404]
                                            [277] = 
                                            {
                                                ["y"] = 104092.17757707,
                                                ["x"] = 191043.58088788,
                                            }, -- end of [277]
                                            [341] = 
                                            {
                                                ["y"] = 103794.06544434,
                                                ["x"] = 191322.79342394,
                                            }, -- end of [341]
                                            [405] = 
                                            {
                                                ["y"] = 102986.05283561,
                                                ["x"] = 191798.64571585,
                                            }, -- end of [405]
                                            [139] = 
                                            {
                                                ["y"] = 103548.11597353,
                                                ["x"] = 188658.9169321,
                                            }, -- end of [139]
                                            [171] = 
                                            {
                                                ["y"] = 103896.89402568,
                                                ["x"] = 189567.51239576,
                                            }, -- end of [171]
                                            [203] = 
                                            {
                                                ["y"] = 104183.54398025,
                                                ["x"] = 189941.35422279,
                                            }, -- end of [203]
                                            [235] = 
                                            {
                                                ["y"] = 104243.36151199,
                                                ["x"] = 190488.3160473,
                                            }, -- end of [235]
                                            [278] = 
                                            {
                                                ["y"] = 104063.52793852,
                                                ["x"] = 191078.24443304,
                                            }, -- end of [278]
                                            [342] = 
                                            {
                                                ["y"] = 103813.25407555,
                                                ["x"] = 191345.84736483,
                                            }, -- end of [342]
                                            [406] = 
                                            {
                                                ["y"] = 102981.82607348,
                                                ["x"] = 191801.31362348,
                                            }, -- end of [406]
                                            [35] = 
                                            {
                                                ["y"] = 102970.53710548,
                                                ["x"] = 187976.30053332,
                                            }, -- end of [35]
                                            [43] = 
                                            {
                                                ["y"] = 103038.88241357,
                                                ["x"] = 188015.62086417,
                                            }, -- end of [43]
                                            [51] = 
                                            {
                                                ["y"] = 103097.87284143,
                                                ["x"] = 188021.20596564,
                                            }, -- end of [51]
                                            [59] = 
                                            {
                                                ["y"] = 103153.28558552,
                                                ["x"] = 188013.48607178,
                                            }, -- end of [59]
                                            [70] = 
                                            {
                                                ["y"] = 103161.662693,
                                                ["x"] = 188071.3195864,
                                            }, -- end of [70]
                                            [86] = 
                                            {
                                                ["y"] = 103228.43229507,
                                                ["x"] = 188171.77667678,
                                            }, -- end of [86]
                                            [102] = 
                                            {
                                                ["y"] = 103322.55819822,
                                                ["x"] = 188362.24532646,
                                            }, -- end of [102]
                                            [118] = 
                                            {
                                                ["y"] = 103385.81287899,
                                                ["x"] = 188457.03144625,
                                            }, -- end of [118]
                                            [140] = 
                                            {
                                                ["y"] = 103554.31060082,
                                                ["x"] = 188666.75945307,
                                            }, -- end of [140]
                                            [172] = 
                                            {
                                                ["y"] = 103899.50177983,
                                                ["x"] = 189571.77712286,
                                            }, -- end of [172]
                                            [204] = 
                                            {
                                                ["y"] = 104188.50173236,
                                                ["x"] = 189940.77574417,
                                            }, -- end of [204]
                                            [236] = 
                                            {
                                                ["y"] = 104251.50468826,
                                                ["x"] = 190517.18971685,
                                            }, -- end of [236]
                                            [280] = 
                                            {
                                                ["y"] = 104055.23702864,
                                                ["x"] = 191083.79804169,
                                            }, -- end of [280]
                                            [344] = 
                                            {
                                                ["y"] = 103816.99191872,
                                                ["x"] = 191355.05428775,
                                            }, -- end of [344]
                                            [408] = 
                                            {
                                                ["y"] = 102972.75436163,
                                                ["x"] = 191805.49540291,
                                            }, -- end of [408]
                                            [281] = 
                                            {
                                                ["y"] = 104046.62965058,
                                                ["x"] = 191088.88304403,
                                            }, -- end of [281]
                                            [345] = 
                                            {
                                                ["y"] = 103818.92279199,
                                                ["x"] = 191364.86670252,
                                            }, -- end of [345]
                                            [409] = 
                                            {
                                                ["y"] = 102968.02673163,
                                                ["x"] = 191807.11996205,
                                            }, -- end of [409]
                                            [141] = 
                                            {
                                                ["y"] = 103557.01070503,
                                                ["x"] = 188670.96686902,
                                            }, -- end of [141]
                                            [173] = 
                                            {
                                                ["y"] = 103902.38921247,
                                                ["x"] = 189575.85806446,
                                            }, -- end of [173]
                                            [205] = 
                                            {
                                                ["y"] = 104192.98925465,
                                                ["x"] = 189942.69096387,
                                            }, -- end of [205]
                                            [237] = 
                                            {
                                                ["y"] = 104256.13053218,
                                                ["x"] = 190531.45723113,
                                            }, -- end of [237]
                                            [282] = 
                                            {
                                                ["y"] = 104042.24808467,
                                                ["x"] = 191091.28114687,
                                            }, -- end of [282]
                                            [346] = 
                                            {
                                                ["y"] = 103818.83517171,
                                                ["x"] = 191369.83430317,
                                            }, -- end of [346]
                                            [410] = 
                                            {
                                                ["y"] = 102963.20406802,
                                                ["x"] = 191808.43619114,
                                            }, -- end of [410]
                                            [71] = 
                                            {
                                                ["y"] = 103165.687856,
                                                ["x"] = 188074.25502196,
                                            }, -- end of [71]
                                            [87] = 
                                            {
                                                ["y"] = 103234.50702076,
                                                ["x"] = 188179.71719195,
                                            }, -- end of [87]
                                            [103] = 
                                            {
                                                ["y"] = 103325.54403963,
                                                ["x"] = 188366.2541804,
                                            }, -- end of [103]
                                            [119] = 
                                            {
                                                ["y"] = 103393.25039929,
                                                ["x"] = 188463.71458112,
                                            }, -- end of [119]
                                            [142] = 
                                            {
                                                ["y"] = 103559.38067789,
                                                ["x"] = 188675.36738909,
                                            }, -- end of [142]
                                            [174] = 
                                            {
                                                ["y"] = 103905.54250804,
                                                ["x"] = 189579.73708226,
                                            }, -- end of [174]
                                            [206] = 
                                            {
                                                ["y"] = 104195.85315374,
                                                ["x"] = 189946.75516706,
                                            }, -- end of [206]
                                            [238] = 
                                            {
                                                ["y"] = 104259.86938494,
                                                ["x"] = 190540.72796014,
                                            }, -- end of [238]
                                            [284] = 
                                            {
                                                ["y"] = 104028.41245591,
                                                ["x"] = 191097.05558465,
                                            }, -- end of [284]
                                            [348] = 
                                            {
                                                ["y"] = 103808.13780027,
                                                ["x"] = 191413.35991265,
                                            }, -- end of [348]
                                            [412] = 
                                            {
                                                ["y"] = 102948.40433027,
                                                ["x"] = 191810.80084211,
                                            }, -- end of [412]
                                            [285] = 
                                            {
                                                ["y"] = 104023.61969952,
                                                ["x"] = 191098.47667696,
                                            }, -- end of [285]
                                            [349] = 
                                            {
                                                ["y"] = 103804.07540791,
                                                ["x"] = 191416.18932589,
                                            }, -- end of [349]
                                            [413] = 
                                            {
                                                ["y"] = 102938.42370185,
                                                ["x"] = 191811.39900873,
                                            }, -- end of [413]
                                            [9] = 
                                            {
                                                ["y"] = 102928.85236478,
                                                ["x"] = 187771.80779835,
                                            }, -- end of [9]
                                            [11] = 
                                            {
                                                ["y"] = 102931.56173487,
                                                ["x"] = 187786.54591503,
                                            }, -- end of [11]
                                            [13] = 
                                            {
                                                ["y"] = 102944.46050997,
                                                ["x"] = 187834.84065936,
                                            }, -- end of [13]
                                            [15] = 
                                            {
                                                ["y"] = 102948.89349388,
                                                ["x"] = 187849.10019197,
                                            }, -- end of [15]
                                            [18] = 
                                            {
                                                ["y"] = 102946.30605,
                                                ["x"] = 187863.73384146,
                                            }, -- end of [18]
                                            [22] = 
                                            {
                                                ["y"] = 102928.24557492,
                                                ["x"] = 187899.31317374,
                                            }, -- end of [22]
                                            [26] = 
                                            {
                                                ["y"] = 102932.21552202,
                                                ["x"] = 187918.49231488,
                                            }, -- end of [26]
                                            [30] = 
                                            {
                                                ["y"] = 102946.23518521,
                                                ["x"] = 187932.68063615,
                                            }, -- end of [30]
                                            [36] = 
                                            {
                                                ["y"] = 102973.80842681,
                                                ["x"] = 187980.07881731,
                                            }, -- end of [36]
                                            [44] = 
                                            {
                                                ["y"] = 103048.5044547,
                                                ["x"] = 188018.33302432,
                                            }, -- end of [44]
                                            [52] = 
                                            {
                                                ["y"] = 103112.21544765,
                                                ["x"] = 188016.81434734,
                                            }, -- end of [52]
                                            [60] = 
                                            {
                                                ["y"] = 103155.28575189,
                                                ["x"] = 188018.05409944,
                                            }, -- end of [60]
                                            [72] = 
                                            {
                                                ["y"] = 103170.32462977,
                                                ["x"] = 188076.10166117,
                                            }, -- end of [72]
                                            [88] = 
                                            {
                                                ["y"] = 103244.41799858,
                                                ["x"] = 188190.97280791,
                                            }, -- end of [88]
                                            [104] = 
                                            {
                                                ["y"] = 103329.25572782,
                                                ["x"] = 188369.57352716,
                                            }, -- end of [104]
                                            [120] = 
                                            {
                                                ["y"] = 103404.87030831,
                                                ["x"] = 188473.19658106,
                                            }, -- end of [120]
                                            [144] = 
                                            {
                                                ["y"] = 103598.73926128,
                                                ["x"] = 188767.24746919,
                                            }, -- end of [144]
                                            [176] = 
                                            {
                                                ["y"] = 103953.85796686,
                                                ["x"] = 189630.34368494,
                                            }, -- end of [176]
                                            [208] = 
                                            {
                                                ["y"] = 104207.10158301,
                                                ["x"] = 189995.43574631,
                                            }, -- end of [208]
                                            [240] = 
                                            {
                                                ["y"] = 104266.98311364,
                                                ["x"] = 190553.91975528,
                                            }, -- end of [240]
                                            [288] = 
                                            {
                                                ["y"] = 103999.04929047,
                                                ["x"] = 191101.91366489,
                                            }, -- end of [288]
                                            [352] = 
                                            {
                                                ["y"] = 103794.54611009,
                                                ["x"] = 191432.24893867,
                                            }, -- end of [352]
                                            [416] = 
                                            {
                                                ["y"] = 102923.52150458,
                                                ["x"] = 191810.11271791,
                                            }, -- end of [416]
                                            [289] = 
                                            {
                                                ["y"] = 103994.1561793,
                                                ["x"] = 191100.88271097,
                                            }, -- end of [289]
                                            [353] = 
                                            {
                                                ["y"] = 103793.09521605,
                                                ["x"] = 191437.02189517,
                                            }, -- end of [353]
                                            [417] = 
                                            {
                                                ["y"] = 102918.71549353,
                                                ["x"] = 191808.73797907,
                                            }, -- end of [417]
                                            [145] = 
                                            {
                                                ["y"] = 103603.52590089,
                                                ["x"] = 188781.45447721,
                                            }, -- end of [145]
                                            [177] = 
                                            {
                                                ["y"] = 103956.79480019,
                                                ["x"] = 189634.38894776,
                                            }, -- end of [177]
                                            [209] = 
                                            {
                                                ["y"] = 104234.60198162,
                                                ["x"] = 190091.53640165,
                                            }, -- end of [209]
                                            [241] = 
                                            {
                                                ["y"] = 104269.77902918,
                                                ["x"] = 190558.06404431,
                                            }, -- end of [241]
                                            [290] = 
                                            {
                                                ["y"] = 103989.466421,
                                                ["x"] = 191099.17869393,
                                            }, -- end of [290]
                                            [354] = 
                                            {
                                                ["y"] = 103790.53652467,
                                                ["x"] = 191441.29993352,
                                            }, -- end of [354]
                                            [418] = 
                                            {
                                                ["y"] = 102914.01982676,
                                                ["x"] = 191807.02250062,
                                            }, -- end of [418]
                                            [73] = 
                                            {
                                                ["y"] = 103175.20415464,
                                                ["x"] = 188077.18129473,
                                            }, -- end of [73]
                                            [89] = 
                                            {
                                                ["y"] = 103274.74895506,
                                                ["x"] = 188224.20104679,
                                            }, -- end of [89]
                                            [105] = 
                                            {
                                                ["y"] = 103333.63618523,
                                                ["x"] = 188371.97991811,
                                            }, -- end of [105]
                                            [121] = 
                                            {
                                                ["y"] = 103408.92417985,
                                                ["x"] = 188476.12173474,
                                            }, -- end of [121]
                                            [146] = 
                                            {
                                                ["y"] = 103604.48109153,
                                                ["x"] = 188786.35972417,
                                            }, -- end of [146]
                                            [178] = 
                                            {
                                                ["y"] = 103959.43404709,
                                                ["x"] = 189638.6342365,
                                            }, -- end of [178]
                                            [210] = 
                                            {
                                                ["y"] = 104238.16057343,
                                                ["x"] = 190121.29067035,
                                            }, -- end of [210]
                                            [242] = 
                                            {
                                                ["y"] = 104272.81471558,
                                                ["x"] = 190562.03626694,
                                            }, -- end of [242]
                                            [292] = 
                                            {
                                                ["y"] = 103980.9558502,
                                                ["x"] = 191093.94085655,
                                            }, -- end of [292]
                                            [356] = 
                                            {
                                                ["y"] = 103781.89607364,
                                                ["x"] = 191445.5939409,
                                            }, -- end of [356]
                                            [420] = 
                                            {
                                                ["y"] = 102782.93497467,
                                                ["x"] = 191725.07085629,
                                            }, -- end of [420]
                                            [391] = 
                                            {
                                                ["y"] = 103277.38974471,
                                                ["x"] = 191887.29694602,
                                            }, -- end of [391]
                                            [398] = 
                                            {
                                                ["y"] = 103191.03596213,
                                                ["x"] = 191864.06640524,
                                            }, -- end of [398]
                                            [379] = 
                                            {
                                                ["y"] = 103529.64786551,
                                                ["x"] = 191828.99266937,
                                            }, -- end of [379]
                                            [315] = 
                                            {
                                                ["y"] = 103959.29435294,
                                                ["x"] = 191188.09873192,
                                            }, -- end of [315]
                                            [293] = 
                                            {
                                                ["y"] = 103976.52693481,
                                                ["x"] = 191091.62146975,
                                            }, -- end of [293]
                                            [357] = 
                                            {
                                                ["y"] = 103776.89324083,
                                                ["x"] = 191445.50318634,
                                            }, -- end of [357]
                                            [421] = 
                                            {
                                                ["y"] = 102599.01686962,
                                                ["x"] = 191587.03921107,
                                            }, -- end of [421]
                                            [414] = 
                                            {
                                                ["y"] = 102933.4247938,
                                                ["x"] = 191811.37194364,
                                            }, -- end of [414]
                                            [147] = 
                                            {
                                                ["y"] = 103605.00619332,
                                                ["x"] = 188791.33072623,
                                            }, -- end of [147]
                                            [179] = 
                                            {
                                                ["y"] = 103983.49082142,
                                                ["x"] = 189682.4637414,
                                            }, -- end of [179]
                                            [211] = 
                                            {
                                                ["y"] = 104241.8117109,
                                                ["x"] = 190135.81959007,
                                            }, -- end of [211]
                                            [243] = 
                                            {
                                                ["y"] = 104276.13241468,
                                                ["x"] = 190565.77430905,
                                            }, -- end of [243]
                                            [294] = 
                                            {
                                                ["y"] = 103967.74990767,
                                                ["x"] = 191086.84495293,
                                            }, -- end of [294]
                                            [358] = 
                                            {
                                                ["y"] = 103766.91117028,
                                                ["x"] = 191445.46881852,
                                            }, -- end of [358]
                                            [422] = 
                                            {
                                                ["y"] = 102594.25254908,
                                                ["x"] = 191587.59775613,
                                            }, -- end of [422]
                                            [106] = 
                                            {
                                                ["y"] = 103342.47512456,
                                                ["x"] = 188376.62267949,
                                            }, -- end of [106]
                                            [37] = 
                                            {
                                                ["y"] = 102977.38540838,
                                                ["x"] = 187983.57108381,
                                            }, -- end of [37]
                                            [45] = 
                                            {
                                                ["y"] = 103058.28237995,
                                                ["x"] = 188020.42598893,
                                            }, -- end of [45]
                                            [53] = 
                                            {
                                                ["y"] = 103121.55170624,
                                                ["x"] = 188013.24852837,
                                            }, -- end of [53]
                                            [61] = 
                                            {
                                                ["y"] = 103156.52272124,
                                                ["x"] = 188022.89794217,
                                            }, -- end of [61]
                                            [74] = 
                                            {
                                                ["y"] = 103185.02569379,
                                                ["x"] = 188079.04368687,
                                            }, -- end of [74]
                                            [90] = 
                                            {
                                                ["y"] = 103289.7261667,
                                                ["x"] = 188244.21477012,
                                            }, -- end of [90]
                                            [423] = 
                                            {
                                                ["y"] = 102590.67852567,
                                                ["x"] = 191591.08313846,
                                            }, -- end of [423]
                                            [122] = 
                                            {
                                                ["y"] = 103413.21736465,
                                                ["x"] = 188478.68107262,
                                            }, -- end of [122]
                                            [148] = 
                                            {
                                                ["y"] = 103605.28389273,
                                                ["x"] = 188801.32467745,
                                            }, -- end of [148]
                                            [180] = 
                                            {
                                                ["y"] = 103987.74086314,
                                                ["x"] = 189691.51349747,
                                            }, -- end of [180]
                                            [212] = 
                                            {
                                                ["y"] = 104244.22432737,
                                                ["x"] = 190160.70124607,
                                            }, -- end of [212]
                                            [244] = 
                                            {
                                                ["y"] = 104279.75178371,
                                                ["x"] = 190569.22393276,
                                            }, -- end of [244]
                                            [296] = 
                                            {
                                                ["y"] = 103959.3161439,
                                                ["x"] = 191088.62435864,
                                            }, -- end of [296]
                                            [360] = 
                                            {
                                                ["y"] = 103758.16186749,
                                                ["x"] = 191449.96139918,
                                            }, -- end of [360]
                                            [424] = 
                                            {
                                                ["y"] = 102577.44650365,
                                                ["x"] = 191606.06314995,
                                            }, -- end of [424]
                                            [411] = 
                                            {
                                                ["y"] = 102958.31135006,
                                                ["x"] = 191809.46351102,
                                            }, -- end of [411]
                                            [407] = 
                                            {
                                                ["y"] = 102977.37657102,
                                                ["x"] = 191803.59028429,
                                            }, -- end of [407]
                                            [403] = 
                                            {
                                                ["y"] = 103005.2063479,
                                                ["x"] = 191782.62320102,
                                            }, -- end of [403]
                                            [399] = 
                                            {
                                                ["y"] = 103173.1750741,
                                                ["x"] = 191855.07184297,
                                            }, -- end of [399]
                                            [395] = 
                                            {
                                                ["y"] = 103233.10241243,
                                                ["x"] = 191879.89834542,
                                            }, -- end of [395]
                                            [297] = 
                                            {
                                                ["y"] = 103957.93813615,
                                                ["x"] = 191093.30621415,
                                            }, -- end of [297]
                                            [361] = 
                                            {
                                                ["y"] = 103754.61394154,
                                                ["x"] = 191453.47983014,
                                            }, -- end of [361]
                                            [425] = 
                                            {
                                                ["y"] = 102570.63928866,
                                                ["x"] = 191613.38285777,
                                            }, -- end of [425]
                                            [387] = 
                                            {
                                                ["y"] = 103449.85207129,
                                                ["x"] = 191859.87443799,
                                            }, -- end of [387]
                                            [149] = 
                                            {
                                                ["y"] = 103605.00935532,
                                                ["x"] = 188956.2965665,
                                            }, -- end of [149]
                                            [181] = 
                                            {
                                                ["y"] = 103991.41911215,
                                                ["x"] = 189700.81052681,
                                            }, -- end of [181]
                                            [213] = 
                                            {
                                                ["y"] = 104244.32456955,
                                                ["x"] = 190165.69892769,
                                            }, -- end of [213]
                                            [245] = 
                                            {
                                                ["y"] = 104283.42387556,
                                                ["x"] = 190572.61545514,
                                            }, -- end of [245]
                                            [298] = 
                                            {
                                                ["y"] = 103960.28393769,
                                                ["x"] = 191097.55282068,
                                            }, -- end of [298]
                                            [362] = 
                                            {
                                                ["y"] = 103751.50643415,
                                                ["x"] = 191457.39379995,
                                            }, -- end of [362]
                                            [426] = 
                                            {
                                                ["y"] = 102564.52120863,
                                                ["x"] = 191621.29122126,
                                            }, -- end of [426]
                                            [383] = 
                                            {
                                                ["y"] = 103523.35653367,
                                                ["x"] = 191847.20152511,
                                            }, -- end of [383]
                                            [382] = 
                                            {
                                                ["y"] = 103526.60276265,
                                                ["x"] = 191843.47747057,
                                            }, -- end of [382]
                                            [381] = 
                                            {
                                                ["y"] = 103528.56995519,
                                                ["x"] = 191838.89851946,
                                            }, -- end of [381]
                                            [415] = 
                                            {
                                                ["y"] = 102928.44060864,
                                                ["x"] = 191810.98681507,
                                            }, -- end of [415]
                                            [107] = 
                                            {
                                                ["y"] = 103346.52756191,
                                                ["x"] = 188379.5502283,
                                            }, -- end of [107]
                                            [75] = 
                                            {
                                                ["y"] = 103189.67822421,
                                                ["x"] = 188080.8479562,
                                            }, -- end of [75]
                                            [91] = 
                                            {
                                                ["y"] = 103292.37774802,
                                                ["x"] = 188248.45264329,
                                            }, -- end of [91]
                                            [427] = 
                                            {
                                                ["y"] = 102563.45736525,
                                                ["x"] = 191622.73465685,
                                            }, -- end of [427]
                                            [123] = 
                                            {
                                                ["y"] = 103417.75931089,
                                                ["x"] = 188480.76372785,
                                            }, -- end of [123]
                                            [150] = 
                                            {
                                                ["y"] = 103604.06160706,
                                                ["x"] = 188966.24953214,
                                            }, -- end of [150]
                                            [182] = 
                                            {
                                                ["y"] = 103994.56344915,
                                                ["x"] = 189710.30220951,
                                            }, -- end of [182]
                                            [214] = 
                                            {
                                                ["y"] = 104243.73667324,
                                                ["x"] = 190170.65616391,
                                            }, -- end of [214]
                                            [246] = 
                                            {
                                                ["y"] = 104286.46621428,
                                                ["x"] = 190576.57032565,
                                            }, -- end of [246]
                                            [300] = 
                                            {
                                                ["y"] = 103970.70466459,
                                                ["x"] = 191108.13784516,
                                            }, -- end of [300]
                                            [364] = 
                                            {
                                                ["y"] = 103743.67101324,
                                                ["x"] = 191470.17526218,
                                            }, -- end of [364]
                                            [254] = 
                                            {
                                                ["y"] = 104191.81720791,
                                                ["x"] = 190736.85190406,
                                            }, -- end of [254]
                                            [267] = 
                                            {
                                                ["y"] = 104163.59290546,
                                                ["x"] = 190987.85903097,
                                            }, -- end of [267]
                                            [291] = 
                                            {
                                                ["y"] = 103985.17644877,
                                                ["x"] = 191096.62370615,
                                            }, -- end of [291]
                                            [295] = 
                                            {
                                                ["y"] = 103963.15577739,
                                                ["x"] = 191085.55756709,
                                            }, -- end of [295]
                                            [323] = 
                                            {
                                                ["y"] = 103857.50226121,
                                                ["x"] = 191239.44332916,
                                            }, -- end of [323]
                                            [347] = 
                                            {
                                                ["y"] = 103810.39767547,
                                                ["x"] = 191408.93195433,
                                            }, -- end of [347]
                                            [301] = 
                                            {
                                                ["y"] = 103980.22498491,
                                                ["x"] = 191125.71816733,
                                            }, -- end of [301]
                                            [365] = 
                                            {
                                                ["y"] = 103717.972038,
                                                ["x"] = 191518.79357714,
                                            }, -- end of [365]
                                            [355] = 
                                            {
                                                ["y"] = 103786.70967758,
                                                ["x"] = 191444.47222985,
                                            }, -- end of [355]
                                            [76] = 
                                            {
                                                ["y"] = 103193.50157089,
                                                ["x"] = 188084.01256001,
                                            }, -- end of [76]
                                            [151] = 
                                            {
                                                ["y"] = 103604.21084647,
                                                ["x"] = 188971.24489428,
                                            }, -- end of [151]
                                            [183] = 
                                            {
                                                ["y"] = 103999.99932325,
                                                ["x"] = 189729.54734241,
                                            }, -- end of [183]
                                            [215] = 
                                            {
                                                ["y"] = 104242.39196521,
                                                ["x"] = 190175.46929332,
                                            }, -- end of [215]
                                            [247] = 
                                            {
                                                ["y"] = 104288.28417035,
                                                ["x"] = 190581.20472322,
                                            }, -- end of [247]
                                            [19] = 
                                            {
                                                ["y"] = 102944.53261177,
                                                ["x"] = 187868.4099429,
                                            }, -- end of [19]
                                            [23] = 
                                            {
                                                ["y"] = 102927.92454261,
                                                ["x"] = 187904.28287057,
                                            }, -- end of [23]
                                            [27] = 
                                            {
                                                ["y"] = 102935.49529533,
                                                ["x"] = 187922.25283436,
                                            }, -- end of [27]
                                            [31] = 
                                            {
                                                ["y"] = 102948.91758424,
                                                ["x"] = 187936.8928658,
                                            }, -- end of [31]
                                            [38] = 
                                            {
                                                ["y"] = 102985.01146138,
                                                ["x"] = 187990.03689385,
                                            }, -- end of [38]
                                            [46] = 
                                            {
                                                ["y"] = 103073.10044273,
                                                ["x"] = 188022.74066118,
                                            }, -- end of [46]
                                            [54] = 
                                            {
                                                ["y"] = 103130.70706636,
                                                ["x"] = 188009.23008095,
                                            }, -- end of [54]
                                            [62] = 
                                            {
                                                ["y"] = 103157.16633903,
                                                ["x"] = 188027.84925102,
                                            }, -- end of [62]
                                            [303] = 
                                            {
                                                ["y"] = 103982.72826129,
                                                ["x"] = 191135.35453741,
                                            }, -- end of [303]
                                            [92] = 
                                            {
                                                ["y"] = 103294.63799057,
                                                ["x"] = 188252.9096909,
                                            }, -- end of [92]
                                            [108] = 
                                            {
                                                ["y"] = 103358.12782386,
                                                ["x"] = 188389.04520046,
                                            }, -- end of [108]
                                            [124] = 
                                            {
                                                ["y"] = 103422.52651357,
                                                ["x"] = 188482.26161274,
                                            }, -- end of [124]
                                            [152] = 
                                            {
                                                ["y"] = 103606.31501831,
                                                ["x"] = 188996.13016939,
                                            }, -- end of [152]
                                            [184] = 
                                            {
                                                ["y"] = 104001.90684186,
                                                ["x"] = 189739.35872076,
                                            }, -- end of [184]
                                            [216] = 
                                            {
                                                ["y"] = 104237.0495219,
                                                ["x"] = 190189.48444149,
                                            }, -- end of [216]
                                            [248] = 
                                            {
                                                ["y"] = 104288.40591291,
                                                ["x"] = 190586.16153454,
                                            }, -- end of [248]
                                            [304] = 
                                            {
                                                ["y"] = 103982.90490892,
                                                ["x"] = 191140.34868678,
                                            }, -- end of [304]
                                            [368] = 
                                            {
                                                ["y"] = 103702.96810547,
                                                ["x"] = 191538.76975044,
                                            }, -- end of [368]
                                            [367] = 
                                            {
                                                ["y"] = 103712.18112869,
                                                ["x"] = 191526.93748548,
                                            }, -- end of [367]
                                            [366] = 
                                            {
                                                ["y"] = 103715.20212553,
                                                ["x"] = 191522.95440262,
                                            }, -- end of [366]
                                            [363] = 
                                            {
                                                ["y"] = 103748.72594811,
                                                ["x"] = 191461.54828851,
                                            }, -- end of [363]
                                            [359] = 
                                            {
                                                ["y"] = 103762.17412865,
                                                ["x"] = 191446.99434074,
                                            }, -- end of [359]
                                            [351] = 
                                            {
                                                ["y"] = 103797.20633921,
                                                ["x"] = 191422.61167561,
                                            }, -- end of [351]
                                            [350] = 
                                            {
                                                ["y"] = 103799.55934393,
                                                ["x"] = 191418.30388066,
                                            }, -- end of [350]
                                            [305] = 
                                            {
                                                ["y"] = 103982.57392667,
                                                ["x"] = 191145.33666649,
                                            }, -- end of [305]
                                            [369] = 
                                            {
                                                ["y"] = 103697.60996488,
                                                ["x"] = 191547.21103273,
                                            }, -- end of [369]
                                            [343] = 
                                            {
                                                ["y"] = 103815.57428378,
                                                ["x"] = 191350.26315221,
                                            }, -- end of [343]
                                            [339] = 
                                            {
                                                ["y"] = 103788.57837776,
                                                ["x"] = 191314.48247666,
                                            }, -- end of [339]
                                            [153] = 
                                            {
                                                ["y"] = 103606.02532428,
                                                ["x"] = 189006.11692443,
                                            }, -- end of [153]
                                            [185] = 
                                            {
                                                ["y"] = 104003.71483973,
                                                ["x"] = 189754.24601491,
                                            }, -- end of [185]
                                            [217] = 
                                            {
                                                ["y"] = 104226.90204696,
                                                ["x"] = 190212.32992943,
                                            }, -- end of [217]
                                            [249] = 
                                            {
                                                ["y"] = 104286.09323504,
                                                ["x"] = 190590.55189978,
                                            }, -- end of [249]
                                            [306] = 
                                            {
                                                ["y"] = 103981.8662646,
                                                ["x"] = 191150.28536253,
                                            }, -- end of [306]
                                            [370] = 
                                            {
                                                ["y"] = 103652.63116222,
                                                ["x"] = 191625.15929059,
                                            }, -- end of [370]
                                            [335] = 
                                            {
                                                ["y"] = 103767.91037306,
                                                ["x"] = 191222.77832533,
                                            }, -- end of [335]
                                            [375] = 
                                            {
                                                ["y"] = 103537.35426744,
                                                ["x"] = 191800.26231348,
                                            }, -- end of [375]
                                            [311] = 
                                            {
                                                ["y"] = 103972.72828488,
                                                ["x"] = 191173.37280654,
                                            }, -- end of [311]
                                            [331] = 
                                            {
                                                ["y"] = 103786.91300082,
                                                ["x"] = 191224.38549926,
                                            }, -- end of [331]
                                            [327] = 
                                            {
                                                ["y"] = 103827.86126798,
                                                ["x"] = 191242.64755688,
                                            }, -- end of [327]
                                            [371] = 
                                            {
                                                ["y"] = 103640.40788848,
                                                ["x"] = 191646.96217338,
                                            }, -- end of [371]
                                            [77] = 
                                            {
                                                ["y"] = 103196.12064494,
                                                ["x"] = 188088.25881447,
                                            }, -- end of [77]
                                            [93] = 
                                            {
                                                ["y"] = 103296.55543184,
                                                ["x"] = 188257.52701221,
                                            }, -- end of [93]
                                            [109] = 
                                            {
                                                ["y"] = 103361.44787768,
                                                ["x"] = 188392.77837533,
                                            }, -- end of [109]
                                            [125] = 
                                            {
                                                ["y"] = 103432.23641964,
                                                ["x"] = 188484.64448966,
                                            }, -- end of [125]
                                            [154] = 
                                            {
                                                ["y"] = 103606.23193155,
                                                ["x"] = 189011.11307918,
                                            }, -- end of [154]
                                            [186] = 
                                            {
                                                ["y"] = 104004.98570724,
                                                ["x"] = 189759.07673923,
                                            }, -- end of [186]
                                            [218] = 
                                            {
                                                ["y"] = 104222.39630085,
                                                ["x"] = 190221.25519183,
                                            }, -- end of [218]
                                            [250] = 
                                            {
                                                ["y"] = 104214.70623033,
                                                ["x"] = 190686.97301477,
                                            }, -- end of [250]
                                            [308] = 
                                            {
                                                ["y"] = 103979.33566563,
                                                ["x"] = 191159.94922617,
                                            }, -- end of [308]
                                            [372] = 
                                            {
                                                ["y"] = 103613.23995519,
                                                ["x"] = 191688.93370181,
                                            }, -- end of [372]
                                            [319] = 
                                            {
                                                ["y"] = 103895.39061589,
                                                ["x"] = 191227.06684427,
                                            }, -- end of [319]
                                            [318] = 
                                            {
                                                ["y"] = 103921.95353538,
                                                ["x"] = 191213.12980679,
                                            }, -- end of [318]
                                            [317] = 
                                            {
                                                ["y"] = 103934.75680274,
                                                ["x"] = 191205.31934726,
                                            }, -- end of [317]
                                            [419] = 
                                            {
                                                ["y"] = 102891.01215675,
                                                ["x"] = 191797.30274842,
                                            }, -- end of [419]
                                            [255] = 
                                            {
                                                ["y"] = 104182.11139265,
                                                ["x"] = 190770.47486858,
                                            }, -- end of [255]
                                            [270] = 
                                            {
                                                ["y"] = 104134.7662189,
                                                ["x"] = 190995.6374604,
                                            }, -- end of [270]
                                            [309] = 
                                            {
                                                ["y"] = 103977.50501871,
                                                ["x"] = 191164.60082787,
                                            }, -- end of [309]
                                            [373] = 
                                            {
                                                ["y"] = 103543.59268112,
                                                ["x"] = 191786.63104274,
                                            }, -- end of [373]
                                            [334] = 
                                            {
                                                ["y"] = 103772.42401887,
                                                ["x"] = 191220.88576548,
                                            }, -- end of [334]
                                            [307] = 
                                            {
                                                ["y"] = 103980.79018375,
                                                ["x"] = 191155.16688073,
                                            }, -- end of [307]
                                            [155] = 
                                            {
                                                ["y"] = 103607.29276222,
                                                ["x"] = 189015.98519764,
                                            }, -- end of [155]
                                            [187] = 
                                            {
                                                ["y"] = 104006.80545313,
                                                ["x"] = 189763.73265677,
                                            }, -- end of [187]
                                            [219] = 
                                            {
                                                ["y"] = 104219.79795655,
                                                ["x"] = 190225.52624876,
                                            }, -- end of [219]
                                            [251] = 
                                            {
                                                ["y"] = 104212.21405543,
                                                ["x"] = 190691.30491025,
                                            }, -- end of [251]
                                            [310] = 
                                            {
                                                ["y"] = 103975.30163535,
                                                ["x"] = 191169.08728436,
                                            }, -- end of [310]
                                            [374] = 
                                            {
                                                ["y"] = 103541.32185151,
                                                ["x"] = 191791.0838799,
                                            }, -- end of [374]
                                            [302] = 
                                            {
                                                ["y"] = 103981.86574428,
                                                ["x"] = 191130.43547717,
                                            }, -- end of [302]
                                            [299] = 
                                            {
                                                ["y"] = 103967.89649227,
                                                ["x"] = 191104.0086457,
                                            }, -- end of [299]
                                            [39] = 
                                            {
                                                ["y"] = 102993.10137352,
                                                ["x"] = 187995.9106855,
                                            }, -- end of [39]
                                            [47] = 
                                            {
                                                ["y"] = 103078.0791942,
                                                ["x"] = 188023.19599005,
                                            }, -- end of [47]
                                            [55] = 
                                            {
                                                ["y"] = 103135.52882468,
                                                ["x"] = 188007.92921251,
                                            }, -- end of [55]
                                            [63] = 
                                            {
                                                ["y"] = 103157.08809282,
                                                ["x"] = 188032.84487639,
                                            }, -- end of [63]
                                            [78] = 
                                            {
                                                ["y"] = 103198.05476745,
                                                ["x"] = 188092.86931343,
                                            }, -- end of [78]
                                            [94] = 
                                            {
                                                ["y"] = 103301.47830157,
                                                ["x"] = 188271.6948254,
                                            }, -- end of [94]
                                            [110] = 
                                            {
                                                ["y"] = 103364.15531874,
                                                ["x"] = 188396.97185183,
                                            }, -- end of [110]
                                            [126] = 
                                            {
                                                ["y"] = 103436.90503757,
                                                ["x"] = 188486.42414332,
                                            }, -- end of [126]
                                            [156] = 
                                            {
                                                ["y"] = 103609.00969572,
                                                ["x"] = 189020.6816062,
                                            }, -- end of [156]
                                            [188] = 
                                            {
                                                ["y"] = 104017.68911749,
                                                ["x"] = 189786.23853209,
                                            }, -- end of [188]
                                            [220] = 
                                            {
                                                ["y"] = 104217.17659926,
                                                ["x"] = 190229.78330173,
                                            }, -- end of [220]
                                            [252] = 
                                            {
                                                ["y"] = 104196.7168156,
                                                ["x"] = 190722.68390247,
                                            }, -- end of [252]
                                            [312] = 
                                            {
                                                ["y"] = 103969.79449263,
                                                ["x"] = 191177.41923517,
                                            }, -- end of [312]
                                            [376] = 
                                            {
                                                ["y"] = 103531.96904615,
                                                ["x"] = 191814.26002344,
                                            }, -- end of [376]
                                            [287] = 
                                            {
                                                ["y"] = 104004.03230291,
                                                ["x"] = 191102.27121158,
                                            }, -- end of [287]
                                            [286] = 
                                            {
                                                ["y"] = 104009.00906169,
                                                ["x"] = 191101.85494569,
                                            }, -- end of [286]
                                            [283] = 
                                            {
                                                ["y"] = 104033.10246307,
                                                ["x"] = 191095.32506293,
                                            }, -- end of [283]
                                            [279] = 
                                            {
                                                ["y"] = 104059.53830046,
                                                ["x"] = 191081.25063381,
                                            }, -- end of [279]
                                            [275] = 
                                            {
                                                ["y"] = 104110.10569737,
                                                ["x"] = 191019.5518502,
                                            }, -- end of [275]
                                            [271] = 
                                            {
                                                ["y"] = 104130.18650979,
                                                ["x"] = 190997.63821173,
                                            }, -- end of [271]
                                            [313] = 
                                            {
                                                ["y"] = 103966.53181216,
                                                ["x"] = 191181.20577388,
                                            }, -- end of [313]
                                            [377] = 
                                            {
                                                ["y"] = 103530.59772518,
                                                ["x"] = 191819.06575585,
                                            }, -- end of [377]
                                            [263] = 
                                            {
                                                ["y"] = 104180.0603902,
                                                ["x"] = 190979.16383785,
                                            }, -- end of [263]
                                            [259] = 
                                            {
                                                ["y"] = 104173.33871288,
                                                ["x"] = 190849.77611156,
                                            }, -- end of [259]
                                            [157] = 
                                            {
                                                ["y"] = 103620.42338551,
                                                ["x"] = 189048.41773947,
                                            }, -- end of [157]
                                            [189] = 
                                            {
                                                ["y"] = 104028.88146608,
                                                ["x"] = 189808.58462221,
                                            }, -- end of [189]
                                            [221] = 
                                            {
                                                ["y"] = 104214.97845522,
                                                ["x"] = 190234.27106561,
                                            }, -- end of [221]
                                            [253] = 
                                            {
                                                ["y"] = 104194.8890803,
                                                ["x"] = 190727.33641612,
                                            }, -- end of [253]
                                            [314] = 
                                            {
                                                ["y"] = 103963.01233625,
                                                ["x"] = 191184.75679157,
                                            }, -- end of [314]
                                            [378] = 
                                            {
                                                ["y"] = 103529.79632659,
                                                ["x"] = 191823.99784516,
                                            }, -- end of [378]
                                            [239] = 
                                            {
                                                ["y"] = 104264.4047035,
                                                ["x"] = 190549.63639801,
                                            }, -- end of [239]
                                            [223] = 
                                            {
                                                ["y"] = 104204.72515491,
                                                ["x"] = 190262.4617684,
                                            }, -- end of [223]
                                            [207] = 
                                            {
                                                ["y"] = 104197.35172871,
                                                ["x"] = 189951.51708306,
                                            }, -- end of [207]
                                            [191] = 
                                            {
                                                ["y"] = 104088.74370378,
                                                ["x"] = 189951.51655742,
                                            }, -- end of [191]
                                            [175] = 
                                            {
                                                ["y"] = 103915.59173011,
                                                ["x"] = 189590.87213652,
                                            }, -- end of [175]
                                            [159] = 
                                            {
                                                ["y"] = 103663.55954897,
                                                ["x"] = 189127.35607095,
                                            }, -- end of [159]
                                            [79] = 
                                            {
                                                ["y"] = 103201.99957976,
                                                ["x"] = 188102.04982017,
                                            }, -- end of [79]
                                            [95] = 
                                            {
                                                ["y"] = 103304.13768521,
                                                ["x"] = 188281.33083674,
                                            }, -- end of [95]
                                            [111] = 
                                            {
                                                ["y"] = 103366.20194461,
                                                ["x"] = 188401.53074185,
                                            }, -- end of [111]
                                            [143] = 
                                            {
                                                ["y"] = 103580.36837337,
                                                ["x"] = 188720.74745409,
                                            }, -- end of [143]
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            [1] = 
                                            {
                                                ["y"] = 98130.607278722,
                                                ["x"] = 188082.93512168,
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["y"] = 98130.607278722,
                                                ["x"] = 188082.93512168,
                                            }, -- end of [2]
                                        }, -- end of [2]
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 323.05726937534,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 102911.58716738,
                                            ["x"] = 187666.3742192,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 4,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2303.1648673878,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 102562.07097277,
                                            ["x"] = 191621.666754,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 2.7777777777778,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 16,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 42,
                                        ["y"] = 102911.58716738,
                                        ["x"] = 187666.3742192,
                                        ["name"] = "Invaders One-1-7",
                                        ["heading"] = 0.31173820448712,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 43,
                                        ["y"] = 102910.32740333,
                                        ["x"] = 187636.68547846,
                                        ["name"] = "Invaders One-1-8",
                                        ["heading"] = 0.042406944954126,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 44,
                                        ["y"] = 102902.76207095,
                                        ["x"] = 187608.63011621,
                                        ["name"] = "Invaders One-1-9",
                                        ["heading"] = 0.26339236384827,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [3]
                                    [4] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "T-90",
                                        ["unitId"] = 45,
                                        ["y"] = 102893.33067081,
                                        ["x"] = 187580.26953996,
                                        ["name"] = "Invaders One-1-10",
                                        ["heading"] = 0.32104826234622,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [4]
                                    [5] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Gepard",
                                        ["unitId"] = 46,
                                        ["y"] = 102882.29674031,
                                        ["x"] = 187552.42748652,
                                        ["name"] = "Invaders One-1-11",
                                        ["heading"] = 0.37731652957087,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [5]
                                    [6] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 47,
                                        ["y"] = 102871.89417649,
                                        ["x"] = 187524.31143006,
                                        ["name"] = "Invaders One-1-12",
                                        ["heading"] = 0.3543681228139,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [6]
                                }, -- end of ["units"]
                                ["y"] = 102911.58716738,
                                ["x"] = 187666.3742192,
                                ["name"] = "Invaders One-1",
                                ["start_time"] = 0,
                            }, -- end of [8]
                            [9] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 203.67540560883,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 105196.57242958,
                                            ["x"] = 189490.45314515,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "Off Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 27,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland Radar",
                                        ["unitId"] = 61,
                                        ["y"] = 105196.57242958,
                                        ["x"] = 189490.45314515,
                                        ["name"] = "AAA One-3-1",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland ADS",
                                        ["unitId"] = 62,
                                        ["y"] = 105212.43389131,
                                        ["x"] = 189499.40290847,
                                        ["name"] = "AAA One-3-2",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland ADS",
                                        ["unitId"] = 63,
                                        ["y"] = 105215.26945988,
                                        ["x"] = 189481.06032424,
                                        ["name"] = "AAA One-3-3",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [3]
                                }, -- end of ["units"]
                                ["y"] = 105196.57242958,
                                ["x"] = 189490.45314515,
                                ["name"] = "AAA One-3",
                                ["start_time"] = 0,
                            }, -- end of [9]
                            [10] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 1,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 100050.73458182,
                                            ["x"] = 193732.04177405,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "Off Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 37,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "SA-18 Igla manpad",
                                        ["unitId"] = 75,
                                        ["y"] = 100050.73458182,
                                        ["x"] = 193732.04177405,
                                        ["name"] = "Sneaky Beachy-1",
                                        ["heading"] = 2.164208272473,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "SA-18 Igla manpad",
                                        ["unitId"] = 76,
                                        ["y"] = 100040.98517448,
                                        ["x"] = 193725.33113897,
                                        ["name"] = "Sneaky Beachy-2",
                                        ["heading"] = 3.5255650890285,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [2]
                                }, -- end of ["units"]
                                ["y"] = 100050.73458182,
                                ["x"] = 193732.04177405,
                                ["name"] = "Sneaky Beachy",
                                ["start_time"] = 0,
                            }, -- end of [10]
                            [11] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 39,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 111429.60730939,
                                            ["x"] = 196971.9797653,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "Off Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 40,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 79,
                                        ["y"] = 111429.60730939,
                                        ["x"] = 196971.9797653,
                                        ["name"] = "Invaders Two-1-1",
                                        ["heading"] = 2.164208272473,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 80,
                                        ["y"] = 111369.72907014,
                                        ["x"] = 196843.28623616,
                                        ["name"] = "Guards-1",
                                        ["heading"] = 2.164208272473,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "M 818",
                                        ["unitId"] = 81,
                                        ["y"] = 111413.96747078,
                                        ["x"] = 196900.93021276,
                                        ["name"] = "Guards-2",
                                        ["heading"] = 2.164208272473,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [3]
                                    [4] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 82,
                                        ["y"] = 111415.75488091,
                                        ["x"] = 196820.49675704,
                                        ["name"] = "Guards-3",
                                        ["heading"] = 2.164208272473,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [4]
                                    [5] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 83,
                                        ["y"] = 111459.09957649,
                                        ["x"] = 196841.0519735,
                                        ["name"] = "Guards-4",
                                        ["heading"] = 2.164208272473,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [5]
                                    [6] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "ATZ-5",
                                        ["unitId"] = 84,
                                        ["y"] = 111410.39265053,
                                        ["x"] = 196887.5246368,
                                        ["name"] = "Guards-5",
                                        ["heading"] = 2.164208272473,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [6]
                                }, -- end of ["units"]
                                ["y"] = 111429.60730939,
                                ["x"] = 196971.9797653,
                                ["name"] = "Guards",
                                ["start_time"] = 0,
                            }, -- end of [11]
                            [12] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                        [1] = 
                                        {
                                            [127] = 
                                            {
                                                ["y"] = 110563.76612091,
                                                ["x"] = 196481.45411655,
                                            }, -- end of [127]
                                            [158] = 
                                            {
                                                ["y"] = 109959.04966411,
                                                ["x"] = 196691.51417441,
                                            }, -- end of [158]
                                            [190] = 
                                            {
                                                ["y"] = 109462.19961484,
                                                ["x"] = 196568.95006025,
                                            }, -- end of [190]
                                            [222] = 
                                            {
                                                ["y"] = 109130.67407981,
                                                ["x"] = 196467.75043623,
                                            }, -- end of [222]
                                            [1] = 
                                            {
                                                ["y"] = 110779.13665966,
                                                ["x"] = 195854.6905806,
                                            }, -- end of [1]
                                            [316] = 
                                            {
                                                ["y"] = 103235.30552118,
                                                ["x"] = 191880.50326973,
                                            }, -- end of [316]
                                            [2] = 
                                            {
                                                ["y"] = 111148.37034709,
                                                ["x"] = 196065.04699406,
                                            }, -- end of [2]
                                            [3] = 
                                            {
                                                ["y"] = 111156.55617389,
                                                ["x"] = 196070.78794999,
                                            }, -- end of [3]
                                            [4] = 
                                            {
                                                ["y"] = 111180.33773966,
                                                ["x"] = 196089.06712765,
                                            }, -- end of [4]
                                            [5] = 
                                            {
                                                ["y"] = 111187.69561321,
                                                ["x"] = 196095.83780606,
                                            }, -- end of [5]
                                            [6] = 
                                            {
                                                ["y"] = 111191.18450403,
                                                ["x"] = 196099.41775346,
                                            }, -- end of [6]
                                            [7] = 
                                            {
                                                ["y"] = 111194.33002834,
                                                ["x"] = 196103.30126613,
                                            }, -- end of [7]
                                            [8] = 
                                            {
                                                ["y"] = 111197.07994268,
                                                ["x"] = 196107.47528926,
                                            }, -- end of [8]
                                            [10] = 
                                            {
                                                ["y"] = 111201.53216336,
                                                ["x"] = 196116.41670117,
                                            }, -- end of [10]
                                            [12] = 
                                            {
                                                ["y"] = 111206.26131745,
                                                ["x"] = 196130.63690319,
                                            }, -- end of [12]
                                            [14] = 
                                            {
                                                ["y"] = 111207.39435451,
                                                ["x"] = 196140.5536444,
                                            }, -- end of [14]
                                            [16] = 
                                            {
                                                ["y"] = 111206.3246406,
                                                ["x"] = 196150.47880037,
                                            }, -- end of [16]
                                            [20] = 
                                            {
                                                ["y"] = 111198.24701334,
                                                ["x"] = 196168.51995325,
                                            }, -- end of [20]
                                            [24] = 
                                            {
                                                ["y"] = 111182.50624143,
                                                ["x"] = 196180.74401662,
                                            }, -- end of [24]
                                            [28] = 
                                            {
                                                ["y"] = 111163.49249621,
                                                ["x"] = 196186.57919625,
                                            }, -- end of [28]
                                            [32] = 
                                            {
                                                ["y"] = 111143.55932281,
                                                ["x"] = 196187.23010269,
                                            }, -- end of [32]
                                            [40] = 
                                            {
                                                ["y"] = 111020.19920892,
                                                ["x"] = 196148.4790403,
                                            }, -- end of [40]
                                            [48] = 
                                            {
                                                ["y"] = 110982.70450298,
                                                ["x"] = 196161.01168384,
                                            }, -- end of [48]
                                            [56] = 
                                            {
                                                ["y"] = 110960.38961658,
                                                ["x"] = 196193.34441282,
                                            }, -- end of [56]
                                            [64] = 
                                            {
                                                ["y"] = 110960.98344276,
                                                ["x"] = 196303.5571858,
                                            }, -- end of [64]
                                            [80] = 
                                            {
                                                ["y"] = 110671.48166561,
                                                ["x"] = 196197.3049291,
                                            }, -- end of [80]
                                            [96] = 
                                            {
                                                ["y"] = 110443.30802896,
                                                ["x"] = 196267.29175331,
                                            }, -- end of [96]
                                            [112] = 
                                            {
                                                ["y"] = 110421.69681785,
                                                ["x"] = 196345.03856139,
                                            }, -- end of [112]
                                            [128] = 
                                            {
                                                ["y"] = 110561.64926057,
                                                ["x"] = 196485.97850849,
                                            }, -- end of [128]
                                            [160] = 
                                            {
                                                ["y"] = 109955.51464462,
                                                ["x"] = 196676.94715657,
                                            }, -- end of [160]
                                            [192] = 
                                            {
                                                ["y"] = 109452.4091292,
                                                ["x"] = 196566.952286,
                                            }, -- end of [192]
                                            [224] = 
                                            {
                                                ["y"] = 109095.72106411,
                                                ["x"] = 196469.24598089,
                                            }, -- end of [224]
                                            [256] = 
                                            {
                                                ["y"] = 108372.7612695,
                                                ["x"] = 196107.52148321,
                                            }, -- end of [256]
                                            [320] = 
                                            {
                                                ["y"] = 103175.19399553,
                                                ["x"] = 191856.14130821,
                                            }, -- end of [320]
                                            [257] = 
                                            {
                                                ["y"] = 108351.30290071,
                                                ["x"] = 196079.89372801,
                                            }, -- end of [257]
                                            [321] = 
                                            {
                                                ["y"] = 103112.94953606,
                                                ["x"] = 191824.14452128,
                                            }, -- end of [321]
                                            [129] = 
                                            {
                                                ["y"] = 110558.98577598,
                                                ["x"] = 196490.20799622,
                                            }, -- end of [129]
                                            [161] = 
                                            {
                                                ["y"] = 109952.36017072,
                                                ["x"] = 196667.46122558,
                                            }, -- end of [161]
                                            [193] = 
                                            {
                                                ["y"] = 109447.64614012,
                                                ["x"] = 196565.43505953,
                                            }, -- end of [193]
                                            [225] = 
                                            {
                                                ["y"] = 109035.82348262,
                                                ["x"] = 196472.58314744,
                                            }, -- end of [225]
                                            [258] = 
                                            {
                                                ["y"] = 108344.84469585,
                                                ["x"] = 196072.27758212,
                                            }, -- end of [258]
                                            [322] = 
                                            {
                                                ["y"] = 102984.78296911,
                                                ["x"] = 191767.84155537,
                                            }, -- end of [322]
                                            [65] = 
                                            {
                                                ["y"] = 110957.1757971,
                                                ["x"] = 196306.79629393,
                                            }, -- end of [65]
                                            [81] = 
                                            {
                                                ["y"] = 110661.60106522,
                                                ["x"] = 196195.78757367,
                                            }, -- end of [81]
                                            [97] = 
                                            {
                                                ["y"] = 110433.7667571,
                                                ["x"] = 196270.28162674,
                                            }, -- end of [97]
                                            [113] = 
                                            {
                                                ["y"] = 110425.48930215,
                                                ["x"] = 196348.29246008,
                                            }, -- end of [113]
                                            [130] = 
                                            {
                                                ["y"] = 110555.94070197,
                                                ["x"] = 196494.17172782,
                                            }, -- end of [130]
                                            [162] = 
                                            {
                                                ["y"] = 109949.80755004,
                                                ["x"] = 196663.2241717,
                                            }, -- end of [162]
                                            [194] = 
                                            {
                                                ["y"] = 109443.00186396,
                                                ["x"] = 196563.58498323,
                                            }, -- end of [194]
                                            [226] = 
                                            {
                                                ["y"] = 108975.86362146,
                                                ["x"] = 196474.51014028,
                                            }, -- end of [226]
                                            [260] = 
                                            {
                                                ["y"] = 108319.04280399,
                                                ["x"] = 196029.462755,
                                            }, -- end of [260]
                                            [324] = 
                                            {
                                                ["y"] = 102976.45345346,
                                                ["x"] = 191762.33806014,
                                            }, -- end of [324]
                                            [261] = 
                                            {
                                                ["y"] = 108310.28603772,
                                                ["x"] = 196017.28745823,
                                            }, -- end of [261]
                                            [325] = 
                                            {
                                                ["y"] = 102972.68482779,
                                                ["x"] = 191759.05293804,
                                            }, -- end of [325]
                                            [131] = 
                                            {
                                                ["y"] = 110552.57050321,
                                                ["x"] = 196497.863284,
                                            }, -- end of [131]
                                            [163] = 
                                            {
                                                ["y"] = 109945.01441574,
                                                ["x"] = 196662.46107309,
                                            }, -- end of [163]
                                            [195] = 
                                            {
                                                ["y"] = 109438.50932701,
                                                ["x"] = 196561.39288108,
                                            }, -- end of [195]
                                            [227] = 
                                            {
                                                ["y"] = 108960.95281751,
                                                ["x"] = 196476.12785351,
                                            }, -- end of [227]
                                            [262] = 
                                            {
                                                ["y"] = 107429.09474927,
                                                ["x"] = 194841.0053292,
                                            }, -- end of [262]
                                            [326] = 
                                            {
                                                ["y"] = 102957.97404215,
                                                ["x"] = 191745.51920066,
                                            }, -- end of [326]
                                            [33] = 
                                            {
                                                ["y"] = 111138.65177254,
                                                ["x"] = 196186.28449501,
                                            }, -- end of [33]
                                            [41] = 
                                            {
                                                ["y"] = 111015.21936006,
                                                ["x"] = 196148.91815367,
                                            }, -- end of [41]
                                            [49] = 
                                            {
                                                ["y"] = 110978.7290874,
                                                ["x"] = 196164.04040612,
                                            }, -- end of [49]
                                            [57] = 
                                            {
                                                ["y"] = 110956.06942831,
                                                ["x"] = 196207.70776668,
                                            }, -- end of [57]
                                            [66] = 
                                            {
                                                ["y"] = 110953.12908482,
                                                ["x"] = 196309.73033959,
                                            }, -- end of [66]
                                            [82] = 
                                            {
                                                ["y"] = 110626.72634073,
                                                ["x"] = 196192.87087838,
                                            }, -- end of [82]
                                            [98] = 
                                            {
                                                ["y"] = 110424.42278428,
                                                ["x"] = 196273.83724252,
                                            }, -- end of [98]
                                            [114] = 
                                            {
                                                ["y"] = 110448.72966334,
                                                ["x"] = 196367.25702279,
                                            }, -- end of [114]
                                            [132] = 
                                            {
                                                ["y"] = 110548.92496966,
                                                ["x"] = 196501.28342805,
                                            }, -- end of [132]
                                            [164] = 
                                            {
                                                ["y"] = 109940.17362767,
                                                ["x"] = 196663.70555073,
                                            }, -- end of [164]
                                            [196] = 
                                            {
                                                ["y"] = 109429.91062187,
                                                ["x"] = 196556.29109829,
                                            }, -- end of [196]
                                            [228] = 
                                            {
                                                ["y"] = 108951.12364367,
                                                ["x"] = 196477.95069901,
                                            }, -- end of [228]
                                            [264] = 
                                            {
                                                ["y"] = 107366.50025145,
                                                ["x"] = 194776.35888416,
                                            }, -- end of [264]
                                            [328] = 
                                            {
                                                ["y"] = 102794.91194492,
                                                ["x"] = 191621.36054951,
                                            }, -- end of [328]
                                            [265] = 
                                            {
                                                ["y"] = 107339.97610713,
                                                ["x"] = 194753.5278094,
                                            }, -- end of [265]
                                            [329] = 
                                            {
                                                ["y"] = 102524.8270587,
                                                ["x"] = 191390.99734861,
                                            }, -- end of [329]
                                            [133] = 
                                            {
                                                ["y"] = 110541.17057285,
                                                ["x"] = 196507.59517946,
                                            }, -- end of [133]
                                            [165] = 
                                            {
                                                ["y"] = 109935.31733502,
                                                ["x"] = 196664.89151697,
                                            }, -- end of [165]
                                            [197] = 
                                            {
                                                ["y"] = 109421.67149769,
                                                ["x"] = 196550.62866253,
                                            }, -- end of [197]
                                            [229] = 
                                            {
                                                ["y"] = 108946.28062452,
                                                ["x"] = 196479.19172863,
                                            }, -- end of [229]
                                            [266] = 
                                            {
                                                ["y"] = 107305.00215733,
                                                ["x"] = 194725.21974175,
                                            }, -- end of [266]
                                            [330] = 
                                            {
                                                ["y"] = 102495.10880739,
                                                ["x"] = 191363.731093,
                                            }, -- end of [330]
                                            [67] = 
                                            {
                                                ["y"] = 110948.87795098,
                                                ["x"] = 196312.35924738,
                                            }, -- end of [67]
                                            [83] = 
                                            {
                                                ["y"] = 110621.7425599,
                                                ["x"] = 196193.19234134,
                                            }, -- end of [83]
                                            [99] = 
                                            {
                                                ["y"] = 110419.9251593,
                                                ["x"] = 196276.01876007,
                                            }, -- end of [99]
                                            [115] = 
                                            {
                                                ["y"] = 110517.50638161,
                                                ["x"] = 196425.2758384,
                                            }, -- end of [115]
                                            [134] = 
                                            {
                                                ["y"] = 110529.08313686,
                                                ["x"] = 196516.4741558,
                                            }, -- end of [134]
                                            [166] = 
                                            {
                                                ["y"] = 109930.37495265,
                                                ["x"] = 196665.64277242,
                                            }, -- end of [166]
                                            [198] = 
                                            {
                                                ["y"] = 109413.79056239,
                                                ["x"] = 196544.47653099,
                                            }, -- end of [198]
                                            [230] = 
                                            {
                                                ["y"] = 108941.50960878,
                                                ["x"] = 196480.68561643,
                                            }, -- end of [230]
                                            [268] = 
                                            {
                                                ["y"] = 107284.11710264,
                                                ["x"] = 194711.50392299,
                                            }, -- end of [268]
                                            [269] = 
                                            {
                                                ["y"] = 107270.89805891,
                                                ["x"] = 194704.41879883,
                                            }, -- end of [269]
                                            [135] = 
                                            {
                                                ["y"] = 110516.52953512,
                                                ["x"] = 196524.68124923,
                                            }, -- end of [135]
                                            [167] = 
                                            {
                                                ["y"] = 109925.38885377,
                                                ["x"] = 196665.98524154,
                                            }, -- end of [167]
                                            [199] = 
                                            {
                                                ["y"] = 109386.5462895,
                                                ["x"] = 196522.52233074,
                                            }, -- end of [199]
                                            [231] = 
                                            {
                                                ["y"] = 108936.84364644,
                                                ["x"] = 196482.47920999,
                                            }, -- end of [231]
                                            [17] = 
                                            {
                                                ["y"] = 111205.12936277,
                                                ["x"] = 196155.33271277,
                                            }, -- end of [17]
                                            [21] = 
                                            {
                                                ["y"] = 111194.66985735,
                                                ["x"] = 196172.00734077,
                                            }, -- end of [21]
                                            [25] = 
                                            {
                                                ["y"] = 111177.99883716,
                                                ["x"] = 196182.89980112,
                                            }, -- end of [25]
                                            [29] = 
                                            {
                                                ["y"] = 111158.52836119,
                                                ["x"] = 196187.17606993,
                                            }, -- end of [29]
                                            [34] = 
                                            {
                                                ["y"] = 111129.04099001,
                                                ["x"] = 196183.5220173,
                                            }, -- end of [34]
                                            [42] = 
                                            {
                                                ["y"] = 111010.28007416,
                                                ["x"] = 196149.68978535,
                                            }, -- end of [42]
                                            [50] = 
                                            {
                                                ["y"] = 110975.09615526,
                                                ["x"] = 196167.47221493,
                                            }, -- end of [50]
                                            [58] = 
                                            {
                                                ["y"] = 110955.17569629,
                                                ["x"] = 196212.62210721,
                                            }, -- end of [58]
                                            [68] = 
                                            {
                                                ["y"] = 110935.71625128,
                                                ["x"] = 196319.54749275,
                                            }, -- end of [68]
                                            [84] = 
                                            {
                                                ["y"] = 110616.83855148,
                                                ["x"] = 196194.16089501,
                                            }, -- end of [84]
                                            [100] = 
                                            {
                                                ["y"] = 110415.65890513,
                                                ["x"] = 196278.62038115,
                                            }, -- end of [100]
                                            [116] = 
                                            {
                                                ["y"] = 110521.64898982,
                                                ["x"] = 196428.07148622,
                                            }, -- end of [116]
                                            [136] = 
                                            {
                                                ["y"] = 110486.75361043,
                                                ["x"] = 196543.058383,
                                            }, -- end of [136]
                                            [168] = 
                                            {
                                                ["y"] = 109920.39010406,
                                                ["x"] = 196665.99796891,
                                            }, -- end of [168]
                                            [200] = 
                                            {
                                                ["y"] = 109378.18319125,
                                                ["x"] = 196517.04185554,
                                            }, -- end of [200]
                                            [232] = 
                                            {
                                                ["y"] = 108932.33155351,
                                                ["x"] = 196484.63059884,
                                            }, -- end of [232]
                                            [272] = 
                                            {
                                                ["y"] = 106125.48821587,
                                                ["x"] = 194079.43199794,
                                            }, -- end of [272]
                                            [273] = 
                                            {
                                                ["y"] = 106043.15542923,
                                                ["x"] = 194032.06812537,
                                            }, -- end of [273]
                                            [137] = 
                                            {
                                                ["y"] = 110455.9008859,
                                                ["x"] = 196559.56782408,
                                            }, -- end of [137]
                                            [169] = 
                                            {
                                                ["y"] = 109910.41205154,
                                                ["x"] = 196665.36405551,
                                            }, -- end of [169]
                                            [201] = 
                                            {
                                                ["y"] = 109373.83309418,
                                                ["x"] = 196514.5792317,
                                            }, -- end of [201]
                                            [233] = 
                                            {
                                                ["y"] = 108928.04914684,
                                                ["x"] = 196487.20616152,
                                            }, -- end of [233]
                                            [274] = 
                                            {
                                                ["y"] = 105372.41110819,
                                                ["x"] = 193664.30805424,
                                            }, -- end of [274]
                                            [69] = 
                                            {
                                                ["y"] = 110931.06371576,
                                                ["x"] = 196321.37183816,
                                            }, -- end of [69]
                                            [85] = 
                                            {
                                                ["y"] = 110592.61971652,
                                                ["x"] = 196200.24188034,
                                            }, -- end of [85]
                                            [101] = 
                                            {
                                                ["y"] = 110411.76577341,
                                                ["x"] = 196281.75153348,
                                            }, -- end of [101]
                                            [117] = 
                                            {
                                                ["y"] = 110530.30445018,
                                                ["x"] = 196433.07907049,
                                            }, -- end of [117]
                                            [138] = 
                                            {
                                                ["y"] = 110074.54776937,
                                                ["x"] = 196735.15739224,
                                            }, -- end of [138]
                                            [170] = 
                                            {
                                                ["y"] = 109900.49006866,
                                                ["x"] = 196664.12542082,
                                            }, -- end of [170]
                                            [202] = 
                                            {
                                                ["y"] = 109369.3118998,
                                                ["x"] = 196512.44579602,
                                            }, -- end of [202]
                                            [234] = 
                                            {
                                                ["y"] = 108924.08199602,
                                                ["x"] = 196490.24499381,
                                            }, -- end of [234]
                                            [276] = 
                                            {
                                                ["y"] = 104889.08987028,
                                                ["x"] = 193402.07396836,
                                            }, -- end of [276]
                                            [277] = 
                                            {
                                                ["y"] = 104826.97714083,
                                                ["x"] = 193351.6575576,
                                            }, -- end of [277]
                                            [139] = 
                                            {
                                                ["y"] = 110052.77403825,
                                                ["x"] = 196747.42949733,
                                            }, -- end of [139]
                                            [171] = 
                                            {
                                                ["y"] = 109885.74231946,
                                                ["x"] = 196661.40122588,
                                            }, -- end of [171]
                                            [203] = 
                                            {
                                                ["y"] = 109364.65868271,
                                                ["x"] = 196510.61863236,
                                            }, -- end of [203]
                                            [235] = 
                                            {
                                                ["y"] = 108920.47544141,
                                                ["x"] = 196493.70435239,
                                            }, -- end of [235]
                                            [278] = 
                                            {
                                                ["y"] = 104819.63599859,
                                                ["x"] = 193344.87651144,
                                            }, -- end of [278]
                                            [35] = 
                                            {
                                                ["y"] = 111110.0508813,
                                                ["x"] = 196177.25751318,
                                            }, -- end of [35]
                                            [43] = 
                                            {
                                                ["y"] = 111005.41032485,
                                                ["x"] = 196150.81857035,
                                            }, -- end of [43]
                                            [51] = 
                                            {
                                                ["y"] = 110971.8396572,
                                                ["x"] = 196171.26360312,
                                            }, -- end of [51]
                                            [59] = 
                                            {
                                                ["y"] = 110955.28012996,
                                                ["x"] = 196217.61211908,
                                            }, -- end of [59]
                                            [70] = 
                                            {
                                                ["y"] = 110926.15596118,
                                                ["x"] = 196322.36675203,
                                            }, -- end of [70]
                                            [86] = 
                                            {
                                                ["y"] = 110588.0698839,
                                                ["x"] = 196202.31665596,
                                            }, -- end of [86]
                                            [102] = 
                                            {
                                                ["y"] = 110408.39500085,
                                                ["x"] = 196285.43596663,
                                            }, -- end of [102]
                                            [118] = 
                                            {
                                                ["y"] = 110547.70365703,
                                                ["x"] = 196442.92657843,
                                            }, -- end of [118]
                                            [140] = 
                                            {
                                                ["y"] = 110048.0871457,
                                                ["x"] = 196749.15826636,
                                            }, -- end of [140]
                                            [172] = 
                                            {
                                                ["y"] = 109866.3464444,
                                                ["x"] = 196656.53266994,
                                            }, -- end of [172]
                                            [204] = 
                                            {
                                                ["y"] = 109359.89830673,
                                                ["x"] = 196509.09209567,
                                            }, -- end of [204]
                                            [236] = 
                                            {
                                                ["y"] = 108917.22279952,
                                                ["x"] = 196497.49990292,
                                            }, -- end of [236]
                                            [280] = 
                                            {
                                                ["y"] = 104651.48295107,
                                                ["x"] = 193146.61764397,
                                            }, -- end of [280]
                                            [281] = 
                                            {
                                                ["y"] = 104543.87388933,
                                                ["x"] = 193015.02700317,
                                            }, -- end of [281]
                                            [141] = 
                                            {
                                                ["y"] = 110043.19191466,
                                                ["x"] = 196750.14809082,
                                            }, -- end of [141]
                                            [173] = 
                                            {
                                                ["y"] = 109648.94145864,
                                                ["x"] = 196598.65107826,
                                            }, -- end of [173]
                                            [205] = 
                                            {
                                                ["y"] = 109355.05773048,
                                                ["x"] = 196507.84127634,
                                            }, -- end of [205]
                                            [237] = 
                                            {
                                                ["y"] = 108914.2766225,
                                                ["x"] = 196501.5383906,
                                            }, -- end of [237]
                                            [282] = 
                                            {
                                                ["y"] = 104156.24809648,
                                                ["x"] = 192550.56585553,
                                            }, -- end of [282]
                                            [71] = 
                                            {
                                                ["y"] = 110921.28399744,
                                                ["x"] = 196321.51989334,
                                            }, -- end of [71]
                                            [87] = 
                                            {
                                                ["y"] = 110552.44583532,
                                                ["x"] = 196220.48542822,
                                            }, -- end of [87]
                                            [103] = 
                                            {
                                                ["y"] = 110405.86270509,
                                                ["x"] = 196289.73365205,
                                            }, -- end of [103]
                                            [119] = 
                                            {
                                                ["y"] = 110551.63466429,
                                                ["x"] = 196446.0096855,
                                            }, -- end of [119]
                                            [142] = 
                                            {
                                                ["y"] = 110038.21024187,
                                                ["x"] = 196750.53928964,
                                            }, -- end of [142]
                                            [174] = 
                                            {
                                                ["y"] = 109644.33543676,
                                                ["x"] = 196596.71072732,
                                            }, -- end of [174]
                                            [206] = 
                                            {
                                                ["y"] = 109350.15098974,
                                                ["x"] = 196506.88433936,
                                            }, -- end of [206]
                                            [238] = 
                                            {
                                                ["y"] = 108911.57376385,
                                                ["x"] = 196505.74437582,
                                            }, -- end of [238]
                                            [284] = 
                                            {
                                                ["y"] = 104110.85076177,
                                                ["x"] = 192478.73645857,
                                            }, -- end of [284]
                                            [285] = 
                                            {
                                                ["y"] = 104106.13249362,
                                                ["x"] = 192469.92549061,
                                            }, -- end of [285]
                                            [9] = 
                                            {
                                                ["y"] = 111199.49506102,
                                                ["x"] = 196111.85243888,
                                            }, -- end of [9]
                                            [11] = 
                                            {
                                                ["y"] = 111204.92898191,
                                                ["x"] = 196125.81971138,
                                            }, -- end of [11]
                                            [13] = 
                                            {
                                                ["y"] = 111207.0912466,
                                                ["x"] = 196135.56584501,
                                            }, -- end of [13]
                                            [15] = 
                                            {
                                                ["y"] = 111207.1125524,
                                                ["x"] = 196145.54311349,
                                            }, -- end of [15]
                                            [18] = 
                                            {
                                                ["y"] = 111203.47712277,
                                                ["x"] = 196160.04921984,
                                            }, -- end of [18]
                                            [22] = 
                                            {
                                                ["y"] = 111190.79391159,
                                                ["x"] = 196175.16738667,
                                            }, -- end of [22]
                                            [26] = 
                                            {
                                                ["y"] = 111173.27017602,
                                                ["x"] = 196184.51902584,
                                            }, -- end of [26]
                                            [30] = 
                                            {
                                                ["y"] = 111153.54020303,
                                                ["x"] = 196187.52095955,
                                            }, -- end of [30]
                                            [36] = 
                                            {
                                                ["y"] = 111044.83744394,
                                                ["x"] = 196151.86963019,
                                            }, -- end of [36]
                                            [44] = 
                                            {
                                                ["y"] = 111000.63003869,
                                                ["x"] = 196152.28126304,
                                            }, -- end of [44]
                                            [52] = 
                                            {
                                                ["y"] = 110968.93401241,
                                                ["x"] = 196175.33120403,
                                            }, -- end of [52]
                                            [60] = 
                                            {
                                                ["y"] = 110957.58741451,
                                                ["x"] = 196232.43029479,
                                            }, -- end of [60]
                                            [72] = 
                                            {
                                                ["y"] = 110916.80765676,
                                                ["x"] = 196319.32643319,
                                            }, -- end of [72]
                                            [88] = 
                                            {
                                                ["y"] = 110548.31349349,
                                                ["x"] = 196223.29471036,
                                            }, -- end of [88]
                                            [104] = 
                                            {
                                                ["y"] = 110404.32404328,
                                                ["x"] = 196294.48355836,
                                            }, -- end of [104]
                                            [120] = 
                                            {
                                                ["y"] = 110555.17333616,
                                                ["x"] = 196449.5390619,
                                            }, -- end of [120]
                                            [144] = 
                                            {
                                                ["y"] = 109998.24651184,
                                                ["x"] = 196749.03756205,
                                            }, -- end of [144]
                                            [176] = 
                                            {
                                                ["y"] = 109618.92945392,
                                                ["x"] = 196580.79555451,
                                            }, -- end of [176]
                                            [208] = 
                                            {
                                                ["y"] = 109330.25876922,
                                                ["x"] = 196504.97010741,
                                            }, -- end of [208]
                                            [240] = 
                                            {
                                                ["y"] = 108897.76716674,
                                                ["x"] = 196532.3659768,
                                            }, -- end of [240]
                                            [288] = 
                                            {
                                                ["y"] = 104069.71329115,
                                                ["x"] = 192387.66339026,
                                            }, -- end of [288]
                                            [289] = 
                                            {
                                                ["y"] = 104033.73607309,
                                                ["x"] = 192321.86899916,
                                            }, -- end of [289]
                                            [145] = 
                                            {
                                                ["y"] = 109993.25482904,
                                                ["x"] = 196748.76378392,
                                            }, -- end of [145]
                                            [177] = 
                                            {
                                                ["y"] = 109609.86918792,
                                                ["x"] = 196576.56859623,
                                            }, -- end of [177]
                                            [209] = 
                                            {
                                                ["y"] = 109320.26076032,
                                                ["x"] = 196505.08417166,
                                            }, -- end of [209]
                                            [241] = 
                                            {
                                                ["y"] = 108891.86485893,
                                                ["x"] = 196546.15324151,
                                            }, -- end of [241]
                                            [290] = 
                                            {
                                                ["y"] = 104004.11679509,
                                                ["x"] = 192275.53486169,
                                            }, -- end of [290]
                                            [73] = 
                                            {
                                                ["y"] = 110912.55659078,
                                                ["x"] = 196316.69269886,
                                            }, -- end of [73]
                                            [89] = 
                                            {
                                                ["y"] = 110532.26563404,
                                                ["x"] = 196235.22575871,
                                            }, -- end of [89]
                                            [105] = 
                                            {
                                                ["y"] = 110403.55628232,
                                                ["x"] = 196299.41979052,
                                            }, -- end of [105]
                                            [121] = 
                                            {
                                                ["y"] = 110558.3571908,
                                                ["x"] = 196453.39209679,
                                            }, -- end of [121]
                                            [146] = 
                                            {
                                                ["y"] = 109988.28121481,
                                                ["x"] = 196749.18898604,
                                            }, -- end of [146]
                                            [178] = 
                                            {
                                                ["y"] = 109600.57451616,
                                                ["x"] = 196572.88284371,
                                            }, -- end of [178]
                                            [210] = 
                                            {
                                                ["y"] = 109295.27639986,
                                                ["x"] = 196505.86014652,
                                            }, -- end of [210]
                                            [242] = 
                                            {
                                                ["y"] = 108888.6872649,
                                                ["x"] = 196555.62983902,
                                            }, -- end of [242]
                                            [292] = 
                                            {
                                                ["y"] = 103719.12013938,
                                                ["x"] = 191920.89531766,
                                            }, -- end of [292]
                                            [293] = 
                                            {
                                                ["y"] = 103705.38731947,
                                                ["x"] = 191906.35865916,
                                            }, -- end of [293]
                                            [147] = 
                                            {
                                                ["y"] = 109983.45577937,
                                                ["x"] = 196750.48318873,
                                            }, -- end of [147]
                                            [179] = 
                                            {
                                                ["y"] = 109591.10090828,
                                                ["x"] = 196569.68219546,
                                            }, -- end of [179]
                                            [211] = 
                                            {
                                                ["y"] = 109285.2848679,
                                                ["x"] = 196505.48048741,
                                            }, -- end of [211]
                                            [243] = 
                                            {
                                                ["y"] = 108887.5663369,
                                                ["x"] = 196560.50102532,
                                            }, -- end of [243]
                                            [294] = 
                                            {
                                                ["y"] = 103665.71370484,
                                                ["x"] = 191868.27196497,
                                            }, -- end of [294]
                                            [37] = 
                                            {
                                                ["y"] = 111035.12695103,
                                                ["x"] = 196149.49591914,
                                            }, -- end of [37]
                                            [45] = 
                                            {
                                                ["y"] = 110995.93970327,
                                                ["x"] = 196154.01225598,
                                            }, -- end of [45]
                                            [53] = 
                                            {
                                                ["y"] = 110966.33474352,
                                                ["x"] = 196179.60113719,
                                            }, -- end of [53]
                                            [61] = 
                                            {
                                                ["y"] = 110969.042101,
                                                ["x"] = 196291.24298758,
                                            }, -- end of [61]
                                            [74] = 
                                            {
                                                ["y"] = 110882.98963666,
                                                ["x"] = 196297.96607914,
                                            }, -- end of [74]
                                            [90] = 
                                            {
                                                ["y"] = 110528.00172134,
                                                ["x"] = 196237.83467584,
                                            }, -- end of [90]
                                            [106] = 
                                            {
                                                ["y"] = 110403.52466074,
                                                ["x"] = 196304.4148272,
                                            }, -- end of [106]
                                            [122] = 
                                            {
                                                ["y"] = 110561.18934895,
                                                ["x"] = 196457.51109337,
                                            }, -- end of [122]
                                            [148] = 
                                            {
                                                ["y"] = 109973.9265179,
                                                ["x"] = 196753.48048917,
                                            }, -- end of [148]
                                            [180] = 
                                            {
                                                ["y"] = 109581.45871134,
                                                ["x"] = 196567.04108772,
                                            }, -- end of [180]
                                            [212] = 
                                            {
                                                ["y"] = 109275.33873138,
                                                ["x"] = 196504.46697153,
                                            }, -- end of [212]
                                            [244] = 
                                            {
                                                ["y"] = 108880.37108253,
                                                ["x"] = 196594.74227214,
                                            }, -- end of [244]
                                            [296] = 
                                            {
                                                ["y"] = 103654.19415569,
                                                ["x"] = 191858.68051059,
                                            }, -- end of [296]
                                            [297] = 
                                            {
                                                ["y"] = 103649.99500225,
                                                ["x"] = 191855.9676115,
                                            }, -- end of [297]
                                            [149] = 
                                            {
                                                ["y"] = 109968.98618026,
                                                ["x"] = 196753.20037672,
                                            }, -- end of [149]
                                            [181] = 
                                            {
                                                ["y"] = 109571.65584375,
                                                ["x"] = 196565.0798139,
                                            }, -- end of [181]
                                            [213] = 
                                            {
                                                ["y"] = 109270.4101942,
                                                ["x"] = 196503.63118349,
                                            }, -- end of [213]
                                            [245] = 
                                            {
                                                ["y"] = 108873.10041431,
                                                ["x"] = 196623.84604244,
                                            }, -- end of [245]
                                            [298] = 
                                            {
                                                ["y"] = 103645.58496753,
                                                ["x"] = 191853.61602526,
                                            }, -- end of [298]
                                            [75] = 
                                            {
                                                ["y"] = 110741.83258371,
                                                ["x"] = 196222.65689571,
                                            }, -- end of [75]
                                            [91] = 
                                            {
                                                ["y"] = 110523.59057077,
                                                ["x"] = 196240.18765424,
                                            }, -- end of [91]
                                            [107] = 
                                            {
                                                ["y"] = 110404.225763,
                                                ["x"] = 196309.36131129,
                                            }, -- end of [107]
                                            [123] = 
                                            {
                                                ["y"] = 110563.50349433,
                                                ["x"] = 196461.93808969,
                                            }, -- end of [123]
                                            [150] = 
                                            {
                                                ["y"] = 109964.94380277,
                                                ["x"] = 196750.34755647,
                                            }, -- end of [150]
                                            [182] = 
                                            {
                                                ["y"] = 109561.74191779,
                                                ["x"] = 196563.77790778,
                                            }, -- end of [182]
                                            [214] = 
                                            {
                                                ["y"] = 109265.53278988,
                                                ["x"] = 196502.53447713,
                                            }, -- end of [214]
                                            [246] = 
                                            {
                                                ["y"] = 108871.52297603,
                                                ["x"] = 196628.58923548,
                                            }, -- end of [246]
                                            [300] = 
                                            {
                                                ["y"] = 103636.19779862,
                                                ["x"] = 191850.20870157,
                                            }, -- end of [300]
                                            [301] = 
                                            {
                                                ["y"] = 103631.32698881,
                                                ["x"] = 191849.08446321,
                                            }, -- end of [301]
                                            [151] = 
                                            {
                                                ["y"] = 109962.56860808,
                                                ["x"] = 196745.98471933,
                                            }, -- end of [151]
                                            [183] = 
                                            {
                                                ["y"] = 109551.76775104,
                                                ["x"] = 196563.08511846,
                                            }, -- end of [183]
                                            [215] = 
                                            {
                                                ["y"] = 109255.95244842,
                                                ["x"] = 196499.67586004,
                                            }, -- end of [215]
                                            [247] = 
                                            {
                                                ["y"] = 108869.44041497,
                                                ["x"] = 196633.12961834,
                                            }, -- end of [247]
                                            [19] = 
                                            {
                                                ["y"] = 111201.21157606,
                                                ["x"] = 196164.50031892,
                                            }, -- end of [19]
                                            [23] = 
                                            {
                                                ["y"] = 111186.7515453,
                                                ["x"] = 196178.10803362,
                                            }, -- end of [23]
                                            [27] = 
                                            {
                                                ["y"] = 111168.41618788,
                                                ["x"] = 196185.71033697,
                                            }, -- end of [27]
                                            [31] = 
                                            {
                                                ["y"] = 111148.54200399,
                                                ["x"] = 196187.58583128,
                                            }, -- end of [31]
                                            [38] = 
                                            {
                                                ["y"] = 111030.18345377,
                                                ["x"] = 196148.75540655,
                                            }, -- end of [38]
                                            [46] = 
                                            {
                                                ["y"] = 110991.36763917,
                                                ["x"] = 196156.03315102,
                                            }, -- end of [46]
                                            [54] = 
                                            {
                                                ["y"] = 110964.04464108,
                                                ["x"] = 196184.04555846,
                                            }, -- end of [54]
                                            [62] = 
                                            {
                                                ["y"] = 110967.39588962,
                                                ["x"] = 196295.92338416,
                                            }, -- end of [62]
                                            [76] = 
                                            {
                                                ["y"] = 110723.77533868,
                                                ["x"] = 196214.06163263,
                                            }, -- end of [76]
                                            [92] = 
                                            {
                                                ["y"] = 110509.98495865,
                                                ["x"] = 196246.5007435,
                                            }, -- end of [92]
                                            [108] = 
                                            {
                                                ["y"] = 110405.57409915,
                                                ["x"] = 196314.1726143,
                                            }, -- end of [108]
                                            [124] = 
                                            {
                                                ["y"] = 110565.00216214,
                                                ["x"] = 196466.6986545,
                                            }, -- end of [124]
                                            [152] = 
                                            {
                                                ["y"] = 109960.91143554,
                                                ["x"] = 196741.26917693,
                                            }, -- end of [152]
                                            [184] = 
                                            {
                                                ["y"] = 109541.76956509,
                                                ["x"] = 196562.99686119,
                                            }, -- end of [184]
                                            [216] = 
                                            {
                                                ["y"] = 109241.87701604,
                                                ["x"] = 196494.49548369,
                                            }, -- end of [216]
                                            [248] = 
                                            {
                                                ["y"] = 108866.59964562,
                                                ["x"] = 196637.23349764,
                                            }, -- end of [248]
                                            [304] = 
                                            {
                                                ["y"] = 103601.445427,
                                                ["x"] = 191847.00993695,
                                            }, -- end of [304]
                                            [305] = 
                                            {
                                                ["y"] = 103581.45343118,
                                                ["x"] = 191847.47653914,
                                            }, -- end of [305]
                                            [153] = 
                                            {
                                                ["y"] = 109959.79188028,
                                                ["x"] = 196736.398945,
                                            }, -- end of [153]
                                            [185] = 
                                            {
                                                ["y"] = 109531.7866556,
                                                ["x"] = 196563.55093207,
                                            }, -- end of [185]
                                            [217] = 
                                            {
                                                ["y"] = 109214.03168624,
                                                ["x"] = 196483.34833449,
                                            }, -- end of [217]
                                            [249] = 
                                            {
                                                ["y"] = 108862.97208809,
                                                ["x"] = 196640.66723091,
                                            }, -- end of [249]
                                            [306] = 
                                            {
                                                ["y"] = 103491.67441387,
                                                ["x"] = 191853.72008139,
                                            }, -- end of [306]
                                            [143] = 
                                            {
                                                ["y"] = 110033.20970325,
                                                ["x"] = 196750.59880646,
                                            }, -- end of [143]
                                            [77] = 
                                            {
                                                ["y"] = 110714.50352227,
                                                ["x"] = 196210.32226542,
                                            }, -- end of [77]
                                            [93] = 
                                            {
                                                ["y"] = 110486.80096354,
                                                ["x"] = 196255.84999354,
                                            }, -- end of [93]
                                            [109] = 
                                            {
                                                ["y"] = 110407.40645922,
                                                ["x"] = 196318.82362822,
                                            }, -- end of [109]
                                            [125] = 
                                            {
                                                ["y"] = 110565.51227169,
                                                ["x"] = 196471.66475926,
                                            }, -- end of [125]
                                            [154] = 
                                            {
                                                ["y"] = 109959.25907762,
                                                ["x"] = 196731.43074259,
                                            }, -- end of [154]
                                            [186] = 
                                            {
                                                ["y"] = 109516.90042181,
                                                ["x"] = 196565.3769811,
                                            }, -- end of [186]
                                            [218] = 
                                            {
                                                ["y"] = 109204.47801364,
                                                ["x"] = 196480.40266691,
                                            }, -- end of [218]
                                            [250] = 
                                            {
                                                ["y"] = 108858.96832878,
                                                ["x"] = 196643.66248297,
                                            }, -- end of [250]
                                            [308] = 
                                            {
                                                ["y"] = 103422.66682073,
                                                ["x"] = 191865.26723544,
                                            }, -- end of [308]
                                            [323] = 
                                            {
                                                ["y"] = 102980.48955839,
                                                ["x"] = 191765.28241038,
                                            }, -- end of [323]
                                            [319] = 
                                            {
                                                ["y"] = 103193.10695002,
                                                ["x"] = 191865.03127409,
                                            }, -- end of [319]
                                            [79] = 
                                            {
                                                ["y"] = 110681.24112255,
                                                ["x"] = 196199.47864169,
                                            }, -- end of [79]
                                            [159] = 
                                            {
                                                ["y"] = 109958.0996195,
                                                ["x"] = 196686.60579484,
                                            }, -- end of [159]
                                            [175] = 
                                            {
                                                ["y"] = 109640.01297749,
                                                ["x"] = 196594.20659521,
                                            }, -- end of [175]
                                            [191] = 
                                            {
                                                ["y"] = 109457.26962464,
                                                ["x"] = 196568.12051831,
                                            }, -- end of [191]
                                            [207] = 
                                            {
                                                ["y"] = 109340.23532504,
                                                ["x"] = 196505.59462384,
                                            }, -- end of [207]
                                            [309] = 
                                            {
                                                ["y"] = 103324.50716849,
                                                ["x"] = 191884.2962719,
                                            }, -- end of [309]
                                            [223] = 
                                            {
                                                ["y"] = 109120.67634282,
                                                ["x"] = 196467.78173091,
                                            }, -- end of [223]
                                            [239] = 
                                            {
                                                ["y"] = 108906.69263284,
                                                ["x"] = 196514.47071699,
                                            }, -- end of [239]
                                            [254] = 
                                            {
                                                ["y"] = 108842.312033,
                                                ["x"] = 196639.75871256,
                                            }, -- end of [254]
                                            [155] = 
                                            {
                                                ["y"] = 109959.1947309,
                                                ["x"] = 196726.43369413,
                                            }, -- end of [155]
                                            [187] = 
                                            {
                                                ["y"] = 109487.16048598,
                                                ["x"] = 196569.26992159,
                                            }, -- end of [187]
                                            [219] = 
                                            {
                                                ["y"] = 109189.90082777,
                                                ["x"] = 196476.87603219,
                                            }, -- end of [219]
                                            [251] = 
                                            {
                                                ["y"] = 108854.56558762,
                                                ["x"] = 196646.00773018,
                                            }, -- end of [251]
                                            [310] = 
                                            {
                                                ["y"] = 103304.64744491,
                                                ["x"] = 191886.63500653,
                                            }, -- end of [310]
                                            [302] = 
                                            {
                                                ["y"] = 103626.39454319,
                                                ["x"] = 191848.26904139,
                                            }, -- end of [302]
                                            [299] = 
                                            {
                                                ["y"] = 103640.96863821,
                                                ["x"] = 191851.70125676,
                                            }, -- end of [299]
                                            [78] = 
                                            {
                                                ["y"] = 110690.86746349,
                                                ["x"] = 196202.18072958,
                                            }, -- end of [78]
                                            [39] = 
                                            {
                                                ["y"] = 111025.19685985,
                                                ["x"] = 196148.41021129,
                                            }, -- end of [39]
                                            [47] = 
                                            {
                                                ["y"] = 110986.94826681,
                                                ["x"] = 196158.37079244,
                                            }, -- end of [47]
                                            [55] = 
                                            {
                                                ["y"] = 110962.06075551,
                                                ["x"] = 196188.63336321,
                                            }, -- end of [55]
                                            [63] = 
                                            {
                                                ["y"] = 110964.47542943,
                                                ["x"] = 196299.98049129,
                                            }, -- end of [63]
                                            [311] = 
                                            {
                                                ["y"] = 103289.67157384,
                                                ["x"] = 191887.43891193,
                                            }, -- end of [311]
                                            [94] = 
                                            {
                                                ["y"] = 110477.29262716,
                                                ["x"] = 196258.93872859,
                                            }, -- end of [94]
                                            [110] = 
                                            {
                                                ["y"] = 110415.94536137,
                                                ["x"] = 196336.90564916,
                                            }, -- end of [110]
                                            [126] = 
                                            {
                                                ["y"] = 110565.08973788,
                                                ["x"] = 196476.63991574,
                                            }, -- end of [126]
                                            [156] = 
                                            {
                                                ["y"] = 109960.05188825,
                                                ["x"] = 196701.45640375,
                                            }, -- end of [156]
                                            [188] = 
                                            {
                                                ["y"] = 109477.17209155,
                                                ["x"] = 196569.67759798,
                                            }, -- end of [188]
                                            [220] = 
                                            {
                                                ["y"] = 109150.57779378,
                                                ["x"] = 196469.55869444,
                                            }, -- end of [220]
                                            [252] = 
                                            {
                                                ["y"] = 108849.66018312,
                                                ["x"] = 196646.32923185,
                                            }, -- end of [252]
                                            [312] = 
                                            {
                                                ["y"] = 103279.67277521,
                                                ["x"] = 191887.38394135,
                                            }, -- end of [312]
                                            [291] = 
                                            {
                                                ["y"] = 103992.13751762,
                                                ["x"] = 192259.52197874,
                                            }, -- end of [291]
                                            [287] = 
                                            {
                                                ["y"] = 104076.57530522,
                                                ["x"] = 192400.99982525,
                                            }, -- end of [287]
                                            [259] = 
                                            {
                                                ["y"] = 108342.19188065,
                                                ["x"] = 196068.04027221,
                                            }, -- end of [259]
                                            [263] = 
                                            {
                                                ["y"] = 107422.40587262,
                                                ["x"] = 194833.57398527,
                                            }, -- end of [263]
                                            [267] = 
                                            {
                                                ["y"] = 107292.66058781,
                                                ["x"] = 194716.69845904,
                                            }, -- end of [267]
                                            [275] = 
                                            {
                                                ["y"] = 104893.16776538,
                                                ["x"] = 193404.96271319,
                                            }, -- end of [275]
                                            [271] = 
                                            {
                                                ["y"] = 106541.70503163,
                                                ["x"] = 194308.29216533,
                                            }, -- end of [271]
                                            [313] = 
                                            {
                                                ["y"] = 103269.69217826,
                                                ["x"] = 191886.78592067,
                                            }, -- end of [313]
                                            [279] = 
                                            {
                                                ["y"] = 104812.95683097,
                                                ["x"] = 193337.43577249,
                                            }, -- end of [279]
                                            [283] = 
                                            {
                                                ["y"] = 104147.6167395,
                                                ["x"] = 192538.30020599,
                                            }, -- end of [283]
                                            [286] = 
                                            {
                                                ["y"] = 104102.17283604,
                                                ["x"] = 192460.74381851,
                                            }, -- end of [286]
                                            [157] = 
                                            {
                                                ["y"] = 109959.71276472,
                                                ["x"] = 196696.46914037,
                                            }, -- end of [157]
                                            [189] = 
                                            {
                                                ["y"] = 109467.17678876,
                                                ["x"] = 196569.41464472,
                                            }, -- end of [189]
                                            [221] = 
                                            {
                                                ["y"] = 109140.65554358,
                                                ["x"] = 196468.32940974,
                                            }, -- end of [221]
                                            [253] = 
                                            {
                                                ["y"] = 108845.58161513,
                                                ["x"] = 196643.54228508,
                                            }, -- end of [253]
                                            [314] = 
                                            {
                                                ["y"] = 103259.76219793,
                                                ["x"] = 191885.61709894,
                                            }, -- end of [314]
                                            [303] = 
                                            {
                                                ["y"] = 103616.440473,
                                                ["x"] = 191847.34002335,
                                            }, -- end of [303]
                                            [307] = 
                                            {
                                                ["y"] = 103466.88707834,
                                                ["x"] = 191856.95160616,
                                            }, -- end of [307]
                                            [295] = 
                                            {
                                                ["y"] = 103658.17534428,
                                                ["x"] = 191861.70352848,
                                            }, -- end of [295]
                                            [270] = 
                                            {
                                                ["y"] = 107079.78080538,
                                                ["x"] = 194606.06446639,
                                            }, -- end of [270]
                                            [255] = 
                                            {
                                                ["y"] = 108776.69115484,
                                                ["x"] = 196557.84293638,
                                            }, -- end of [255]
                                            [318] = 
                                            {
                                                ["y"] = 103206.87658256,
                                                ["x"] = 191870.97633907,
                                            }, -- end of [318]
                                            [317] = 
                                            {
                                                ["y"] = 103220.95158533,
                                                ["x"] = 191876.15646893,
                                            }, -- end of [317]
                                            [315] = 
                                            {
                                                ["y"] = 103249.90801339,
                                                ["x"] = 191883.92114544,
                                            }, -- end of [315]
                                            [95] = 
                                            {
                                                ["y"] = 110462.74351739,
                                                ["x"] = 196262.58290151,
                                            }, -- end of [95]
                                            [111] = 
                                            {
                                                ["y"] = 110418.52349187,
                                                ["x"] = 196341.18629553,
                                            }, -- end of [111]
                                            [327] = 
                                            {
                                                ["y"] = 102937.92110516,
                                                ["x"] = 191730.59198081,
                                            }, -- end of [327]
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            [1] = 
                                            {
                                                ["y"] = 104699.30796176,
                                                ["x"] = 191071.91042243,
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["y"] = 104699.30796176,
                                                ["x"] = 191071.91042243,
                                            }, -- end of [2]
                                        }, -- end of [2]
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 83,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 110778.27860898,
                                            ["x"] = 195856.21578502,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 14,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 4454.1750744459,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 102496.75727963,
                                            ["x"] = 191362.16613034,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 2.7777777777778,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 44,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 88,
                                        ["y"] = 110778.27860898,
                                        ["x"] = 195856.21578502,
                                        ["name"] = "Invaders Two-1-2",
                                        ["heading"] = 1.0570642483266,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Gepard",
                                        ["unitId"] = 89,
                                        ["y"] = 110752.11761308,
                                        ["x"] = 195841.53285973,
                                        ["name"] = "Invaders Two-1-3",
                                        ["heading"] = 1.0593550001005,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 90,
                                        ["y"] = 110725.88976162,
                                        ["x"] = 195826.96944005,
                                        ["name"] = "Invaders Two-1-4",
                                        ["heading"] = 1.0639195360945,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [3]
                                    [4] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "T-90",
                                        ["unitId"] = 91,
                                        ["y"] = 110699.94500201,
                                        ["x"] = 195811.93623618,
                                        ["name"] = "Invaders Two-1-5",
                                        ["heading"] = 1.0456382396694,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [4]
                                    [5] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 92,
                                        ["y"] = 110674.21021039,
                                        ["x"] = 195796.51054188,
                                        ["name"] = "Invaders Two-1-6",
                                        ["heading"] = 1.0308106815616,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [5]
                                    [6] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 93,
                                        ["y"] = 110647.92297634,
                                        ["x"] = 195782.09266669,
                                        ["name"] = "Invaders Two-1-7",
                                        ["heading"] = 1.069125148498,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [6]
                                }, -- end of ["units"]
                                ["y"] = 110778.27860898,
                                ["x"] = 195856.21578502,
                                ["name"] = "Invaders Two-1",
                                ["start_time"] = 0,
                            }, -- end of [12]
                            [13] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 9,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 106278.35259403,
                                            ["x"] = 194253.87834329,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "Off Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 46,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland Radar",
                                        ["unitId"] = 100,
                                        ["y"] = 106278.35259403,
                                        ["x"] = 194253.87834329,
                                        ["name"] = "AAA One-4-6",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland Radar",
                                        ["unitId"] = 95,
                                        ["y"] = 106357.27021192,
                                        ["x"] = 194164.40132582,
                                        ["name"] = "AAA One-4-1",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland ADS",
                                        ["unitId"] = 96,
                                        ["y"] = 106313.36533999,
                                        ["x"] = 194320.56928799,
                                        ["name"] = "AAA One-4-2",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [3]
                                    [4] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland ADS",
                                        ["unitId"] = 99,
                                        ["y"] = 106338.93020213,
                                        ["x"] = 194281.66623692,
                                        ["name"] = "AAA One-4-5",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [4]
                                    [5] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland ADS",
                                        ["unitId"] = 98,
                                        ["y"] = 106262.70798415,
                                        ["x"] = 194202.82446026,
                                        ["name"] = "AAA One-4-4",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [5]
                                    [6] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Roland ADS",
                                        ["unitId"] = 97,
                                        ["y"] = 106321.14595021,
                                        ["x"] = 194223.31166031,
                                        ["name"] = "AAA One-4-3",
                                        ["heading"] = 4.625122517785,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [6]
                                }, -- end of ["units"]
                                ["y"] = 106278.35259403,
                                ["x"] = 194253.87834329,
                                ["name"] = "AAA One-4",
                                ["start_time"] = 0,
                            }, -- end of [13]
                            [14] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["task"] = "Ground Nothing",
                                ["taskSelected"] = true,
                                ["route"] = 
                                {
                                    ["spans"] = 
                                    {
                                        [1] = 
                                        {
                                            [33] = 
                                            {
                                                ["y"] = 108698.72753668,
                                                ["x"] = 195062.14758608,
                                            }, -- end of [33]
                                            [35] = 
                                            {
                                                ["y"] = 108674.2523146,
                                                ["x"] = 195018.58284137,
                                            }, -- end of [35]
                                            [37] = 
                                            {
                                                ["y"] = 108662.96723068,
                                                ["x"] = 195002.08320293,
                                            }, -- end of [37]
                                            [39] = 
                                            {
                                                ["y"] = 108644.97366056,
                                                ["x"] = 194984.75953766,
                                            }, -- end of [39]
                                            [41] = 
                                            {
                                                ["y"] = 108616.68155323,
                                                ["x"] = 194964.18196022,
                                            }, -- end of [41]
                                            [43] = 
                                            {
                                                ["y"] = 108607.99883899,
                                                ["x"] = 194959.2514448,
                                            }, -- end of [43]
                                            [45] = 
                                            {
                                                ["y"] = 108589.11133794,
                                                ["x"] = 194952.70387429,
                                            }, -- end of [45]
                                            [47] = 
                                            {
                                                ["y"] = 108545.83683679,
                                                ["x"] = 194940.57850103,
                                            }, -- end of [47]
                                            [49] = 
                                            {
                                                ["y"] = 108525.84869609,
                                                ["x"] = 194940.14498894,
                                            }, -- end of [49]
                                            [51] = 
                                            {
                                                ["y"] = 108386.52779977,
                                                ["x"] = 194953.54078076,
                                            }, -- end of [51]
                                            [53] = 
                                            {
                                                ["y"] = 108262.46344591,
                                                ["x"] = 194968.40627145,
                                            }, -- end of [53]
                                            [55] = 
                                            {
                                                ["y"] = 108222.6525003,
                                                ["x"] = 194965.72938588,
                                            }, -- end of [55]
                                            [57] = 
                                            {
                                                ["y"] = 108193.96293543,
                                                ["x"] = 194957.02472988,
                                            }, -- end of [57]
                                            [59] = 
                                            {
                                                ["y"] = 108149.09492129,
                                                ["x"] = 194935.01765279,
                                            }, -- end of [59]
                                            [61] = 
                                            {
                                                ["y"] = 108109.05976597,
                                                ["x"] = 194914.52432435,
                                            }, -- end of [61]
                                            [63] = 
                                            {
                                                ["y"] = 108085.02364833,
                                                ["x"] = 194907.71783627,
                                            }, -- end of [63]
                                            [66] = 
                                            {
                                                ["y"] = 107765.50832739,
                                                ["x"] = 194897.58796535,
                                            }, -- end of [66]
                                            [70] = 
                                            {
                                                ["y"] = 107706.88925344,
                                                ["x"] = 194909.617161,
                                            }, -- end of [70]
                                            [74] = 
                                            {
                                                ["y"] = 107549.85749797,
                                                ["x"] = 194973.77408348,
                                            }, -- end of [74]
                                            [78] = 
                                            {
                                                ["y"] = 107531.90663202,
                                                ["x"] = 194967.88551867,
                                            }, -- end of [78]
                                            [82] = 
                                            {
                                                ["y"] = 107327.12623279,
                                                ["x"] = 194742.85404562,
                                            }, -- end of [82]
                                            [86] = 
                                            {
                                                ["y"] = 107269.37073955,
                                                ["x"] = 194703.66159159,
                                            }, -- end of [86]
                                            [90] = 
                                            {
                                                ["y"] = 104825.68197993,
                                                ["x"] = 193350.54885001,
                                            }, -- end of [90]
                                            [94] = 
                                            {
                                                ["y"] = 104650.46040122,
                                                ["x"] = 193145.25365231,
                                            }, -- end of [94]
                                            [98] = 
                                            {
                                                ["y"] = 104109.99378403,
                                                ["x"] = 192477.26254649,
                                            }, -- end of [98]
                                            [102] = 
                                            {
                                                ["y"] = 104011.56804988,
                                                ["x"] = 192286.54410936,
                                            }, -- end of [102]
                                            [106] = 
                                            {
                                                ["y"] = 103704.18694506,
                                                ["x"] = 191905.14806307,
                                            }, -- end of [106]
                                            [110] = 
                                            {
                                                ["y"] = 103648.51559982,
                                                ["x"] = 191855.12063084,
                                            }, -- end of [110]
                                            [114] = 
                                            {
                                                ["y"] = 103629.65050456,
                                                ["x"] = 191848.7747303,
                                            }, -- end of [114]
                                            [118] = 
                                            {
                                                ["y"] = 103564.77609219,
                                                ["x"] = 191848.43220366,
                                            }, -- end of [118]
                                            [122] = 
                                            {
                                                ["y"] = 103297.9599651,
                                                ["x"] = 191887.11388139,
                                            }, -- end of [122]
                                            [126] = 
                                            {
                                                ["y"] = 103253.14559903,
                                                ["x"] = 191884.53470962,
                                            }, -- end of [126]
                                            [132] = 
                                            {
                                                ["y"] = 103097.74292004,
                                                ["x"] = 191817.23063994,
                                            }, -- end of [132]
                                            [140] = 
                                            {
                                                ["y"] = 102907.87796915,
                                                ["x"] = 191709.51477565,
                                            }, -- end of [140]
                                            [1] = 
                                            {
                                                ["y"] = 109317.65284632,
                                                ["x"] = 196045.90808469,
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["y"] = 109308.79195585,
                                                ["x"] = 196001.7968499,
                                            }, -- end of [2]
                                            [133] = 
                                            {
                                                ["y"] = 102983.29632245,
                                                ["x"] = 191767.00657558,
                                            }, -- end of [133]
                                            [141] = 
                                            {
                                                ["y"] = 102781.93335283,
                                                ["x"] = 191610.84384001,
                                            }, -- end of [141]
                                            [3] = 
                                            {
                                                ["y"] = 109304.24612164,
                                                ["x"] = 195967.09672413,
                                            }, -- end of [3]
                                            [4] = 
                                            {
                                                ["y"] = 109285.03656083,
                                                ["x"] = 195793.21707717,
                                            }, -- end of [4]
                                            [67] = 
                                            {
                                                ["y"] = 107745.67885696,
                                                ["x"] = 194900.17632081,
                                            }, -- end of [67]
                                            [71] = 
                                            {
                                                ["y"] = 107697.69527,
                                                ["x"] = 194913.54383883,
                                            }, -- end of [71]
                                            [75] = 
                                            {
                                                ["y"] = 107544.88115112,
                                                ["x"] = 194974.33753494,
                                            }, -- end of [75]
                                            [5] = 
                                            {
                                                ["y"] = 109274.51358722,
                                                ["x"] = 195734.1532326,
                                            }, -- end of [5]
                                            [83] = 
                                            {
                                                ["y"] = 107303.62766263,
                                                ["x"] = 194724.21133442,
                                            }, -- end of [83]
                                            [87] = 
                                            {
                                                ["y"] = 107082.6545071,
                                                ["x"] = 194607.67701874,
                                            }, -- end of [87]
                                            [91] = 
                                            {
                                                ["y"] = 104821.97475539,
                                                ["x"] = 193347.19659239,
                                            }, -- end of [91]
                                            [6] = 
                                            {
                                                ["y"] = 109265.30256537,
                                                ["x"] = 195695.2327556,
                                            }, -- end of [6]
                                            [99] = 
                                            {
                                                ["y"] = 104105.41776429,
                                                ["x"] = 192468.37848283,
                                            }, -- end of [99]
                                            [103] = 
                                            {
                                                ["y"] = 104000.1958049,
                                                ["x"] = 192270.09647859,
                                            }, -- end of [103]
                                            [107] = 
                                            {
                                                ["y"] = 103664.44912347,
                                                ["x"] = 191867.12881759,
                                            }, -- end of [107]
                                            [7] = 
                                            {
                                                ["y"] = 109242.26340059,
                                                ["x"] = 195603.08307173,
                                            }, -- end of [7]
                                            [115] = 
                                            {
                                                ["y"] = 103624.7038807,
                                                ["x"] = 191848.05107963,
                                            }, -- end of [115]
                                            [119] = 
                                            {
                                                ["y"] = 103485.0102021,
                                                ["x"] = 191854.45473569,
                                            }, -- end of [119]
                                            [123] = 
                                            {
                                                ["y"] = 103282.96723769,
                                                ["x"] = 191887.45951958,
                                            }, -- end of [123]
                                            [8] = 
                                            {
                                                ["y"] = 109230.15940898,
                                                ["x"] = 195544.31911084,
                                            }, -- end of [8]
                                            [134] = 
                                            {
                                                ["y"] = 102979.07983961,
                                                ["x"] = 191764.32510947,
                                            }, -- end of [134]
                                            [9] = 
                                            {
                                                ["y"] = 109217.07196662,
                                                ["x"] = 195496.08485367,
                                            }, -- end of [9]
                                            [10] = 
                                            {
                                                ["y"] = 109211.78378441,
                                                ["x"] = 195482.04976414,
                                            }, -- end of [10]
                                            [11] = 
                                            {
                                                ["y"] = 109207.63705071,
                                                ["x"] = 195472.95318854,
                                            }, -- end of [11]
                                            [12] = 
                                            {
                                                ["y"] = 109205.26807389,
                                                ["x"] = 195468.55029799,
                                            }, -- end of [12]
                                            [13] = 
                                            {
                                                ["y"] = 109202.65778195,
                                                ["x"] = 195464.28707643,
                                            }, -- end of [13]
                                            [14] = 
                                            {
                                                ["y"] = 109199.75914457,
                                                ["x"] = 195460.21440253,
                                            }, -- end of [14]
                                            [15] = 
                                            {
                                                ["y"] = 109196.57666989,
                                                ["x"] = 195456.35942382,
                                            }, -- end of [15]
                                            [16] = 
                                            {
                                                ["y"] = 109193.15024402,
                                                ["x"] = 195452.71894476,
                                            }, -- end of [16]
                                            [17] = 
                                            {
                                                ["y"] = 109189.53535461,
                                                ["x"] = 195449.26533344,
                                            }, -- end of [17]
                                            [18] = 
                                            {
                                                ["y"] = 109181.93968489,
                                                ["x"] = 195442.76279683,
                                            }, -- end of [18]
                                            [19] = 
                                            {
                                                ["y"] = 109118.85247016,
                                                ["x"] = 195393.57912421,
                                            }, -- end of [19]
                                            [20] = 
                                            {
                                                ["y"] = 108950.26555394,
                                                ["x"] = 195286.04885006,
                                            }, -- end of [20]
                                            [21] = 
                                            {
                                                ["y"] = 108914.15850941,
                                                ["x"] = 195259.19981852,
                                            }, -- end of [21]
                                            [22] = 
                                            {
                                                ["y"] = 108910.45050164,
                                                ["x"] = 195255.84600354,
                                            }, -- end of [22]
                                            [23] = 
                                            {
                                                ["y"] = 108873.83413317,
                                                ["x"] = 195221.80699315,
                                            }, -- end of [23]
                                            [24] = 
                                            {
                                                ["y"] = 108839.19302715,
                                                ["x"] = 195193.09021247,
                                            }, -- end of [24]
                                            [25] = 
                                            {
                                                ["y"] = 108802.94649143,
                                                ["x"] = 195166.43083052,
                                            }, -- end of [25]
                                            [26] = 
                                            {
                                                ["y"] = 108754.20023806,
                                                ["x"] = 195131.46732651,
                                            }, -- end of [26]
                                            [27] = 
                                            {
                                                ["y"] = 108738.61610506,
                                                ["x"] = 195118.93864713,
                                            }, -- end of [27]
                                            [28] = 
                                            {
                                                ["y"] = 108731.28856193,
                                                ["x"] = 195112.13586054,
                                            }, -- end of [28]
                                            [29] = 
                                            {
                                                ["y"] = 108724.40884258,
                                                ["x"] = 195104.88104723,
                                            }, -- end of [29]
                                            [30] = 
                                            {
                                                ["y"] = 108718.17338269,
                                                ["x"] = 195097.06984632,
                                            }, -- end of [30]
                                            [31] = 
                                            {
                                                ["y"] = 108715.40171697,
                                                ["x"] = 195092.90896406,
                                            }, -- end of [31]
                                            [32] = 
                                            {
                                                ["y"] = 108712.86145,
                                                ["x"] = 195088.60309518,
                                            }, -- end of [32]
                                            [34] = 
                                            {
                                                ["y"] = 108689.60224348,
                                                ["x"] = 195044.35478269,
                                            }, -- end of [34]
                                            [36] = 
                                            {
                                                ["y"] = 108665.97981873,
                                                ["x"] = 195006.07286285,
                                            }, -- end of [36]
                                            [38] = 
                                            {
                                                ["y"] = 108659.65414457,
                                                ["x"] = 194998.34268551,
                                            }, -- end of [38]
                                            [40] = 
                                            {
                                                ["y"] = 108641.11938661,
                                                ["x"] = 194981.5783719,
                                            }, -- end of [40]
                                            [42] = 
                                            {
                                                ["y"] = 108612.45599719,
                                                ["x"] = 194961.51098537,
                                            }, -- end of [42]
                                            [44] = 
                                            {
                                                ["y"] = 108603.3593462,
                                                ["x"] = 194957.38943513,
                                            }, -- end of [44]
                                            [46] = 
                                            {
                                                ["y"] = 108550.78303863,
                                                ["x"] = 194941.29204399,
                                            }, -- end of [46]
                                            [48] = 
                                            {
                                                ["y"] = 108540.84588919,
                                                ["x"] = 194940.29008886,
                                            }, -- end of [48]
                                            [50] = 
                                            {
                                                ["y"] = 108515.86167965,
                                                ["x"] = 194940.63525676,
                                            }, -- end of [50]
                                            [52] = 
                                            {
                                                ["y"] = 108267.46217355,
                                                ["x"] = 194968.37807996,
                                            }, -- end of [52]
                                            [54] = 
                                            {
                                                ["y"] = 108227.50476749,
                                                ["x"] = 194966.93021279,
                                            }, -- end of [54]
                                            [56] = 
                                            {
                                                ["y"] = 108198.63232983,
                                                ["x"] = 194958.80598793,
                                            }, -- end of [56]
                                            [58] = 
                                            {
                                                ["y"] = 108171.18764007,
                                                ["x"] = 194946.71524117,
                                            }, -- end of [58]
                                            [60] = 
                                            {
                                                ["y"] = 108127.10808596,
                                                ["x"] = 194923.12618846,
                                            }, -- end of [60]
                                            [62] = 
                                            {
                                                ["y"] = 108104.32909558,
                                                ["x"] = 194912.90858891,
                                            }, -- end of [62]
                                            [64] = 
                                            {
                                                ["y"] = 108060.33965881,
                                                ["x"] = 194903.94801487,
                                            }, -- end of [64]
                                            [68] = 
                                            {
                                                ["y"] = 107726.02713884,
                                                ["x"] = 194903.88265859,
                                            }, -- end of [68]
                                            [72] = 
                                            {
                                                ["y"] = 107611.71017504,
                                                ["x"] = 194953.8935767,
                                            }, -- end of [72]
                                            [76] = 
                                            {
                                                ["y"] = 107539.95984963,
                                                ["x"] = 194973.55653683,
                                            }, -- end of [76]
                                            [80] = 
                                            {
                                                ["y"] = 107421.23007882,
                                                ["x"] = 194832.33947489,
                                            }, -- end of [80]
                                            [84] = 
                                            {
                                                ["y"] = 107291.22261681,
                                                ["x"] = 194715.7829401,
                                            }, -- end of [84]
                                            [88] = 
                                            {
                                                ["y"] = 104891.75558632,
                                                ["x"] = 193404.00911969,
                                            }, -- end of [88]
                                            [92] = 
                                            {
                                                ["y"] = 104818.46118729,
                                                ["x"] = 193343.64215658,
                                            }, -- end of [92]
                                            [96] = 
                                            {
                                                ["y"] = 104155.23692848,
                                                ["x"] = 192549.19338121,
                                            }, -- end of [96]
                                            [100] = 
                                            {
                                                ["y"] = 104073.59628313,
                                                ["x"] = 192394.99359739,
                                            }, -- end of [100]
                                            [104] = 
                                            {
                                                ["y"] = 103984.79617997,
                                                ["x"] = 192250.40640735,
                                            }, -- end of [104]
                                            [108] = 
                                            {
                                                ["y"] = 103656.84168822,
                                                ["x"] = 191860.64184171,
                                            }, -- end of [108]
                                            [112] = 
                                            {
                                                ["y"] = 103639.35628559,
                                                ["x"] = 191851.14739903,
                                            }, -- end of [112]
                                            [116] = 
                                            {
                                                ["y"] = 103614.73774163,
                                                ["x"] = 191847.25796397,
                                            }, -- end of [116]
                                            [120] = 
                                            {
                                                ["y"] = 103460.26770734,
                                                ["x"] = 191858.01833929,
                                            }, -- end of [120]
                                            [124] = 
                                            {
                                                ["y"] = 103272.97703338,
                                                ["x"] = 191887.04586767,
                                            }, -- end of [124]
                                            [128] = 
                                            {
                                                ["y"] = 103228.8570039,
                                                ["x"] = 191878.66854006,
                                            }, -- end of [128]
                                            [136] = 
                                            {
                                                ["y"] = 102971.44415566,
                                                ["x"] = 191757.88273478,
                                            }, -- end of [136]
                                            [129] = 
                                            {
                                                ["y"] = 103214.62411396,
                                                ["x"] = 191873.93975417,
                                            }, -- end of [129]
                                            [137] = 
                                            {
                                                ["y"] = 102960.52504436,
                                                ["x"] = 191747.60539112,
                                            }, -- end of [137]
                                            [65] = 
                                            {
                                                ["y"] = 107780.46786776,
                                                ["x"] = 194896.53362663,
                                            }, -- end of [65]
                                            [69] = 
                                            {
                                                ["y"] = 107716.34516894,
                                                ["x"] = 194906.37093913,
                                            }, -- end of [69]
                                            [73] = 
                                            {
                                                ["y"] = 107569.15640715,
                                                ["x"] = 194968.52121163,
                                            }, -- end of [73]
                                            [77] = 
                                            {
                                                ["y"] = 107535.60179682,
                                                ["x"] = 194971.21671504,
                                            }, -- end of [77]
                                            [81] = 
                                            {
                                                ["y"] = 107365.243511,
                                                ["x"] = 194775.2071365,
                                            }, -- end of [81]
                                            [85] = 
                                            {
                                                ["y"] = 107282.63632034,
                                                ["x"] = 194710.65934398,
                                            }, -- end of [85]
                                            [89] = 
                                            {
                                                ["y"] = 104887.74158325,
                                                ["x"] = 193401.03199062,
                                            }, -- end of [89]
                                            [93] = 
                                            {
                                                ["y"] = 104782.43815995,
                                                ["x"] = 193302.08117774,
                                            }, -- end of [93]
                                            [97] = 
                                            {
                                                ["y"] = 104146.67305663,
                                                ["x"] = 192536.88055505,
                                            }, -- end of [97]
                                            [101] = 
                                            {
                                                ["y"] = 104040.47810291,
                                                ["x"] = 192333.32739727,
                                            }, -- end of [101]
                                            [105] = 
                                            {
                                                ["y"] = 103717.98134591,
                                                ["x"] = 191919.62679924,
                                            }, -- end of [105]
                                            [109] = 
                                            {
                                                ["y"] = 103652.78569932,
                                                ["x"] = 191857.72006217,
                                            }, -- end of [109]
                                            [113] = 
                                            {
                                                ["y"] = 103634.54626023,
                                                ["x"] = 191849.7870007,
                                            }, -- end of [113]
                                            [117] = 
                                            {
                                                ["y"] = 103594.74098326,
                                                ["x"] = 191847.04833445,
                                            }, -- end of [117]
                                            [121] = 
                                            {
                                                ["y"] = 103312.90144299,
                                                ["x"] = 191885.81228088,
                                            }, -- end of [121]
                                            [125] = 
                                            {
                                                ["y"] = 103263.02703687,
                                                ["x"] = 191886.06343343,
                                            }, -- end of [125]
                                            [130] = 
                                            {
                                                ["y"] = 103200.6834429,
                                                ["x"] = 191868.40807244,
                                            }, -- end of [130]
                                            [138] = 
                                            {
                                                ["y"] = 102952.65798186,
                                                ["x"] = 191741.43398321,
                                            }, -- end of [138]
                                            [79] = 
                                            {
                                                ["y"] = 107528.5650551,
                                                ["x"] = 194964.14905766,
                                            }, -- end of [79]
                                            [95] = 
                                            {
                                                ["y"] = 104616.05226429,
                                                ["x"] = 193102.35451637,
                                            }, -- end of [95]
                                            [111] = 
                                            {
                                                ["y"] = 103644.03220883,
                                                ["x"] = 191852.91292767,
                                            }, -- end of [111]
                                            [127] = 
                                            {
                                                ["y"] = 103243.35253231,
                                                ["x"] = 191882.51603864,
                                            }, -- end of [127]
                                            [131] = 
                                            {
                                                ["y"] = 103182.56487578,
                                                ["x"] = 191859.94649505,
                                            }, -- end of [131]
                                            [135] = 
                                            {
                                                ["y"] = 102975.14292081,
                                                ["x"] = 191761.24877331,
                                            }, -- end of [135]
                                            [139] = 
                                            {
                                                ["y"] = 102928.32681464,
                                                ["x"] = 191723.88895172,
                                            }, -- end of [139]
                                            [142] = 
                                            {
                                                ["y"] = 102565.95772011,
                                                ["x"] = 191426.228568,
                                            }, -- end of [142]
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            [1] = 
                                            {
                                                ["y"] = 103246.92679462,
                                                ["x"] = 191268.81589264,
                                            }, -- end of [1]
                                            [2] = 
                                            {
                                                ["y"] = 103246.92679462,
                                                ["x"] = 191268.81589264,
                                            }, -- end of [2]
                                        }, -- end of [2]
                                    }, -- end of ["spans"]
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 140,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 109319.36326561,
                                            ["x"] = 196045.53799205,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 13,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 3170.8725024458,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 102567.42160299,
                                            ["x"] = 191424.52238038,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 2.7777777777778,
                                            ["action"] = "On Road",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 58,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 112,
                                        ["y"] = 109319.36326561,
                                        ["x"] = 196045.53799205,
                                        ["name"] = "Invaders Two-2-1",
                                        ["heading"] = 3.3787244612122,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "Gepard",
                                        ["unitId"] = 113,
                                        ["y"] = 109326.70276443,
                                        ["x"] = 196074.59937024,
                                        ["name"] = "Invaders Two-2-2",
                                        ["heading"] = 3.3889714179622,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [2]
                                    [3] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 114,
                                        ["y"] = 109336.24041107,
                                        ["x"] = 196102.97765425,
                                        ["name"] = "Invaders Two-2-3",
                                        ["heading"] = 3.4658218097236,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [3]
                                    [4] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "T-90",
                                        ["unitId"] = 115,
                                        ["y"] = 109344.35189,
                                        ["x"] = 196131.74637471,
                                        ["name"] = "Invaders Two-2-4",
                                        ["heading"] = 3.4164131240164,
                                        ["playerCanDrive"] = false,
                                    }, -- end of [4]
                                    [5] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 116,
                                        ["y"] = 109350.19509631,
                                        ["x"] = 196161.06258387,
                                        ["name"] = "Invaders Two-2-5",
                                        ["heading"] = 3.3383309847229,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [5]
                                    [6] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "BTR-80",
                                        ["unitId"] = 117,
                                        ["y"] = 109356.17370484,
                                        ["x"] = 196190.45986168,
                                        ["name"] = "Invaders Two-2-6",
                                        ["heading"] = 3.3422292366278,
                                        ["playerCanDrive"] = true,
                                    }, -- end of [6]
                                }, -- end of ["units"]
                                ["y"] = 109319.36326561,
                                ["x"] = 196045.53799205,
                                ["name"] = "Invaders Two-2",
                                ["start_time"] = 0,
                            }, -- end of [14]
                        }, -- end of ["group"]
                    }, -- end of ["vehicle"]
                    ["plane"] = 
                    {
                        ["group"] = 
                        {
                            [1] = 
                            {
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["radioSet"] = false,
                                ["task"] = "CAP",
                                ["uncontrolled"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 173,
                                            ["action"] = "From Parking Area",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 138.88888888889,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                        [1] = 
                                                        {
                                                            ["enabled"] = true,
                                                            ["key"] = "CAP",
                                                            ["id"] = "EngageTargets",
                                                            ["number"] = 1,
                                                            ["auto"] = true,
                                                            ["params"] = 
                                                            {
                                                                ["targetTypes"] = 
                                                                {
                                                                    [1] = "Air",
                                                                }, -- end of ["targetTypes"]
                                                                ["priority"] = 0,
                                                            }, -- end of ["params"]
                                                        }, -- end of [1]
                                                        [2] = 
                                                        {
                                                            ["enabled"] = true,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["number"] = 2,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = true,
                                                                        ["name"] = 17,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [2]
                                                        [3] = 
                                                        {
                                                            ["enabled"] = true,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["number"] = 3,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = 4,
                                                                        ["name"] = 18,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [3]
                                                        [4] = 
                                                        {
                                                            ["enabled"] = true,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["number"] = 4,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["value"] = true,
                                                                        ["name"] = 19,
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [4]
                                                        [5] = 
                                                        {
                                                            ["enabled"] = true,
                                                            ["auto"] = true,
                                                            ["id"] = "WrappedAction",
                                                            ["number"] = 5,
                                                            ["params"] = 
                                                            {
                                                                ["action"] = 
                                                                {
                                                                    ["id"] = "Option",
                                                                    ["params"] = 
                                                                    {
                                                                        ["targetTypes"] = 
                                                                        {
                                                                        }, -- end of ["targetTypes"]
                                                                        ["name"] = 21,
                                                                        ["value"] = "none;",
                                                                        ["noTargetTypes"] = 
                                                                        {
                                                                            [1] = "Fighters",
                                                                            [2] = "Multirole fighters",
                                                                            [3] = "Bombers",
                                                                            [4] = "Helicopters",
                                                                            [5] = "Infantry",
                                                                            [6] = "Fortifications",
                                                                            [7] = "Tanks",
                                                                            [8] = "IFV",
                                                                            [9] = "APC",
                                                                            [10] = "Artillery",
                                                                            [11] = "Unarmed vehicles",
                                                                            [12] = "AAA",
                                                                            [13] = "SR SAM",
                                                                            [14] = "MR SAM",
                                                                            [15] = "LR SAM",
                                                                            [16] = "Aircraft Carriers",
                                                                            [17] = "Cruisers",
                                                                            [18] = "Destroyers",
                                                                            [19] = "Frigates",
                                                                            [20] = "Corvettes",
                                                                            [21] = "Light armed ships",
                                                                            [22] = "Unarmed ships",
                                                                            [23] = "Submarines",
                                                                            [24] = "Cruise missiles",
                                                                            [25] = "Antiship Missiles",
                                                                            [26] = "AA Missiles",
                                                                            [27] = "AG Missiles",
                                                                            [28] = "SA Missiles",
                                                                        }, -- end of ["noTargetTypes"]
                                                                    }, -- end of ["params"]
                                                                }, -- end of ["action"]
                                                            }, -- end of ["params"]
                                                        }, -- end of [5]
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "TakeOffParking",
                                            ["ETA"] = 0,
                                            ["ETA_locked"] = true,
                                            ["y"] = 48870.6328125,
                                            ["x"] = 75682.515625,
                                            ["formation_template"] = "",
                                            ["airdromeId"] = 1,
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 138.88888888889,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 522.99266963756,
                                            ["ETA_locked"] = false,
                                            ["y"] = -22963.121804303,
                                            ["x"] = 86460.825768061,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                        [3] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 138.88888888889,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1423.3690034357,
                                            ["ETA_locked"] = false,
                                            ["y"] = 69978.883141065,
                                            ["x"] = 170125.95347673,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [3]
                                        [4] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 138.88888888889,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2239.8408936136,
                                            ["ETA_locked"] = false,
                                            ["y"] = 134533.6809552,
                                            ["x"] = 181211.12077815,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [4]
                                        [5] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 138.88888888889,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2683.5767198334,
                                            ["ETA_locked"] = false,
                                            ["y"] = 81064.050442483,
                                            ["x"] = 211858.34802325,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [5]
                                        [6] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 138.88888888889,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 3133.9563501958,
                                            ["ETA_locked"] = false,
                                            ["y"] = 109429.03736082,
                                            ["x"] = 156106.47718376,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [6]
                                        [7] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 138.88888888889,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 3334.5223263057,
                                            ["ETA_locked"] = false,
                                            ["y"] = 132903.50929323,
                                            ["x"] = 171104.05647392,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [7]
                                        [8] = 
                                        {
                                            ["alt"] = 2000,
                                            ["action"] = "Turning Point",
                                            ["alt_type"] = "BARO",
                                            ["properties"] = 
                                            {
                                                ["addopt"] = 
                                                {
                                                }, -- end of ["addopt"]
                                            }, -- end of ["properties"]
                                            ["speed"] = 138.88888888889,
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 3832.9169327859,
                                            ["ETA_locked"] = false,
                                            ["y"] = 68022.677146697,
                                            ["x"] = 195230.59707112,
                                            ["formation_template"] = "",
                                            ["speed_locked"] = true,
                                        }, -- end of [8]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 23,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["alt"] = 173,
                                        ["hardpoint_racks"] = true,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Afghanistan (1)",
                                        ["skill"] = "Good",
                                        ["parking"] = "8",
                                        ["speed"] = 138.88888888889,
                                        ["type"] = "MiG-21Bis",
                                        ["unitId"] = 54,
                                        ["psi"] = 1.4218621732169,
                                        ["parking_id"] = "02",
                                        ["x"] = 75682.515625,
                                        ["name"] = "Aerial-1-1",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{R-3S}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{R-3R}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{PTB_800_MIG21}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{R-3R}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{R-3S}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{ASO-2}",
                                                }, -- end of [6]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 2280,
                                            ["flare"] = 40,
                                            ["ammo_type"] = 1,
                                            ["chaff"] = 18,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["y"] = 48870.6328125,
                                        ["heading"] = -1.4218621732169,
                                        ["callsign"] = 
                                        {
                                            [1] = 1,
                                            [2] = 1,
                                            [3] = 1,
                                            ["name"] = "Enfield11",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "018",
                                    }, -- end of [1]
                                    [2] = 
                                    {
                                        ["alt"] = 173,
                                        ["alt_type"] = "BARO",
                                        ["livery_id"] = "Afghanistan (1)",
                                        ["skill"] = "Good",
                                        ["parking"] = "7",
                                        ["speed"] = 138.88888888889,
                                        ["type"] = "MiG-21Bis",
                                        ["unitId"] = 55,
                                        ["psi"] = 1.4218621732169,
                                        ["parking_id"] = "01",
                                        ["x"] = 75708.328125,
                                        ["name"] = "Aerial-1-2",
                                        ["payload"] = 
                                        {
                                            ["pylons"] = 
                                            {
                                                [1] = 
                                                {
                                                    ["CLSID"] = "{R-3S}",
                                                }, -- end of [1]
                                                [2] = 
                                                {
                                                    ["CLSID"] = "{R-3R}",
                                                }, -- end of [2]
                                                [3] = 
                                                {
                                                    ["CLSID"] = "{PTB_800_MIG21}",
                                                }, -- end of [3]
                                                [4] = 
                                                {
                                                    ["CLSID"] = "{R-3R}",
                                                }, -- end of [4]
                                                [5] = 
                                                {
                                                    ["CLSID"] = "{R-3S}",
                                                }, -- end of [5]
                                                [6] = 
                                                {
                                                    ["CLSID"] = "{ASO-2}",
                                                }, -- end of [6]
                                            }, -- end of ["pylons"]
                                            ["fuel"] = 2280,
                                            ["flare"] = 40,
                                            ["ammo_type"] = 1,
                                            ["chaff"] = 18,
                                            ["gun"] = 100,
                                        }, -- end of ["payload"]
                                        ["y"] = 48871.59765625,
                                        ["heading"] = -1.4218621732169,
                                        ["callsign"] = 
                                        {
                                            [1] = 1,
                                            [2] = 1,
                                            [3] = 2,
                                            ["name"] = "Enfield12",
                                        }, -- end of ["callsign"]
                                        ["onboard_num"] = "019",
                                    }, -- end of [2]
                                }, -- end of ["units"]
                                ["y"] = 48870.6328125,
                                ["x"] = 75682.515625,
                                ["name"] = "Aerial-1",
                                ["communication"] = true,
                                ["start_time"] = 0,
                                ["modulation"] = 0,
                                ["frequency"] = 124,
                            }, -- end of [1]
                        }, -- end of ["group"]
                    }, -- end of ["plane"]
                }, -- end of [1]
                [2] = 
                {
                    ["id"] = 0,
                    ["name"] = "Russia",
                    ["ship"] = 
                    {
                        ["group"] = 
                        {
                            [1] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 117364.15910153,
                                            ["x"] = 202161.40471415,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 250.62171156378,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 108113.26269357,
                                            ["x"] = 188659.67775097,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                        [3] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 472.1061126147,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 109424.05796827,
                                            ["x"] = 185876.75855237,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [3]
                                        [4] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 656.52202498113,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 109746.71526666,
                                            ["x"] = 183335.83232755,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [4]
                                        [5] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 808.91545653245,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 107931.76796322,
                                            ["x"] = 182246.86394549,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [5]
                                        [6] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 978.30373236902,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 105653.00079335,
                                            ["x"] = 182831.68029882,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [6]
                                        [7] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1096.5915974996,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 104422.86984325,
                                            ["x"] = 181742.71191676,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [7]
                                        [8] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1387.3642412831,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 107165.45687955,
                                            ["x"] = 178778.29798781,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [8]
                                        [9] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1682.0403382567,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 104301.87335635,
                                            ["x"] = 175854.21622116,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [9]
                                        [10] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1920.6038365209,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 101478.62199545,
                                            ["x"] = 177588.4992,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [10]
                                        [11] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2147.8945219295,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 98473.875904201,
                                            ["x"] = 178556.47109517,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [11]
                                        [12] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2415.5791784627,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 95287.635082612,
                                            ["x"] = 180472.24880435,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [12]
                                        [13] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2667.6728415879,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 96437.101708122,
                                            ["x"] = 183779.48611284,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [13]
                                        [14] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2906.8893836096,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 98252.049011559,
                                            ["x"] = 186562.40531144,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [14]
                                        [15] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 3204.6577739117,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 99401.515637069,
                                            ["x"] = 190535.12329786,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [15]
                                        [16] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 3513.8977243149,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 102547.42429636,
                                            ["x"] = 193459.2050645,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [16]
                                        [17] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 3950.560897489,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 107508.28025909,
                                            ["x"] = 196947.93710333,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [17]
                                        [18] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 4255.5117462385,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 110633.92936745,
                                            ["x"] = 199806.10940148,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [18]
                                        [19] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 4556.0670809719,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 114277.92454191,
                                            ["x"] = 197769.75915693,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [19]
                                        [20] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 4862.0331515945,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 113742.04289861,
                                            ["x"] = 193554.15689627,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [20]
                                        [21] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 5350.8387447497,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 107883.07026515,
                                            ["x"] = 190124.51437912,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [21]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 15,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "MOLNIYA",
                                        ["unitId"] = 41,
                                        ["y"] = 117364.15910153,
                                        ["x"] = 202161.40471415,
                                        ["name"] = "Naval-1-1",
                                        ["heading"] = 3.7422919773631,
                                        ["modulation"] = 0,
                                        ["frequency"] = 127500000,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 117364.15910153,
                                ["x"] = 202161.40471415,
                                ["name"] = "Bad News",
                                ["start_time"] = 0,
                            }, -- end of [1]
                            [2] = 
                            {
                                ["visible"] = false,
                                ["hiddenOnPlanner"] = true,
                                ["tasks"] = 
                                {
                                }, -- end of ["tasks"]
                                ["uncontrollable"] = false,
                                ["route"] = 
                                {
                                    ["points"] = 
                                    {
                                        [1] = 
                                        {
                                            ["alt"] = -0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 0,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 128744.70770435,
                                            ["x"] = 148786.1865043,
                                            ["ETA_locked"] = true,
                                            ["speed"] = 0,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [1]
                                        [2] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2396.9267360977,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 106667.71423228,
                                            ["x"] = 173703.49492599,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [2]
                                        [3] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 472.1061126147,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 109746.88732763,
                                            ["x"] = 185372.242283,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [3]
                                        [4] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 656.52202498113,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 110069.54462602,
                                            ["x"] = 182831.31605818,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [4]
                                        [5] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 808.91545653245,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 108254.59732258,
                                            ["x"] = 181742.34767612,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [5]
                                        [6] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 978.30373236902,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 105975.83015271,
                                            ["x"] = 182327.16402945,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [6]
                                        [7] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1096.5915974996,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 104745.69920261,
                                            ["x"] = 181238.19564739,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [7]
                                        [8] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1387.3642412831,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 107488.28623891,
                                            ["x"] = 178273.78171844,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [8]
                                        [9] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1682.0403382567,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 104624.70271571,
                                            ["x"] = 175349.69995179,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [9]
                                        [10] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 1920.6038365209,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 101801.45135481,
                                            ["x"] = 177083.98293063,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [10]
                                        [11] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2147.8945219295,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 98796.705263559,
                                            ["x"] = 178051.9548258,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [11]
                                        [12] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2415.5791784627,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 95610.46444197,
                                            ["x"] = 179967.73253498,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [12]
                                        [13] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2667.6728415879,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 96759.93106748,
                                            ["x"] = 183274.96984347,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [13]
                                        [14] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 2906.8893836096,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 98574.878370917,
                                            ["x"] = 186057.88904207,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [14]
                                        [15] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 3204.6577739117,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 99724.344996427,
                                            ["x"] = 190030.60702849,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [15]
                                        [16] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 3513.8977243149,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 102870.25365572,
                                            ["x"] = 192954.68879513,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [16]
                                        [17] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 3950.560897489,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 107831.10961845,
                                            ["x"] = 196443.42083396,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [17]
                                        [18] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 4255.5117462385,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 110956.75872681,
                                            ["x"] = 199301.59313211,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [18]
                                        [19] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 4556.0670809719,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 114600.75390127,
                                            ["x"] = 197265.24288756,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [19]
                                        [20] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 4862.0331515945,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 114064.87225797,
                                            ["x"] = 193049.6406269,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [20]
                                        [21] = 
                                        {
                                            ["alt"] = 0,
                                            ["type"] = "Turning Point",
                                            ["ETA"] = 5350.8387447497,
                                            ["alt_type"] = "BARO",
                                            ["formation_template"] = "",
                                            ["y"] = 108205.89962451,
                                            ["x"] = 189619.99810975,
                                            ["ETA_locked"] = false,
                                            ["speed"] = 13.88888,
                                            ["action"] = "Turning Point",
                                            ["task"] = 
                                            {
                                                ["id"] = "ComboTask",
                                                ["params"] = 
                                                {
                                                    ["tasks"] = 
                                                    {
                                                    }, -- end of ["tasks"]
                                                }, -- end of ["params"]
                                            }, -- end of ["task"]
                                            ["speed_locked"] = true,
                                        }, -- end of [21]
                                    }, -- end of ["points"]
                                }, -- end of ["route"]
                                ["groupId"] = 26,
                                ["hidden"] = false,
                                ["units"] = 
                                {
                                    [1] = 
                                    {
                                        ["transportable"] = 
                                        {
                                            ["randomTransportable"] = false,
                                        }, -- end of ["transportable"]
                                        ["skill"] = "Average",
                                        ["type"] = "MOLNIYA",
                                        ["unitId"] = 60,
                                        ["y"] = 128744.70770435,
                                        ["x"] = 148786.1865043,
                                        ["name"] = "Bad News-1-1",
                                        ["heading"] = 5.558153271064,
                                        ["modulation"] = 0,
                                        ["frequency"] = 127500000,
                                    }, -- end of [1]
                                }, -- end of ["units"]
                                ["y"] = 128744.70770435,
                                ["x"] = 148786.1865043,
                                ["name"] = "Bad News-1",
                                ["start_time"] = 0,
                            }, -- end of [2]
                        }, -- end of ["group"]
                    }, -- end of ["ship"]
                }, -- end of [2]
            }, -- end of ["country"]
        }, -- end of ["red"]
    }, -- end of ["coalition"]
    ["sortie"] = "DictKey_sortie_5",
    ["version"] = 20,
    ["trigrules"] = 
    {
        [1] = 
        {
            ["rules"] = 
            {
            }, -- end of ["rules"]
            ["comment"] = "Load Lua",
            ["eventlist"] = "",
            ["predicate"] = "triggerStart",
            ["actions"] = 
            {
                [1] = 
                {
                    ["text"] = "dcsCommon = {}\
dcsCommon.version = \"2.5.6\"\
--[[-- VERSION HISTORY\
 2.2.6 - compassPositionOfARelativeToB\
       - clockPositionOfARelativeToB\
 2.2.7 - isTroopCarrier \
       - distFlat\
 2.2.8 - fixed event2text \
 2.2.9 - getUnitAGL\
       - getUnitAlt\
       - getUnitSpeed \
       - getUnitHeading\
       - getUnitHeadingDegrees\
       - mag\
       - clockPositionOfARelativeToB with own heading \
 2.3.0 - unitIsInfantry\
 2.3.1 - bool2YesNo\
       - bool2Text\
 2.3.2 - getGroupAvgSpeed\
       - getGroupMaxSpeed\
 2.3.3 - getSizeOfTable\
 2.3.4 - isSceneryObject\
         coalition2county\
 2.3.5 - smallRandom\
         pickRandom uses smallRandom\
         airfield handling, parking \
         flight waypoint handling\
         landing waypoint creation\
         take-off waypoint creation\
 2.3.6 - createOverheadAirdromeRoutPintData(aerodrome)\
 2.3.7 - coalition2county - warning when creating UN \
 2.3.8 - improved headingOfBInDegrees, new getClockDirection\
 2.3.9 - getClosingVelocity\
       - dot product \
       - magSquare\
       - vMag\
 2.4.0 - libCheck\
 2.4.1 - grid/square/rect formation \
       - arrangeGroupInNColumns formation \
       - 2Columns formation deep and wide formation\
 2.4.2 - getAirbasesInRangeOfPoint\
 2.4.3 - lerp \
 2.4.4 - getClosestAirbaseTo\
       - fixed bug in containsString when strings equal\
 2.4.5 - added cargo and mass options to createStaticObjectData\
 2.4.6 - fixed randompercent \
 2.4.7 - smokeColor2Num(smokeColor)\
 2.4.8 - linkStaticDataToUnit()\
 2.4.9 - trim functions \
       - createGroundUnitData uses trim function to remove leading/trailing blanks\
         so now we can use blanks after comma to separate types \
       - dcsCommon.trimArray(\
       - createStaticObjectData uses trim for type \
       - getEnemyCoalitionFor understands strings, still returns number\
       - coalition2county also undertsands 'red' and 'blue'\
 2.5.0 - \"Line\" formation with one unit places unit at center     \
 2.5.1 - vNorm(a)  \
 2.5.1 - added SA-18 Igla manpad to unitIsInfantry()\
 2.5.2 - added copyArray method\
       - corrected heading in createStaticObjectData\
 2.5.3 - corrected rotateGroupData bug for cz \
       - removed forced error in failed pickRandom\
 2.5.4 - rotateUnitData()\
       - randomBetween()\
 2.5.5 - stringStartsWithDigit()\
       - stringStartsWithLetter()\
       - stringIsPositiveNumber()\
 2.5.6 - corrected stringEndsWith() bug with str\
       \
--]]--\
\
    -- dcsCommon is a library of common lua functions \
    -- for easy access and simple mission programming\
    -- (c) 2021, 2022 by Chritian Franz and cf/x AG\
\
    dcsCommon.verbose = false -- set to true to see debug messages. Lots of them\
    dcsCommon.uuidStr = \"uuid-\"\
\
    -- globals\
    dcsCommon.cbID = 0 -- callback id for simple callback scheduling\
    dcsCommon.troopCarriers = {\"Mi-8MT\", \"UH-1H\", \"Mi-24P\"} -- Ka-50 and Gazelle can't carry troops\
\
    -- verify that a module is loaded. obviously not required\
    -- for dcsCommon, but all higher-order modules\
    function dcsCommon.libCheck(testingFor, requiredLibs)\
        local canRun = true \
        for idx, libName in pairs(requiredLibs) do \
            if not _G[libName] then \
                trigger.action.outText(\"*** \" .. testingFor .. \" requires \" .. libName, 30)\
                canRun = false \
            end\
        end\
        return canRun\
    end\
\
    -- returns only positive values, lo must be >0 and <= hi \
    function dcsCommon.randomBetween(loBound, hiBound)\
        if not loBound then loBound = 1 end \
        if not hiBound then hiBound = 1 end \
        if loBound == hiBound then return loBound end \
\
        local delayMin = loBound\
        local delayMax = hiBound \
        local delay = delayMax \
    \
        if delayMin ~= delayMax then \
            -- pick random in range , say 3-7 --> 5 s!\
            local delayDiff = (delayMax - delayMin) + 1 -- 7-3 + 1\
            delay = dcsCommon.smallRandom(delayDiff) - 1 --> 0-4\
            delay = delay + delayMin \
            if delay > delayMax then delay = delayMax end \
            if delay < 1 then delay = 1 end \
        \
            if dcsCommon.verbose then \
                trigger.action.outText(\"+++dcsC: delay range \" .. delayMin .. \"-\" .. delayMax .. \": selected \" .. delay, 30)\
            end\
        end\
        \
        return delay\
    end\
    \
\
    -- taken inspiration from mist, as dcs lua has issues with\
    -- random numbers smaller than 50. Given a range of x numbers 1..x, it is \
    -- repeated a number of times until it fills an array of at least \
    -- 50 items (usually some more), and only then one itemis picked from \
    -- that array with a random number that is from a greater range (0..50+)\
    function dcsCommon.smallRandom(theNum) -- adapted from mist, only support ints\
        if theNum >= 50 then return math.random(theNum) end\
        \
        -- for small randoms (<50) \
        local lowNum, highNum\
        highNum = theNum\
        lowNum = 1\
        local total = 1\
        if math.abs(highNum - lowNum + 1) < 50 then -- if total values is less than 50\
            total = math.modf(50/math.abs(highNum - lowNum + 1)) -- number of times to repeat whole range to get above 50. e.g. 11 would be 5 times 1 .. 11, giving us 55 items total \
        end\
        local choices = {}\
        for i = 1, total do -- iterate required number of times\
            for x = lowNum, highNum do -- iterate between the range\
                choices[#choices +1] = x -- add each entry to a table\
            end\
        end\
        local rtnVal; -- = math.random(#choices) -- will now do a math.random of at least 50 choices\
        for i = 1, 15 do\
            rtnVal = math.random(#choices) -- iterate 15 times for randomization\
        end\
        return choices[rtnVal] -- return indexed\
    end\
    \
\
    function dcsCommon.getSizeOfTable(theTable)\
        local count = 0\
        for _ in pairs(theTable) do count = count + 1 end\
        return count\
    end\
\
    function dcsCommon.findAndRemoveFromTable(theTable, theElement) -- assumes array \
        if not theElement then return false end \
        if not theTable then return false end \
        for i=1, #theTable do \
            if theTable[i] == theElement then \
                -- this element found. remove from table \
                table.remove(theTable, i)\
                return true \
            end\
        end\
    end\
\
    function dcsCommon.pickRandom(theTable)\
        if not theTable then \
            trigger.action.outText(\"*** warning: nil table in pick random\", 30)\
        end\
        \
        if #theTable < 1 then \
            trigger.action.outText(\"*** warning: zero choice in pick random\", 30)\
            --local k = i.ll \
            return nil\
        end\
        if #theTable == 1 then return theTable[1] end\
        r = dcsCommon.smallRandom(#theTable) --r = math.random(#theTable)\
        return theTable[r]\
    end\
\
    -- enumerateTable - make an array out of a table for indexed access\
    function dcsCommon.enumerateTable(theTable)\
        if not theTable then theTable = {} end\
        local array = {}\
        for key, value in pairs(theTable) do \
            table.insert(array, value)\
        end\
        return array\
    end\
\
-- \
-- A I R F I E L D S  A N D  F A R P S  \
--\
\
    -- airfield management \
    function dcsCommon.getAirbaseCat(aBase)\
        if not aBase then return nil end \
        \
        local airDesc = aBase:getDesc()\
        if not airDesc then return nil end \
        \
        local airCat = airDesc.category\
        return airCat \
    end\
\
    -- get free parking slot. optional parkingType can be used to \
    -- filter for a scpecific type, e.g. 104 = open field\
    function dcsCommon.getFirstFreeParkingSlot(aerodrome, parkingType) \
        if not aerodrome then return nil end \
        local freeSlots = aerodrome:getParking(true)\
        \
        for idx, theSlot in pairs(freeSlots) do \
            if not parkingType then \
                -- simply return the first we come across\
                return theSlot\
            end        \
            \
            if theSlot.Term_Type == parkingType then \
                return theSlot \
            end\
        end\
        \
        return nil \
    end\
\
    -- getAirbasesInRangeOfPoint: get airbases that are in range of point \
    function dcsCommon.getAirbasesInRangeOfPoint(center, range, filterCat, filterCoalition)\
        if not center then return {} end \
        if not range then range = 500 end -- 500m default \
        local basesInRange = {}\
        \
        local allAB = dcsCommon.getAirbasesWhoseNameContains(\"*\", filterCat, filterCoalition)\
        for idx, aBase in pairs(allAB) do             \
            local delta = dcsCommon.dist(center, aBase:getPoint())\
            if delta <= range then \
                table.insert(basesInRange, aBase)\
            end\
        end\
        return basesInRange\
    end\
\
    -- getAirbasesInRangeOfAirbase returns all airbases that \
    -- are in range of the given airbase \
    function dcsCommon.getAirbasesInRangeOfAirbase(airbase, includeCenter, range, filterCat, filterCoalition)\
        if not airbase then return {} end\
        if not range then range = 150000 end \
        local center = airbase:getPoint() \
        local centerName = airbase:getName() \
        \
        local ABinRange = {}\
        local allAB = dcsCommon.getAirbasesWhoseNameContains(\"*\", filterCat, filterCoalition)\
        \
        for idx, aBase in pairs(allAB) do \
            if aBase:getName() ~= centerName then \
                local delta = dcsCommon.dist(center, aBase:getPoint())\
                if delta <= range then \
                    table.insert(ABinRange, aBase)\
                end\
            end        \
        end\
        \
        if includeCenter then \
            table.insert(ABinRange, airbase)\
        end\
        \
        return ABinRange\
    end\
\
    function dcsCommon.getAirbasesInRangeOfAirbaseList(theCenterList, includeList, range, filterCat, filterCoalition)\
        local collectorDict = {}\
        for idx, aCenter in pairs(theCenterList) do \
            -- get all surrounding airbases. returns list of airfields \
            local surroundingAB = dcsCommon.getAirbasesInRangeOfAirbase(airbase, includeList, range, filterCat, filterCoalition)\
            \
            for idx2, theAirField in pairs (surroundingAB) do \
                collectorDict[airField] = theAirField \
            end\
        end\
        \
        -- make result an array\
        local theABList = dcsCommon.enumerateTable(collectorDict)\
        return theABList\
    end\
\
    -- getAirbasesWhoseNameContains - get all airbases containing \
    -- a name. filterCat is optional and can be aerodrome (0), farp (1), ship (2)\
    -- filterCoalition is optional and can be 0 (neutral), 1 (red), 2 (blue) \
    -- if no name given or aName = \"*\", then all bases are returned prior to filtering \
    function dcsCommon.getAirbasesWhoseNameContains(aName, filterCat, filterCoalition)\
        --trigger.action.outText(\"getAB(name): enter with \" .. aName, 30)\
        if not aName then aName = \"*\" end \
        local allYourBase = world.getAirbases() -- get em all \
        local areBelongToUs = {}\
        -- now iterate all bases\
        for idx, aBase in pairs(allYourBase) do\
            local airBaseName = aBase:getName() -- get display name\
            if aName == \"*\" or dcsCommon.containsString(airBaseName, aName) then \
                -- containsString is case insesitive unless told otherwise\
                --if aName ~= \"*\" then \
                --    trigger.action.outText(\"getAB(name): matched \" .. airBaseName, 30)\
                --end \
                local doAdd = true \
                if filterCat then \
                    -- make sure the airbase is of that category \
                    local airCat = dcsCommon.getAirbaseCat(aBase)\
                    doAdd = doAdd and airCat == filterCat \
                end\
                \
                if filterCoalition then \
                    doAdd = doAdd and filterCoalition == aBase:getCoalition()\
                end\
                \
                if doAdd then \
                    -- all good, add to table\
                    table.insert(areBelongToUs, aBase)\
                end            \
            end\
        end\
        return areBelongToUs\
    end\
\
    function dcsCommon.getFirstAirbaseWhoseNameContains(aName, filterCat, filterCoalition)\
        local allBases = dcsCommon.getAirbasesWhoseNameContains(aName, filterCat, filterCoalition)\
        for idx, aBase in pairs (allBases) do \
            -- simply return first \
            return aBase\
        end\
        return nil \
    end    \
\
    function dcsCommon.getClosestAirbaseTo(thePoint, filterCat, filterCoalition)\
        local delta = math.huge\
        local allYourBase = dcsCommon.getAirbasesWhoseNameContains(\"*\", filterCat, filterCoalition) -- get em all and filter\
        local closestBase = nil \
        for idx, aBase in pairs(allYourBase) do\
            -- iterate them all \
            local abPoint = aBase:getPoint()\
            newDelta = dcsCommon.dist(thePoint, {x=abPoint.x, y = 0, z=abPoint.z})\
            if newDelta < delta then \
                delta = newDelta\
                closestBase = aBase\
            end\
        end\
        return closestBase, delta \
    end\
\
-- \
-- U N I T S   M A N A G E M E N T \
--\
\
    -- number of living units in group\
    function dcsCommon.livingUnitsInGroup(group)\
        local living = 0\
        local allUnits = group:getUnits()\
        for key, aUnit in pairs(allUnits) do \
            if aUnit:isExist() and aUnit:getLife() >= 1 then \
                living = living + 1\
            end\
        end\
        return living\
    end\
\
    -- closest living unit in group to a point\
    function dcsCommon.getClosestLivingUnitToPoint(group, p)\
        if not p then return nil end\
        if not group then return nil end\
        local closestUnit = nil\
        local closestDist = math.huge\
        local allUnits = group:getUnits()\
        for key, aUnit in pairs(allUnits) do \
            if aUnit:isExist() and aUnit:getLife() >= 1 then \
                local thisDist = dcsCommon.dist(p, aUnit:getPoint())\
                if thisDist < closestDist then \
                    closestDist = thisDist\
                    closestUnit = aUnit \
                end\
            end\
        end\
        return closestUnit, closestDist\
    end\
    \
    -- closest living group to a point - cat can be nil or one of Group.Category = { AIRPLANE = 0, HELICOPTER = 1, GROUND = 2, SHIP = 3, TRAIN = 4}\
    function dcsCommon.getClosestLivingGroupToPoint(p, coal, cat) \
        if not cat then cat = 2 end -- ground is default \
        local closestGroup = nil;\
        local closestGroupDist = math.huge\
        local allGroups =  coalition.getGroups(coal, cat) -- get all groups from this coalition, perhaps filtered by cat \
        for key, grp in pairs(allGroups) do\
            local closestUnit, dist = dcsCommon.getClosestLivingUnitToPoint(grp, p)\
            if closestUnit then \
                if dist < closestGroupDist then \
                    closestGroup = grp\
                    closestGroupDist = dist\
                end\
            end            \
        end\
        return closestGroup, closestGroupDist\
    end\
\
    function dcsCommon.getLivingGroupsAndDistInRangeToPoint(p, range, coal, cat) \
        if not cat then cat = 2 end -- ground is default \
        local groupsInRange = {};\
        local allGroups = coalition.getGroups(coal, cat) -- get all groups from this coalition, perhaps filtered by cat \
        for key, grp in pairs(allGroups) do\
            local closestUnit, dist = dcsCommon.getClosestLivingUnitToPoint(grp, p)\
            if closestUnit then \
                if dist < range then \
                    table.insert(groupsInRange, {group = grp, dist = dist}) -- array\
                end\
            end            \
        end\
        -- sort the groups by distance\
        table.sort(groupsInRange, function (left, right) return left.dist < right.dist end )\
        return groupsInRange\
    end\
\
    -- distFlat ignores y, input must be xyz points, NOT xy points  \
    function dcsCommon.distFlat(p1, p2) \
        local point1 = {x = p1.x, y = 0, z=p1.z}\
        local point2 = {x = p2.x, y = 0, z=p2.z}\
        return dcsCommon.dist(point1, point2)\
    end\
    \
    -- distance between points\
    function dcsCommon.dist(point1, point2)     -- returns distance between two points\
      -- supports xyz and xy notations\
      if not point1 then \
        trigger.action.outText(\"+++ warning: nil point1 in common:dist\", 30)\
        point1 = {x=0, y=0, z=0}\
      end\
\
      if not point2 then \
        trigger.action.outText(\"+++ warning: nil point2 in common:dist\", 30)\
        point2 = {x=0, y=0, z=0}\
        stop.here.now = 1\
      end\
      \
      local p1 = {x = point1.x, y = point1.y}\
      if not point1.z then \
        p1.z = p1.y\
        p1.y = 0\
      else \
        p1.z = point1.z\
      end\
      \
      local p2 = {x = point2.x, y = point2.y}\
      if not point2.z then \
        p2.z = p2.y\
        p2.y = 0\
      else \
        p2.z = point2.z\
      end\
      \
      local x = p1.x - p2.x\
      local y = p1.y - p2.y \
      local z = p1.z - p2.z\
      \
      return (x*x + y*y + z*z)^0.5\
    end\
\
    function dcsCommon.delta(name1, name2) -- returns distance (in meters) of two named objects\
      local n1Pos = Unit.getByName(name1):getPosition().p\
      local n2Pos = Unit.getByName(name2):getPosition().p\
      return dcsCommon.dist(n1Pos, n2Pos)\
    end\
\
    -- lerp between a and b, x being 0..1 (percentage), clipped to [0..1]\
    function dcsCommon.lerp(a, b, x) \
        if not a then return 0 end\
        if not b then return 0 end\
        if not x then return a end\
        if x < 0 then x = 0 end \
        if x > 1 then x = 1 end \
        return a + (b - a ) * x\
    end\
\
    function dcsCommon.bearingFromAtoB(A, B) -- coords in x, z \
        dx = B.x - A.x\
        dz = B.z - A.z\
        bearing = math.atan2(dz, dx) -- in radiants\
        return bearing\
    end\
\
    function dcsCommon.bearingInDegreesFromAtoB(A, B)\
        local bearing = dcsCommon.bearingFromAtoB(A, B) -- in rads \
        bearing = math.floor(bearing / math.pi * 180)\
        if bearing < 0 then bearing = bearing + 360 end\
        if bearing > 360 then bearing = bearing - 360 end\
        return bearing\
    end\
    \
    function dcsCommon.compassPositionOfARelativeToB(A, B)\
        -- warning: is REVERSE in order for bearing, returns a string like 'Sorth', 'Southwest'\
        if not A then return \"***error:A***\" end\
        if not B then return \"***error:B***\" end\
        local bearing = dcsCommon.bearingInDegreesFromAtoB(B, A) -- returns 0..360\
        if bearing < 23 then return \"North\" end \
        if bearing < 68 then return \"NE\" end\
        if bearing < 112 then return \"East\" end \
        if bearing < 158 then return \"SE\" end \
        if bearing < 202 then return \"South\" end \
        if bearing < 248 then return \"SW\" end \
        if bearing < 292 then return \"West\" end\
        if bearing < 338 then return \"NW\" end \
        return \"North\"\
    end\
    \
    function dcsCommon.clockPositionOfARelativeToB(A, B, headingOfBInDegrees)\
        -- o'clock notation \
        if not A then return \"***error:A***\" end\
        if not B then return \"***error:B***\" end\
        if not headingOfBInDegrees then headingOfBInDegrees = 0 end \
        \
        local bearing = dcsCommon.bearingInDegreesFromAtoB(B, A) -- returns 0..360\
--        trigger.action.outText(\"+++comm: oclock - bearing = \" .. bearing .. \" and inHeading = \" .. headingOfBInDegrees, 30) \
        bearing = bearing - headingOfBInDegrees\
        return dcsCommon.getClockDirection(bearing)\
        \
    end \
    \
    -- given a heading, return clock with 0 being 12, 180 being 6 etc.\
    function dcsCommon.getClockDirection(direction) -- inspired by cws, improvements my own\
        if not direction then return 0 end\
        direction = math.fmod (direction, 360)\
        while direction < 0 do \
            direction = direction + 360\
        end\
        \
        if direction < 15 then -- special case 12 o'clock past 12 o'clock\
            return 12\
        end\
    \
        direction = direction + 15 -- add offset so we get all other times correct\
        return math.floor(direction/30)\
    \
    end\
\
    \
    function dcsCommon.randomDegrees()\
        local degrees = math.random(360) * 3.14152 / 180\
        return degrees\
    end\
\
    function dcsCommon.randomPercent()\
        local percent = math.random(100)/100\
        return percent\
    end\
\
    function dcsCommon.randomPointOnPerimeter(sourceRadius, x, z) \
        return dcsCommon.randomPointInCircle(sourceRadius, sourceRadius-1, x, z)\
    end\
\
    function dcsCommon.randomPointInCircle(sourceRadius, innerRadius, x, z)\
        if not x then x = 0 end\
        --local y = 0\
        if not innerRadius then innerRadius = 0 end        \
        if innerRadius < 0 then innerRadius = 0 end\
        \
        local percent = dcsCommon.randomPercent() -- 1 / math.random(100)\
        -- now lets get a random degree\
        local degrees = dcsCommon.randomDegrees() -- math.random(360) * 3.14152 / 180 -- ok, it's actually radiants. \
        local r = (sourceRadius-innerRadius) * percent \
        local x = x + (innerRadius + r) * math.cos(degrees)\
        local z = z + (innerRadius + r) * math.sin(degrees)\
    \
        local thePoint = {}\
        thePoint.x = x\
        thePoint.y = 0\
        thePoint.z = z \
        \
        return thePoint, degrees\
    end\
\
    -- get group location: get the group's location by \
    -- accessing the fist existing, alive member of the group that it finds\
    function dcsCommon.getGroupLocation(group)\
        -- nifty trick from mist: make this work with group and group name\
        if type(group) == 'string' then -- group name\
            group = Group.getByName(group)\
        end\
        \
        -- get all units\
        local allUnits = group:getUnits()\
\
        -- iterate through all members of group until one is alive and exists\
        for index, theUnit in pairs(allUnits) do \
            if (theUnit:isExist() and theUnit:getLife() > 0) then \
                return theUnit:getPosition().p \
            end;\
        end\
\
        -- if we get here, there was no live unit \
        --trigger.action.outText(\"+++cmn: A group has no live units. returning nil\", 10)\
        return nil \
        \
    end\
\
    -- get the group's first Unit that exists and is \
    -- alive \
    function dcsCommon.getGroupUnit(group)\
        if not group then return nil  end\
        \
        -- nifty trick from mist: make this work with group and group name\
        if type(group) == 'string' then -- group name\
            group = Group.getByName(group)\
        end\
        \
        if not group:isExist() then return nil end \
        \
        -- get all units\
        local allUnits = group:getUnits()\
\
        -- iterate through all members of group until one is alive and exists\
        for index, theUnit in pairs(allUnits) do \
            if (theUnit:isExist() and theUnit:getLife() > 0) then \
                return theUnit\
            end;\
        end\
\
        -- if we get here, there was no live unit \
        --trigger.action.outText(\"+++cmn A group has no live units. returning nil\", 10)\
        return nil \
        \
    end\
\
    -- and here the alias\
    function dcsCommon.getFirstLivingUnit(group)\
        return dcsCommon.getGroupUnit(group)\
    end\
    \
    -- isGroupAlive returns true if there is at least one unit in the group that isn't dead\
    function dcsCommon.isGroupAlive(group)\
        return (dcsCommon.getGroupUnit(group) ~= nil) \
    end\
\
    function dcsCommon.getLiveGroupUnits(group)\
        -- nifty trick from mist: make this work with group and group name\
        if type(group) == 'string' then -- group name\
            group = Group.getByName(group)\
        end\
        \
        local liveUnits = {}\
        -- get all units\
        local allUnits = group:getUnits()\
\
        -- iterate through all members of group until one is alive and exists\
        for index, theUnit in pairs(allUnits) do \
            if (theUnit:isExist() and theUnit:getLife() > 0) then \
                table.insert(liveUnits, theUnit) \
            end;\
        end\
\
        -- if we get here, there was no live unit \
        return liveUnits\
    end\
\
    function dcsCommon.getGroupTypeString(group) -- convert into comma separated types \
        if not group then \
            trigger.action.outText(\"+++cmn getGroupTypeString: nil group\", 30)\
            return \"\" \
        end\
        if not dcsCommon.isGroupAlive(group) then \
            trigger.action.outText(\"+++cmn getGroupTypeString: dead group\", 30)\
            return \"\" \
        end \
        local theTypes = \"\"\
        local liveUnits = dcsCommon.getLiveGroupUnits(group)\
        for i=1, #liveUnits do \
            if i > 1 then theTypes = theTypes .. \",\" end\
            theTypes = theTypes .. liveUnits[i]:getTypeName()\
        end\
        return theTypes\
    end\
\
    function dcsCommon.getGroupTypes(group) \
        if not group then \
            trigger.action.outText(\"+++cmn getGroupTypes: nil group\", 30)\
            return {}\
        end\
        if not dcsCommon.isGroupAlive(group) then \
            trigger.action.outText(\"+++cmn getGroupTypes: dead group\", 30)\
            return {}\
        end \
        local liveUnits = dcsCommon.getLiveGroupUnits(group)\
        local unitTypes = {}\
        for i=1, #liveUnits do \
            table.insert(unitTypes, liveUnits[i]:getTypeName())\
        end\
        return unitTypes\
    end\
\
    function dcsCommon.getEnemyCoalitionFor(aCoalition)\
        if aCoalition == 1 then return 2 end\
        if aCoalition == 2 then return 1 end\
        if type(aCoalition) == \"string\" then \
            aCoalition = aCoalition:lower()\
            if aCoalition == \"red\" then return 2 end\
            if aCoalition == \"blue\" then return 1 end\
        end\
        return nil\
    end\
\
    function dcsCommon.getACountryForCoalition(aCoalition)\
        -- scan the table of countries and get the first country that is part of aCoalition\
        -- this is useful if you want to create troops for a coalition but don't know the\
        -- coalition's countries \
        -- we start with id=0 (Russia), go to id=85 (Slovenia), but skip id = 14\
        local i = 0\
        while i < 86 do \
            if i ~= 14 then \
                if (coalition.getCountryCoalition(i) == aCoalition) then return i end\
            end\
            i = i + 1\
        end\
        \
        return nil\
    end\
--\
--\
-- C A L L B A C K   H A N D L E R \
--\
--\
\
    -- installing callbacks\
    -- based on mist, with optional additional hooks for pre- and post-\
    -- processing of the event\
    -- when filtering occurs in pre, an alternative 'rejected' handler can be called \
    function dcsCommon.addEventHandler(f, pre, post, rejected) -- returns ID \
        local handler = {} -- build a wrapper and connect the onEvent\
        --dcsCommon.cbID = dcsCommon.cbID + 1 -- increment unique count\
        handler.id = dcsCommon.uuid(\"eventHandler\")\
        handler.f = f -- the callback itself\
        if (rejected) then handler.rejected = rejected end\
        -- now set up pre- and post-processors. defaults are set in place\
        -- so pre and post are optional. If pre returns false, the callback will\
        -- not be invoked\
        if (pre) then handler.pre = pre else handler.pre = dcsCommon.preCall end\
        if (post) then handler.post = post else handler.post = dcsCommon.postCall end\
        function handler:onEvent(event)\
            if not self.pre(event) then \
                if dcsCommon.verbose then\
--                    trigger.action.outText(\"event \" .. event.id .. \" discarded by pre-processor\", 10)\
                end\
                if (self.rejected) then self.rejected(event) end \
                return\
            end\
            self.f(event) -- call the handler\
            self.post(event) -- do post-processing\
        end\
        world.addEventHandler(handler)\
        return handler.id\
    end\
\
    function dcsCommon.preCall(e)\
        -- we can filter here\
        -- if we return false, the call is abortet\
        if dcsCommon.verbose then\
            trigger.action.outText(\"event \" .. e.id .. \" received: PRE-PROCESSING\", 10)\
        end\
        return true;\
    end;\
\
    function dcsCommon.postCall(e)\
        -- we do pos proccing here \
        if dcsCommon.verbose then\
            trigger.action.outText(\"event \" .. e.id .. \" received: post proc\", 10)\
        end\
    end\
    \
    -- highly specific eventhandler for one event only\
    -- based on above, with direct filtering built in; skips pre\
    -- but does post\
    function dcsCommon.addEventHandlerForEventTypes(f, evTypes, post, rejected) -- returns ID \
        local handler = {} -- build a wrapper and connect the onEvent\
        dcsCommon.cbID = dcsCommon.cbID + 1 -- increment unique count\
        handler.id = dcsCommon.cbID\
        handler.what = evTypes\
        if (rejected) then handler.rejected = rejected end \
        \
        handler.f = f -- set the callback itself\
        -- now set up post-processor. pre is hard-coded to match evType\
        -- post is optional. If event.id is not in evTypes, the callback will\
        -- not be invoked\
        if (post) then handler.post = post else handler.post = dcsCommon.postCall end\
        function handler:onEvent(event)\
            hasMatch = false;\
            for key, evType in pairs(self.what) do\
                if evType == event.id then\
                    hasMatch = true;\
                    break;\
                end;\
            end;\
            if not hasMatch then \
                if dcsCommon.verbose then\
                    trigger.action.outText(\"event \" .. e.id .. \" discarded - not in whitelist evTypes\", 10)\
                end\
                if (self.rejected) then self.rejected(event) end \
                return;\
            end;\
            \
            self.f(event) -- call the actual handler as passed to us\
            self.post(event) -- do post-processing \
        end\
        world.addEventHandler(handler) -- add to event handlers\
        return handler.id\
    end\
    \
    \
    \
    -- remove event handler / callback, identical to Mist \
    -- note we don't call world.removeEventHandler, but rather directly \
    -- access world.eventHandlers directly and remove kvp directly.\
    function dcsCommon.removeEventHandler(id)\
        for key, handler in pairs(world.eventHandlers) do\
            if handler.id and handler.id == id then\
                world.eventHandlers[key] = nil\
                return true\
            end\
        end\
        return false\
    end\
\
--\
--\
-- C L O N I N G \
--\
--\
    -- topClone is a shallow clone of orig, only top level is iterated,\
    -- all values are ref-copied\
    function dcsCommon.topClone(orig)\
        local orig_type = type(orig)\
        local copy\
        if orig_type == 'table' then\
            copy = {}\
            for orig_key, orig_value in pairs(orig) do\
                copy[orig_key] = orig_value\
            end\
        else -- number, string, boolean, etc\
            copy = orig\
        end\
        return copy\
    end\
\
    -- clone is a recursive clone which will also clone\
    -- deeper levels, as used in units \
    function dcsCommon.clone(orig)\
        local orig_type = type(orig)\
        local copy\
        if orig_type == 'table' then\
            copy = {}\
            for orig_key, orig_value in next, orig, nil do\
                copy[dcsCommon.clone(orig_key)] = dcsCommon.clone(orig_value)\
            end\
            setmetatable(copy, dcsCommon.clone(getmetatable(orig)))\
        else -- number, string, boolean, etc\
            copy = orig\
        end\
        return copy\
    end\
\
    function dcsCommon.copyArray(inArray)\
        -- warning: this is a ref copy!\
        local theCopy = {}\
        for idx, element in pairs(inArray) do \
            table.insert(theCopy, element)\
        end\
        return theCopy \
    end\
--\
-- \
-- S P A W N I N G \
-- \
-- \
\
    function dcsCommon.createEmptyGroundGroupData (name)\
        local theGroup = {} -- empty group\
        theGroup.visible = false\
        theGroup.taskSelected = true\
        -- theGroup.route = {}\
        -- theGroup.groupId = id\
        theGroup.tasks = {}\
        -- theGroup.hidden = false -- hidden on f10?\
\
        theGroup.units = { } -- insert units here! -- use addUnitToGroupData\
\
        theGroup.x = 0\
        theGroup.y = 0\
        theGroup.name = name\
        -- theGroup.start_time = 0\
        theGroup.task = \"Ground Nothing\"\
        \
        return theGroup\
    end;\
\
    function dcsCommon.createEmptyAircraftGroupData (name)\
        local theGroup = dcsCommon.createEmptyGroundGroupData(name)--{} -- empty group\
\
        theGroup.task = \"Nothing\" -- can be others, like Transport, CAS, etc\
        -- returns with empty route\
        theGroup.route = dcsCommon.createEmptyAircraftRouteData() -- we can add points here \
        return theGroup\
    end;\
\
    function dcsCommon.createAircraftRoutePointData(x, z, altitudeInFeet, knots, altType, action)\
        local rp = {}\
        rp.x = x\
        rp.y = z\
        rp.action = \"Turning Point\"\
        rp.type = \"Turning Point\"\
        if action then rp.action = action; rp.type = action end -- warning: may not be correct, need to verify later\
        rp.alt = altitudeInFeet * 0.3048\
        rp.speed = knots * 0.514444 -- we use \
        rp.alt_type = \"BARO\"\
        if (altType) then rp.alt_type = altType end \
        return rp\
    end\
\
    function dcsCommon.addRoutePointDataToRouteData(inRoute, x, z, altitudeInFeet, knots, altType, action)\
        local p = dcsCommon.createAircraftRoutePointData(x, z, altitudeInFeet, knots, altType, action)\
        local thePoints = inRoute.points \
        table.insert(thePoints, p)\
    end\
    \
    function dcsCommon.addRoutePointDataToGroupData(group, x, z, altitudeInFeet, knots, altType, action)\
        if not group.route then group.route = dcsCommon.createEmptyAircraftRouteData() end\
        local theRoute = group.route \
        dcsCommon.addRoutePointDataToRouteData(theRoute, x, z, altitudeInFeet, knots, altType, action)\
    end\
\
    function dcsCommon.addRoutePointForGroupData(theGroup, theRP)\
        if not theGroup then return end \
        if not theGroup.route then theGroup.route = dcsCommon.createEmptyAircraftRouteData() end\
        \
        local theRoute = theGroup.route \
        local thePoints = theRoute.points \
        table.insert(thePoints, theRP)\
    end\
    \
    function dcsCommon.createEmptyAircraftRouteData()\
        local route = {}\
        route.points = {}\
        return route\
    end\
\
    function dcsCommon.createTakeOffFromParkingRoutePointData(aerodrome)\
        if not aerodrome then return nil end \
            \
        local rp = {}    \
        local freeParkingSlot = dcsCommon.getFirstFreeParkingSlot(aerodrome, 104) -- get big slot first \
        if not freeParkingSlot then \
            freeParkingSlot = dcsCommon.getFirstFreeParkingSlot(aerodrome) -- try any size\
        end\
            \
        if not freeParkingSlot then \
            trigger.action.outText(\"civA: no free parking at \" .. aerodrome:getName(), 30)\
            return nil \
        end\
            \
        local p = freeParkingSlot.vTerminalPos\
            \
        rp.airdromeId = aerodrome:getID() \
        rp.x = p.x\
        rp.y = p.z\
        rp.alt = p.y \
        rp.action = \"From Parking Area\"\
        rp.type = \"TakeOffParking\"\
            \
        rp.speed = 100; -- in m/s? If so, that's 360 km/h \
        rp.alt_type = \"BARO\"\
        return rp\
    end\
\
    function dcsCommon.createOverheadAirdromeRoutPintData(aerodrome)\
        if not aerodrome then return nil end \
        local rp = {}            \
        local p = aerodrome:getPoint()\
        rp.x = p.x\
        rp.y = p.z\
        rp.alt = p.y + 2000 -- 6000 ft overhead\
        rp.action = \"Turning Point\"\
        rp.type = \"Turning Point\"\
            \
        rp.speed = 133; -- in m/s? If so, that's 360 km/h \
        rp.alt_type = \"BARO\"\
        return rp\
    end\
    \
\
    function dcsCommon.createLandAtAerodromeRoutePointData(aerodrome)\
        if not aerodrome then return nil end \
            \
        local rp = {}            \
        local p = aerodrome:getPoint()\
        rp.airdromeId = aerodrome:getID() \
        rp.x = p.x\
        rp.y = p.z\
        rp.alt = p.y \
        rp.action = \"Landing\"\
        rp.type = \"Land\"\
            \
        rp.speed = 100; -- in m/s? If so, that's 360 km/h \
        rp.alt_type = \"BARO\"\
        return rp\
    end\
\
    \
    function dcsCommon.createRPFormationData(findex) -- must be added as \"task\" to an RP. use 4 for Echelon right\
        local task = {}\
        task.id = \"ComboTask\"\
        local params = {}\
        task.params = params\
        local tasks = {}\
        params.tasks = tasks\
        local t1 = {}\
        tasks[1] = t1\
        t1.number = 1\
        t1.auto = false \
        t1.id = \"WrappedAction\"\
        t1.enabled = true\
        local t1p = {}\
        t1.params = t1p\
        local action = {}\
        t1p.action = action \
        action.id = \"Option\"\
        local ap = {}\
        action.params = ap\
        ap.variantIndex = 3\
        ap.name = 5 -- AI.Option.Air.ID 5 = Formation \
        ap.formationIndex = findex -- 4 is echelon_right\
        ap.value = 262147\
        \
        return task \
    end\
\
    function dcsCommon.addTaskDataToRP(theTask, theGroup, rpIndex)\
        local theRoute = theGroup.route\
        local thePoints = theRoute.points\
        local rp = thePoints[rpIndex]\
        rp.task = theTask\
    end\
    \
    -- create a minimal payload table that is compatible with creating \
    -- a unit. you may need to alter this before adding the unit to\
    -- the mission. all params optional \
    function dcsCommon.createPayload(fuel, flare, chaff, gun) \
        local payload = {}\
        payload.pylons = {}\
        if not fuel then fuel = 1000 end -- in kg. check against fuelMassMax in type desc\
        if not flare then flare = 0 end\
        if not chaff then chaff = 0 end\
        if not gun then gun = 0 end\
        return payload \
        \
    end\
\
    function dcsCommon.createCallsign(cs) \
        local callsign = {}\
        callsign[1] = 1\
        callsign[2] = 1\
        callsign[3] = 1\
        if not cs then cs = \"Enfield11\" end\
        callsign.name = cs\
        return callsign\
    end\
    \
\
    -- create the data table required to spawn a unit.\
    -- unit types are defined in https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB\
    function dcsCommon.createGroundUnitData(name, unitType, transportable)\
        local theUnit = {}\
        unitType = dcsCommon.trim(unitType)\
        theUnit.type = unitType -- e.g. \"LAV-25\",\
        if not transportable then transportable = false end -- elaborate, not requried code\
        theUnit.transportable = {[\"randomTransportable\"] = transportable} \
        -- theUnit.unitId = id \
        theUnit.skill = \"Average\" -- always average \
        theUnit.x = 0 -- make it zero, zero!\
        theUnit.y = 0\
        theUnit.name = name\
        theUnit.playerCanDrive = false\
        theUnit.heading = 0\
        return theUnit\
    end \
\
    function dcsCommon.createAircraftUnitData(name, unitType, transportable, altitude, speed, heading)\
        local theAirUnit = dcsCommon.createGroundUnitData(name, unitType, transportable)\
        theAirUnit.alt = 100 -- make it 100m\
        if altitude then theAirUnit.alt = altitude end \
        theAirUnit.alt_type = \"RADIO\" -- AGL\
        theAirUnit.speed = 77 -- m/s --> 150 knots\
        if speed then theAirUnit.speed = speed end \
        if heading then theAirUnit.heading = heading end \
        theAirUnit.payload = dcsCommon.createPayload()\
        theAirUnit.callsign = dcsCommon.createCallsign()\
        return theAirUnit\
    end\
    \
\
    function dcsCommon.addUnitToGroupData(theUnit, theGroup, dx, dy, heading)\
        -- add a unit to a group, and place it at dx, dy of group's position,\
        -- taking into account unit's own current location\
        if not dx then dx = 0 end\
        if not dy then dy = 0 end\
        if not heading then heading = 0 end\
        theUnit.x = theUnit.x + dx + theGroup.x\
        theUnit.y = theUnit.y + dy + theGroup.y \
        theUnit.heading = heading\
        table.insert(theGroup.units, theUnit)\
    end;\
\
    function dcsCommon.createSingleUnitGroup(name, theUnitType, x, z, heading) \
        -- create the container \
        local theNewGroup = dcsCommon.createEmptyGroundGroupData(name)\
        local aUnit = {}\
        aUnit = dcsCommon.createGroundUnitData(name .. \"-1\", theUnitType, false)\
--        trigger.action.outText(\"dcsCommon - unit name retval \" .. aUnit.name, 30)\
        dcsCommon.addUnitToGroupData(aUnit, theNewGroup, x, z, heading)\
        return theNewGroup\
    end\
    \
\
    function dcsCommon.arrangeGroupDataIntoFormation(theNewGroup, radius, minDist, formation, innerRadius)\
        -- formations:\
        --    (default) \"line\" (left to right along x) -- that is Y direction\
        --    \"line_v\" a line top to bottom -- that is X direction\
        --    \"chevron\" - left to right middle too top\
        --    \"scattered\", \"random\" -- random, innerRadius used to clear area in center\
        --       \"circle\", \"circle_forward\" -- circle, forward facing\
        --    \"circle_in\" -- circle, inwarf facing\
        --    \"circle_out\" -- circle, outward facing\
        --    \"grid\", \"square\", \"rect\" -- optimal rectangle\
        --    \"2cols\", \"2deep\" -- 2 columns, n deep \
        --    \"2wide\" -- 2 columns wide, 2 deep \
\
        local num = #theNewGroup.units \
        \
        -- now do the formation stuff\
        -- make sure that they keep minimum  distance \
--        trigger.action.outText(\"dcsCommon - processing formation \" .. formation .. \" with radius = \" .. radius, 30)\
        if formation == \"LINE_V\" then \
            -- top to bottom in zone (heding 0). -- will run through x-coordinate \
            -- use entire radius top to bottom \
            local currX = -radius\
            local increment = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\
            for i=1, num do\
            \
                local u = theNewGroup.units[i]\
--                trigger.action.outText(\"formation unit \" .. u.name .. \" currX = \" .. currX, 30)\
                u.x = currX\
                currX = currX + increment\
            end\
        \
        elseif formation == \"LINE\" then \
            -- left to right in zone. runs through Y\
            -- left and right are y because at heading 0, forward is x (not y as expected)\
            -- if only one, place in middle of circle and be done \
            if num == 1 then \
                -- nothing. just stay in the middle \
            else \
                local currY = -radius\
                local increment = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\
                for i=1, num do\
                    local u = theNewGroup.units[i]\
--                    trigger.action.outText(\"formation unit \" .. u.name .. \" currX = \" .. currY, 30)\
                    u.y = currY\
                    currY = currY + increment\
                end    \
            end \
            \
        elseif formation == \"CHEVRON\" then \
            -- left to right in zone. runs through Y\
            -- left and right are y because at heading 0, forward is x (not y as expected)\
            local currY = -radius\
            local currX = 0\
            local incrementY = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\
            local incrementX = radius * 2/(num - 1) -- MUST NOT TRY WITH 1 UNIT!\
            for i=1, num do\
                local u = theNewGroup.units[i]\
--                trigger.action.outText(\"formation unit \" .. u.name .. \" currX = \" .. currX .. \" currY = \" .. currY, 30)\
                u.x = currX\
                u.y = currY\
                -- calc coords for NEXT iteration\
                currY = currY + incrementY -- march left to right\
                if i < num / 2 then -- march up\
                    currX = currX + incrementX \
                elseif i == num / 2 then -- even number, keep height\
                    currX = currX + 0 \
                else \
                    currX = currX - incrementX -- march down \
                end \
                -- note: when unit number even, the wedge is sloped. may need an odd/even test for better looks\
            end    \
\
        elseif formation == \"SCATTERED\" or formation == \"RANDOM\" then \
            -- use randomPointInCircle and tehn iterate over all vehicles for mindelta\
            processedUnits = {}\
            for i=1, num do\
                local emergencyBreak = 1 -- prevent endless loop\
                local lowDist = 10000\
                local uPoint = {}\
                local thePoint = {}\
                repeat     -- get random point intil mindistance to all is kept or emergencybreak\
                    for idx, rUnit in pairs(processedUnits) do -- get min dist to all positioned units\
                        thePoint = dcsCommon.randomPointInCircle(radius, innerRadius) -- returns x, 0, z\
                        uPoint.x = rUnit.x\
                        uPoint.y = 0\
                        uPoint.z = rUnit.y \
                        local dist = dcsCommon.dist(thePoint, uPoint) -- measure distance to unit\
                        if (dist < lowDist) then lowDist = dist end\
                    end\
                    emergencyBreak = emergencyBreak + 1\
                until (emergencyBreak > 20) or (lowDist > minDist)\
                -- we have random x, y \
                local u = theNewGroup.units[i] -- get unit to position\
                u.x = thePoint.x\
                u.y = thePoint.z -- z --> y mapping! \
                -- now add the unit to the 'processed' set \
                table.insert(processedUnits, u)\
            end    \
\
        elseif dcsCommon.stringStartsWith(formation, \"CIRCLE\") then\
            -- units are arranged on perimeter of circle defined by radius \
--            trigger.action.outText(\"formation circle detected\", 30)\
            local currAngle = 0\
            local angleInc = 2 * 3.14157 / num -- increase per spoke \
            for i=1, num do\
                local u = theNewGroup.units[i] -- get unit \
                u.x = radius * math.cos(currAngle)\
                u.y = radius * math.sin(currAngle)\
                \
                -- now baldower out heading \
                -- circle, circle_forward no modifier of heading\
                if dcsCommon.stringStartsWith(formation, \"CIRCLE_IN\") then \
                    -- make the heading inward faceing - that's angle + pi\
                    u.heading = u.heading + currAngle + 3.14157\
                elseif dcsCommon.stringStartsWith(formation, \"CIRCLE_OUT\") then \
                    u.heading = u.heading + currAngle + 0\
                end\
\
                currAngle = currAngle + angleInc\
            end\
        elseif formation == \"GRID\" or formation == \"SQUARE\" or formation == \"RECT\" then \
            if num < 2 then return end \
            -- arrange units in an w x h grid\
            -- e-g- 12 units = 4 x 3. \
            -- calculate w \
            local w = math.floor(num^(0.5) + 0.5)\
            dcsCommon.arrangeGroupInNColumns(theNewGroup, w, radius)\
            --[[--\
            local h = math.floor(num / w)\
            --trigger.action.outText(\"AdcsC: num=\" .. num .. \" w=\" .. w .. \"h=\" .. h .. \" -- num%w=\" .. num%w, 30)\
            if (num % w) > 0 then \
                h = h + 1\
            end\
            \
            --trigger.action.outText(\"BdcsC: num=\" .. num .. \" w=\" .. w .. \"h=\" .. h, 30)\
            \
            -- now w * h always >= num and num items fir in that grid\
            -- w is width, h is height, of course :) \
            -- now calculat xInc and yInc\
            local i = 1\
            local xInc = 0 \
            if w > 1 then xInc = 2 * radius / (w-1) end\
            local yInc = 0\
            if h > 1 then yInc = 2 * radius / (h-1) end \
            local currY = radius \
            if h < 2 then currY = 0 end -- special:_ place in Y middle if only one row)\
            while h > 0 do \
                local currX = radius \
                local wCnt = w \
                while wCnt > 0 and (i <= num) do \
                    local u = theNewGroup.units[i] -- get unit \
                    u.x = currX\
                    u.y = currY\
                    currX = currX - xInc\
                    wCnt = wCnt - 1\
                    i = i + 1\
                end\
                currY = currY - yInc \
                h = h - 1\
            end\
            --]]--\
        elseif formation == \"2DEEP\" or formation == \"2COLS\" then\
            if num < 2 then return end \
            -- arrange units in an 2 x h grid\
            local w = 2\
            dcsCommon.arrangeGroupInNColumnsDeep(theNewGroup, w, radius)\
\
        elseif formation == \"2WIDE\" then\
            if num < 2 then return end \
            -- arrange units in an 2 x h grid\
            local w = 2\
            dcsCommon.arrangeGroupInNColumns(theNewGroup, w, radius)\
        else \
            trigger.action.outText(\"dcsCommon - unknown formation: \" .. formation, 30)\
        end\
    \
    end\
    \
    function dcsCommon.arrangeGroupInNColumns(theNewGroup, w, radius)\
        local num = #theNewGroup.units\
        local h = math.floor(num / w)\
        if (num % w) > 0 then \
            h = h + 1\
        end\
        local i = 1\
        local xInc = 0 \
        if w > 1 then xInc = 2 * radius / (w-1) end\
        local yInc = 0\
        if h > 1 then yInc = 2 * radius / (h-1) end \
        local currY = radius \
        if h < 2 then currY = 0 end -- special:_ place in Y middle if only one row)\
        while h > 0 do \
            local currX = radius \
            local wCnt = w \
            while wCnt > 0 and (i <= num) do \
                local u = theNewGroup.units[i] -- get unit \
                u.x = currX\
                u.y = currY\
                currX = currX - xInc\
                wCnt = wCnt - 1\
                i = i + 1\
            end\
            currY = currY - yInc \
            h = h - 1\
        end\
    end\
    \
    function dcsCommon.arrangeGroupInNColumnsDeep(theNewGroup, w, radius)\
        local num = #theNewGroup.units\
        local h = math.floor(num / w)\
        if (num % w) > 0 then \
            h = h + 1\
        end\
        local i = 1\
        local yInc = 0 \
        if w > 1 then yInc = 2 * radius / (w-1) end\
        local xInc = 0\
        if h > 1 then xInc = 2 * radius / (h-1) end \
        local currX = radius \
        if h < 2 then currX = 0 end -- special:_ place in Y middle if only one row)\
        while h > 0 do \
            local currY = radius \
            local wCnt = w \
            while wCnt > 0 and (i <= num) do \
                local u = theNewGroup.units[i] -- get unit \
                u.x = currX\
                u.y = currY\
                currY = currY - yInc\
                wCnt = wCnt - 1\
                i = i + 1\
            end\
            currX = currX - xInc \
            h = h - 1\
        end\
    end\
    \
    \
    function dcsCommon.createGroundGroupWithUnits(name, theUnitTypes, radius, minDist, formation, innerRadius)\
        if not minDist then mindist = 4 end -- meters\
        if not formation then formation = \"line\" end \
        if not radius then radius = 30 end -- meters \
        if not innerRadius then innerRadius = 0 end\
        formation = formation:upper()\
        -- theUnitTypes can be either a single string or a table of strings\
        -- see here for TypeName https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB\
        -- formation defines how the units are going to be arranged in the\
        -- formation specified. \
        -- formations:\
        --    (default) \"line\" (left to right along x) -- that is Y direction\
        --    \"line_V\" a line top to bottom -- that is X direction\
        --    \"chevron\" - left to right middle too top\
        --    \"scattered\", \"random\" -- random, innerRadius used to clear area in center\
        --       \"circle\", \"circle_forward\" -- circle, forward facing\
        --    \"circle_in\" -- circle, inwarf facing\
        --    \"circle_out\" -- circle, outward facing\
\
        -- first, we create a group\
        local theNewGroup = dcsCommon.createEmptyGroundGroupData(name)\
        \
        -- now add a single unit or multiple units\
        if type(theUnitTypes) ~= \"table\" then \
--            trigger.action.outText(\"dcsCommon - i am here\", 30)\
--            trigger.action.outText(\"dcsCommon - name \" .. name, 30)\
--            trigger.action.outText(\"dcsCommon - unit type \" .. theUnitTypes, 30)\
            \
            local aUnit = {}\
            aUnit = dcsCommon.createGroundUnitData(name .. \"-1\", theUnitTypes, false)\
--            trigger.action.outText(\"dcsCommon - unit name retval \" .. aUnit.name, 30)\
            dcsCommon.addUnitToGroupData(aUnit, theNewGroup, 0, 0) -- create with data at location (0,0)\
            return theNewGroup\
        end \
\
        -- if we get here, theUnitTypes is a table\
        -- now loop and create a unit for each table\
        local num = 1\
        for key, theType in pairs(theUnitTypes) do \
            -- trigger.action.outText(\"+++dcsC: creating unit \" .. name .. \"-\" .. num .. \": \" .. theType, 30)\
            local aUnit = dcsCommon.createGroundUnitData(name .. \"-\"..num, theType, false)\
            dcsCommon.addUnitToGroupData(aUnit, theNewGroup, 0, 0)\
            num = num + 1\
        end\
        \
        dcsCommon.arrangeGroupDataIntoFormation(theNewGroup, radius, minDist, formation, innerRadius)\
        return theNewGroup\
\
    \
    end\
\
-- create a new group, based on group in mission. Groups coords are 0,0 for group and all\
-- x,y and heading\
    function dcsCommon.createGroupDataFromLiveGroup(name, newName) \
        if not newName then newName = dcsCommon.uuid(\"uniqName\") end\
        -- get access to the group\
        local liveGroup = Group.getByName(name)\
        if not liveGroup then return nil end\
        -- get the categorty\
        local cat = liveGroup:getCategory()\
        local theNewGroup = {}\
        \
        -- create a new empty group at (0,0) \
        if cat == Group.Category.AIRPLANE or cat == Group.Category.HELICOPTER then \
            theNewGroup = dcsCommon.createEmptyAircraftGroupData(newName)\
        elseif cat == Group.Category.GROUND then\
            theNewGroup = dcsCommon.createEmptyGroudGroupData(newName)\
        else \
            trigger.action.outText(\"dcsCommon - unknown category: \" .. cat, 30)\
            return nil\
        end\
        \
\
        -- now get all units from live group and create data units\
        -- note that unit data for group has x=0, y=0\
        liveUnits = liveGroup:getUnits()\
        \
        for index, theUnit in pairs(liveUnits) do \
            -- for each unit we get the desc \
            local desc = theUnit:getDesc() -- of interest is only typename \
            local newUnit = dcsCommon.createGroundUnitData(dcsCommon.uuid(newName),\
                                                           desc.typeName,\
                                                           false)\
            -- we now basically have a ground unit at (0,0) \
            -- add mandatory fields by type\
            if cat == Group.Category.AIRPLANE or cat == Group.Category.HELICOPTER then \
                newUnit.alt = 100 -- make it 100m\
                newUnit.alt_type = \"RADIO\" -- AGL\
                newUnit.speed = 77 -- m/s --> 150 knots\
                newUnit.payload = dcsCommon.createPayload() -- empty payload\
                newUnit.callsign = dcsCommon.createCallsign() -- 'enfield11'\
                \
            elseif cat == Group.Category.GROUND then\
                -- we got all we need\
            else \
                -- trigger.action.outText(\"dcsCommon - unknown category: \" .. cat, 30)\
                -- return nil\
                -- we also got all we need\
            end            \
            \
        end\
    \
    end;\
    \
\
    function dcsCommon.rotatePointAroundOrigin(inX, inY, angle) -- angle in degrees\
        local degrees =  3.14152 / 180 -- ok, it's actually radiants. \
        angle = angle * degrees -- turns into rads\
        local c = math.cos(angle)\
        local s = math.sin(angle)\
        local px\
        local py \
        px = inX * c - inY * s\
        py = inX * s + inY * c\
        return px, py        \
    end\
\
    function dcsCommon.rotateUnitData(theUnit, degrees, cx, cy)\
        if not cx then cx = 0 end\
        if not cz then cz = 0 end\
        local cy = cz \
        --trigger.action.outText(\"+++dcsC:rotGrp cy,cy = \"..cx .. \",\" .. cy, 30)\
        \
        local rads = degrees *  3.14152 / 180\
        do\
            theUnit.x = theUnit.x - cx -- MOVE TO ORIGIN OF ROTATION\
            theUnit.y = theUnit.y - cy                 \
            theUnit.x, theUnit.y = dcsCommon.rotatePointAroundOrigin(theUnit.x, theUnit.y, degrees)\
            theUnit.x = theUnit.x + cx -- MOVE BACK \
            theUnit.y = theUnit.y + cy                 \
\
            -- may also want to increase heading by degreess\
            theUnit.heading = theUnit.heading + rads \
        end\
    end\
    \
\
    function dcsCommon.rotateGroupData(theGroup, degrees, cx, cz)\
        if not cx then cx = 0 end\
        if not cz then cz = 0 end\
        local cy = cz \
        --trigger.action.outText(\"+++dcsC:rotGrp cy,cy = \"..cx .. \",\" .. cy, 30)\
        \
        local rads = degrees *  3.14152 / 180\
        -- turns all units in group around the group's center by degrees.\
        -- may also need to turn individual units by same amount\
        for i, theUnit in pairs (theGroup.units) do\
            theUnit.x = theUnit.x - cx -- MOVE TO ORIGIN OF ROTATION\
            theUnit.y = theUnit.y - cy                 \
            theUnit.x, theUnit.y = dcsCommon.rotatePointAroundOrigin(theUnit.x, theUnit.y, degrees)\
            theUnit.x = theUnit.x + cx -- MOVE BACK \
            theUnit.y = theUnit.y + cy                 \
\
            -- may also want to increase heading by degreess\
            theUnit.heading = theUnit.heading + rads \
        end\
    end\
\
    function dcsCommon.offsetGroupData(theGroup, dx, dy)\
        -- add dx and dy to group's and all unit's coords\
        for i, theUnit in pairs (theGroup.units) do \
            theUnit.x = theUnit.x + dx\
            theUnit.y = theUnit.y + dy\
        end\
        \
        theGroup.x = theGroup.x + dx\
        theGroup.y = theGroup.y + dy \
    end\
    \
    function dcsCommon.moveGroupDataTo(theGroup, xAbs, yAbs)\
        local dx = xAbs-theGroup.x\
        local dy = yAbs-theGroup.y\
        dcsCommon.offsetGroupData(theGroup, dx, dy)\
    end\
    \
    -- static objectr shapes and types are defined here\
    -- https://github.com/mrSkortch/DCS-miscScripts/tree/master/ObjectDB/Statics\
    \
    function dcsCommon.createStaticObjectData(name, objType, heading, dead, cargo, mass)\
        local staticObj = {}\
        if not heading then heading = 0 end \
        if not dead then dead = false end \
        if not cargo then cargo = false end \
        objType = dcsCommon.trim(objType) \
        \
        staticObj.heading = heading\
        -- staticObj.groupId = 0\
        -- staticObj.shape_name = shape -- e.g. H-Windsock_RW\
        staticObj.type = objType  -- e.g. Windsock\
        -- [\"unitId\"] = 3,\
        staticObj.rate = 1 -- score when killed\
        staticObj.name = name\
        -- staticObj.category = \"Fortifications\",\
        staticObj.y = 0\
        staticObj.x = 0\
        staticObj.dead = dead\
        staticObj.canCargo = cargo -- to cargo\
        if cargo then \
            if not mass then mass = 1234 end \
            staticObj.mass = mass -- to cargo\
        end\
        return staticObj\
    end\
    \
    function dcsCommon.createStaticObjectDataAt(loc, name, objType, heading, dead)\
        local theData = dcsCommon.createStaticObjectData(name, objType, heading, dead)\
        theData.x = loc.x\
        theData.y = loc.z \
        return theData\
    end\
    \
    function dcsCommon.createStaticObjectForCoalitionAtLocation(theCoalition, loc, name, objType, heading, dead) \
        if not heading then heading = math.random(360) * 3.1415 / 180 end\
        local theData = dcsCommon.createStaticObjectDataAt(loc, name, objType, heading, dead)\
        local theStatic = coalition.addStaticObject(theCoalition, theData)\
        return theStatic\
    end\
    \
    function dcsCommon.createStaticObjectForCoalitionInRandomRing(theCoalition, objType, x, z, innerRadius, outerRadius, heading, alive) \
        if not outerRadius then outerRadius = innerRadius end\
        if not heading then heading = math.random(360) * 3.1415 / 180 end\
        local dead = not alive\
        local p = dcsCommon.randomPointInCircle(outerRadius, innerRadius, x, z)\
        local theData = dcsCommon.createStaticObjectData(dcsCommon.uuid(\"static\"), objType, heading, dead)\
        theData.x = p.x\
        theData.y = p.z \
        \
        local theStatic = coalition.addStaticObject(theCoalition, theData)\
        return theStatic\
    end\
    \
    \
    \
    function dcsCommon.linkStaticDataToUnit(theStatic, theUnit, dx, dy, heading)\
        if not theStatic then \
            trigger.action.OutText(\"+++dcsC: NIL theStatic on linkStatic!\", 30)\
            return \
        end\
        -- NOTE: we may get current heading and subtract/add \
        -- to original heading \
        local rotX, rotY = dcsCommon.rotatePointAroundOrigin(dx, dy, -heading)\
        \
        if not theUnit then return end\
        if not theUnit:isExist() then return end \
        theStatic.linkOffset = true \
        theStatic.linkUnit = theUnit:getID()\
        local unitPos = theUnit:getPoint()\
        local offsets = {}\
        offsets.x = rotX  \
        offsets.y = rotY \
        offsets.angle = 0\
        theStatic.offsets = offsets\
    end\
    \
    function dcsCommon.offsetStaticData(theStatic, dx, dy)\
        theStatic.x = theStatic.x + dx\
        theStatic.y = theStatic.y + dy\
        -- now check if thre is a route (for linked objects)\
        if theStatic.route then \
            -- access points[1] x and y and copy from main\
            theStatic.route.points[1].x = theStatic.x\
            theStatic.route.points[1].y = theStatic.y\
        end\
    end\
    \
    function dcsCommon.moveStaticDataTo(theStatic, x, y)\
        theStatic.x = x\
        theStatic.y = y\
        -- now check if thre is a route (for linked objects)\
        if theStatic.route then \
            -- access points[1] x and y and copy from main\
            theStatic.route.points[1].x = theStatic.x\
            theStatic.route.points[1].y = theStatic.y\
        end\
\
    end\
    \
--\
--\
-- M I S C   M E T H O D S \
--\
--\
\
    function dcsCommon.arrayContainsString(theArray, theString) \
        if not theArray then return false end\
        if not theString then return false end\
        for i = 1, #theArray do \
            if theArray[i] == theString then return true end \
        end\
        return false \
    end\
    \
    function dcsCommon.splitString(inputstr, sep) \
        if sep == nil then\
            sep = \"%s\"\
        end\
        if inputstr == nil then \
            inputstr = \"\"\
        end\
        \
        local t={}\
        for str in string.gmatch(inputstr, \"([^\"..sep..\"]+)\") do\
            table.insert(t, str)\
        end\
        return t\
    \
    end\
    \
    function dcsCommon.trimFront(inputstr) \
        if not inputstr then return nil end \
        local s = inputstr\
        while string.len(s) > 1 and string.sub(s, 1, 1) == \" \" do \
            local snew = string.sub(s, 2) -- all except first\
            s = snew\
        end\
        return s\
    end\
    \
    function dcsCommon.trimBack(inputstr)\
        if not inputstr then return nil end \
        local s = inputstr\
        while string.len(s) > 1 and string.sub(s, -1) == \" \" do \
            local snew = string.sub(s, 1, -2) -- all except last\
            s = snew\
        end\
        return s\
    end\
    \
    function dcsCommon.trim(inputstr) \
        local t1 = dcsCommon.trimFront(inputstr)\
        local t2 = dcsCommon.trimBack(t1)\
        return t2\
    end\
    \
    function dcsCommon.trimArray(theArray)\
        local trimmedArray = {}\
        for idx, element in pairs(theArray) do \
            local tel = dcsCommon.trim(element)\
            table.insert(trimmedArray, tel)\
        end\
        return trimmedArray\
    end\
    \
    function dcsCommon.stringIsPositiveNumber(theString)\
        -- only full integer positive numbers supported \
        if not theString then return false end \
--        if theString == \"\" then return false end \
        for i = 1, #theString do \
            local c = theString:sub(i,i)\
            if c < \"0\" or c > \"9\" then return false end \
        end\
        return true \
    end\
    \
    function dcsCommon.stringStartsWithDigit(theString)\
        if #theString < 1 then return false end \
        local c = string.sub(theString, 1, 1) \
        return c >= \"0\" and c <= \"9\" \
    end\
    \
    function dcsCommon.stringStartsWithLetter(theString)\
        if #theString < 1 then return false end \
        local c = string.sub(theString, 1, 1)\
        if c >= \"a\" and c <= \"z\" then return true end  \
        if c >= \"A\" and c <= \"Z\" then return true end \
        return false \
    end\
    \
    function dcsCommon.stringStartsWith(theString, thePrefix)\
        return theString:find(thePrefix) == 1\
    end\
    \
    function dcsCommon.removePrefix(theString, thePrefix)\
        if not dcsCommon.stringStartsWith(theString, thePrefix) then \
            return theString\
        end;\
        return theString:sub(1 + #thePrefix)\
    end\
    \
    function dcsCommon.stringEndsWith(theString, theEnding)\
        return theEnding == \"\" or theString:sub(-#theEnding) == theEnding\
    end\
    \
    function dcsCommon.removeEnding(theString, theEnding) \
        if not dcsCommon.stringEndsWith(theString, theEnding) then \
            return theString\
        end\
        return theString:sub(1, #theString - #theEnding)\
    end\
    \
    function dcsCommon.containsString(inString, what, caseSensitive)\
        if (not caseSensitive) then \
            inString = string.upper(inString)\
            what = string.upper(what)\
        end\
        if inString == what then return true end -- when entire match \
        return string.find(inString, what)\
    end\
    \
    function dcsCommon.bool2Text(theBool) \
        if not theBool then theBool = false end \
        if theBool then return \"true\" end \
        return \"false\"\
    end\
    \
    function dcsCommon.bool2YesNo(theBool)\
        if not theBool then theBool = false end \
        if theBool then return \"yes\" end \
        return \"no\"\
    end\
\
    -- recursively show the contents of a variable\
    function dcsCommon.dumpVar(key, value, prefix, inrecursion)\
        if not inrecursion then \
            -- output a marker to find in the log / screen\
            env.info(\"*** dcsCommon vardump START\")\
        end\
        if not value then value = \"nil\" end\
        if not prefix then prefix = \"\" end\
        prefix = \" \" .. prefix\
        if type(value) == \"table\" then \
            env.info(prefix .. key .. \": [ \")\
            -- iterate through all kvp\
            for k,v in pairs (value) do\
                dcsCommon.dumpVar(k, v, prefix, true)\
            end\
            env.info(prefix .. \" ] - end \" .. key)\
            \
        elseif type(value) == \"boolean\" then \
            local b = \"false\"\
            if value then b = \"true\" end\
            env.info(prefix .. key .. \": \" .. b)\
            \
        else -- simple var, show contents, ends recursion\
            env.info(prefix .. key .. \": \" .. value)\
        end\
        \
        if not inrecursion then \
            -- output a marker to find in the log / screen\
            trigger.action.outText(\"=== dcsCommon vardump END\", 30)\
            env.info(\"=== dcsCommon vardump END\")\
        end\
    end\
    \
    function dcsCommon.dumpVar2Str(key, value, prefix, inrecursion)\
        if not inrecursion then \
            -- output a marker to find in the log / screen\
            trigger.action.outText(\"*** dcsCommon vardump START\",30)\
        end\
        if not value then value = \"nil\" end\
        if not prefix then prefix = \"\" end\
        prefix = \" \" .. prefix\
        if type(value) == \"table\" then \
            trigger.action.outText(prefix .. key .. \": [ \", 30)\
            -- iterate through all kvp\
            for k,v in pairs (value) do\
                dcsCommon.dumpVar2Str(k, v, prefix, true)\
            end\
            trigger.action.outText(prefix .. \" ] - end \" .. key, 30)\
            \
        elseif type(value) == \"boolean\" then \
            local b = \"false\"\
            if value then b = \"true\" end\
            trigger.action.outText(prefix .. key .. \": \" .. b, 30)\
            \
        else -- simple var, show contents, ends recursion\
            trigger.action.outText(prefix .. key .. \": \" .. value, 30)\
        end\
        \
        if not inrecursion then \
            -- output a marker to find in the log / screen\
            trigger.action.outText(\"=== dcsCommon vardump END\", 30)\
            --env.info(\"=== dcsCommon vardump END\")\
        end\
    end\
    \
\
    dcsCommon.simpleUUID = 76543 -- a number to start. as good as any\
    function dcsCommon.numberUUID()\
        dcsCommon.simpleUUID = dcsCommon.simpleUUID + 1\
        return dcsCommon.simpleUUID\
    end\
\
    function dcsCommon.uuid(prefix)\
        dcsCommon.uuIdent = dcsCommon.uuIdent + 1\
        if not prefix then prefix = dcsCommon.uuidStr end\
        return prefix .. \"-\" .. dcsCommon.uuIdent\
    end\
    \
    function dcsCommon.event2text(id) \
        if not id then return \"error\" end\
        if id == 0 then return \"invalid\" end\
        -- translate the event id to text\
        local events = {\"shot\", \"hit\", \"takeoff\", \"land\",\
                        \"crash\", \"eject\", \"refuel\", \"dead\",\
                        \"pilot dead\", \"base captured\", \"mission start\", \"mission end\", -- 12\
                        \"took control\", \"refuel stop\", \"birth\", \"human failure\", \
                        \"det. failure\", \"engine start\", \"engine stop\", \"player enter unit\",\
                        \"player leave unit\", \"player comment\", \"start shoot\", \"end shoot\",\
                        \"mark add\", \"mark changed\", \"makr removed\", \"kill\", \
                        \"score\", \"unit lost\", \"land after eject\", \"Paratrooper land\", \
                        \"chair discard after eject\", \"weapon add\", \"trigger zone\", \"landing quality mark\",\
                        \"BDA\", \"max\"}\
        if id > #events then return \"Unknown (ID=\" .. id .. \")\" end\
        return events[id]\
    end\
\
    function dcsCommon.smokeColor2Text(smokeColor)\
        if (smokeColor == 0) then return \"Green\" end\
        if (smokeColor == 1) then return \"Red\" end\
        if (smokeColor == 2) then return \"White\" end\
        if (smokeColor == 3) then return \"Orange\" end\
        if (smokeColor == 4) then return \"Blue\" end\
        \
        return (\"unknown: \" .. smokeColor)\
    end\
    \
    function dcsCommon.smokeColor2Num(smokeColor)\
        if not smokeColor then smokeColor = \"green\" end \
        if type(smokeColor) ~= \"string\" then return 0 end \
        smokeColor = smokeColor:lower()\
        if (smokeColor == \"green\") then return 0 end \
        if (smokeColor == \"red\") then return 1 end \
        if (smokeColor == \"white\") then return 2 end \
        if (smokeColor == \"orange\") then return 3 end \
        if (smokeColor == \"blue\") then return 4 end \
        return 0\
    end\
    \
    function dcsCommon.markPointWithSmoke(p, smokeColor)\
        local x = p.x \
        local z = p.z -- do NOT change the point directly\
        -- height-correct\
        local y = land.getHeight({x = x, y = z})\
        local newPoint= {x = x, y = y + 2, z = z}\
        trigger.action.smoke(newPoint, smokeColor)\
    end\
\
--\
--\
-- V E C T O R   M A T H \
--\
--\
function dcsCommon.vAdd(a, b) \
    local r = {}\
    if not a then a = {x = 0, y = 0, z = 0} end\
    if not b then b = {x = 0, y = 0, z = 0} end\
    r.x = a.x + b.x \
    r.y = a.y + b.y \
    r.z = a.z + b.z \
    return r \
end\
\
function dcsCommon.vSub(a, b) \
    local r = {}\
    if not a then a = {x = 0, y = 0, z = 0} end\
    if not b then b = {x = 0, y = 0, z = 0} end\
    r.x = a.x - b.x \
    r.y = a.y - b.y \
    r.z = a.z - b.z \
    return r \
end\
\
function dcsCommon.vMultScalar(a, f) \
    local r = {}\
    if not a then a = {x = 0, y = 0, z = 0} end\
    if not f then f = 0 end\
    r.x = a.x * f \
    r.y = a.y * f \
    r.z = a.z * f \
    return r \
end\
\
function dcsCommon.vLerp (a, b, t)\
    if not a then a = {x = 0, y = 0, z = 0} end\
    if not b then b = {x = 0, y = 0, z = 0} end\
    \
    local d = dcsCommon.vSub(b, a)\
    local dt = dcsCommon.vMultScalar(d, t)\
    local r = dcsCommon.vAdd(a, dt)\
    return r\
end\
\
function dcsCommon.mag(x, y, z) \
    if not x then x = 0 end\
    if not y then y = 0 end \
    if not z then z = 0 end \
    \
    return (x * x + y * y + z * z)^0.5\
end\
\
function dcsCommon.vMag(a) \
    if not a then return 0 end \
    if not a.x then a.x = 0 end \
    if not a.y then a.y = 0 end \
    if not a.z then a.z = 0 end\
    return dcsCommon.mag(a.x, a.y, a.z) \
end\
\
function dcsCommon.magSquare(x, y, z) \
    if not x then x = 0 end\
    if not y then y = 0 end \
    if not z then z = 0 end \
    \
    return (x * x + y * y + z * z)\
end\
\
function dcsCommon.vNorm(a) \
    if not a then return {x = 0, y = 0, z = 0} end \
    m = dcsCommon.vMag(a)\
    if m <= 0 then return {x = 0, y = 0, z = 0} end \
    local r = {}\
    r.x = a.x / m \
    r.y = a.y / m \
    r.z = a.z / m\
    return r \
end\
\
function dcsCommon.dot (a, b) \
    if not a then a = {} end \
    if not a.x then a.x = 0 end \
    if not a.y then a.y = 0 end \
    if not a.z then a.z = 0 end\
    if not b then b = {} end \
    if not b.x then b.x = 0 end \
    if not b.y then b.y = 0 end \
    if not b.z then b.z = 0 end \
    \
    return a.x * b.x + a.y * b.y + a.z * b.z \
end\
--\
-- UNIT MISC\
-- \
function dcsCommon.isSceneryObject(theUnit)\
    if not theUnit then return false end\
    return theUnit.getCoalition == nil -- scenery objects do not return a coalition \
end\
\
function dcsCommon.isTroopCarrier(theUnit)\
    -- return true if conf can carry troups\
    if not theUnit then return false end \
    local uType = theUnit:getTypeName()\
    if dcsCommon.arrayContainsString(dcsCommon.troopCarriers, uType) then \
        -- may add additional tests before returning true\
        return true\
    end\
    return false\
end\
\
function dcsCommon.getUnitAlt(theUnit)\
    if not theUnit then return 0 end\
    if not theUnit:isExist() then return 0 end \
    local p = theUnit:getPoint()\
    return p.y \
end\
\
function dcsCommon.getUnitAGL(theUnit)\
    if not theUnit then return 0 end\
    if not theUnit:isExist() then return 0 end \
    local p = theUnit:getPoint()\
    local alt = p.y \
    local loc = {x = p.x, y = p.z}\
    local landElev = land.getHeight(loc)\
    return alt - landElev\
end \
\
function dcsCommon.getUnitSpeed(theUnit)\
    if not theUnit then return 0 end\
    if not theUnit:isExist() then return 0 end \
    local v = theUnit:getVelocity()\
    return dcsCommon.mag(v.x, v.y, v.z)\
end\
\
-- closing velocity of u1 and u2, seen from u1\
function dcsCommon.getClosingVelocity(u1, u2)\
    if not u1 then return 0 end \
    if not u2 then return 0 end \
    if not u1:isExist() then return 0 end \
    if not u2:isExist() then return 0 end \
    local v1 = u1:getVelocity()\
    local v2 = u2:getVelocity()\
    local dV = dcsCommon.vSub(v1,v2)\
    local a = u1:getPoint()\
    local b = u2:getPoint() \
    local aMinusB = dcsCommon.vSub(a,b) -- vector from u2 to u1\
    local abMag = dcsCommon.vMag(aMinusB) -- distance u1 to u2 \
    if abMag < .0001 then return 0 end \
    -- project deltaV onto vector from u2 to u1 \
    local vClose = dcsCommon.dot(dV, aMinusB) / abMag \
    return vClose \
end\
\
function dcsCommon.getGroupAvgSpeed(theGroup)\
    if not theGroup then return 0 end \
    if not dcsCommon.isGroupAlive(theGroup) then return 0 end \
    local totalSpeed = 0\
    local cnt = 0 \
    local livingUnits = theGroup:getUnits()\
    for idx, theUnit in pairs(livingUnits) do \
        cnt = cnt + 1\
        totalSpeed = totalSpeed + dcsCommon.getUnitSpeed(theUnit)\
    end \
    if cnt == 0 then return 0 end \
    return totalSpeed / cnt \
end\
 \
function dcsCommon.getGroupMaxSpeed(theGroup)\
    if not theGroup then return 0 end \
    if not dcsCommon.isGroupAlive(theGroup) then return 0 end \
    local maxSpeed = 0\
    local livingUnits = theGroup:getUnits()\
    for idx, theUnit in pairs(livingUnits) do \
        currSpeed = dcsCommon.getUnitSpeed(theUnit)\
        if currSpeed > maxSpeed then maxSpeed = currSpeed end \
    end \
    return maxSpeed\
end \
\
function dcsCommon.getUnitHeading(theUnit)\
    if not theUnit then return 0 end \
    if not theUnit:isExist() then return 0 end \
    local pos = theUnit:getPosition() -- returns three vectors, p is location\
\
    local heading = math.atan2(pos.x.z, pos.x.x)\
    -- make sure positive only, add 260 degrees\
    if heading < 0 then\
        heading = heading + 2 * math.pi    -- put heading in range of 0 to 2*pi\
    end\
    return heading \
end\
\
function dcsCommon.getUnitHeadingDegrees(theUnit)\
    local heading = dcsCommon.getUnitHeading(theUnit)\
    return heading * 57.2958 -- 180 / math.pi \
end\
\
function dcsCommon.unitIsInfantry(theUnit)\
    if not theUnit then return false end \
    if not theUnit:isExist() then return end\
    local theType = theUnit:getTypeName()\
    local isInfantry =  \
                dcsCommon.containsString(theType, \"infantry\", false) or \
                dcsCommon.containsString(theType, \"paratrooper\", false) or\
                dcsCommon.containsString(theType, \"stinger\", false) or\
                dcsCommon.containsString(theType, \"manpad\", false) or\
                dcsCommon.containsString(theType, \"soldier\", false) or \
                dcsCommon.containsString(theType, \"SA-18 Igla\", false)\
    return isInfantry\
end\
\
function dcsCommon.coalition2county(inCoalition)\
    -- simply return UN troops for 0 neutral,\
    -- joint red for 1  red\
    -- joint blue for 2 blue \
    if inCoalition == 1 then return 81 end -- cjtf red\
    if inCoalition == 2 then return 80 end -- blue \
    if type(inCoalition) == \"string\" then \
            inCoalition = inCoalition:lower()\
            if inCoalition == \"red\" then return 81 end\
            if inCoalition == \"blue\" then return 80 end\
    end\
        \
    trigger.action.outText(\"+++dcsC: coalition2county in (\" .. inCoalition .. \") converts to UN (82)!\", 30)\
    return 82 -- UN \
    \
end\
\
--\
--\
-- INIT\
--\
--\
    -- init any variables the lib requires internally\
    function dcsCommon.init()\
        cbID = 0\
        dcsCommon.uuIdent = 0\
        if (dcsCommon.verbose) or true then\
          trigger.action.outText(\"dcsCommon v\" .. dcsCommon.version .. \" loaded\", 10)\
        end\
    end\
\
    \
-- do init. \
dcsCommon.init()\
\
--[[--\
\
to do: \
- formation 2Column\
- formation 3Column\
\
-]]--\
",
                    ["predicate"] = "a_do_script",
                }, -- end of [1]
                [2] = 
                {
                    ["text"] = "-- cf/x zone management module\
-- reads dcs zones and makes them accessible and mutable \
-- by scripting.\
--\
-- Copyright (c) 2021, 2022 by Christian Franz and cf/x AG\
--\
\
cfxZones = {}\
cfxZones.version = \"2.5.8\"\
--[[-- VERSION HISTORY\
 - 2.2.4 - getCoalitionFromZoneProperty\
         - getStringFromZoneProperty\
 - 2.2.5 - createGroundUnitsInZoneForCoalition corrected coalition --> country \
 - 2.2.6 - getVectorFromZoneProperty(theZone, theProperty, defaultVal)\
 - 2.2.7 - allow 'yes' as 'true' for boolean attribute \
 - 2.2.8 - getBoolFromZoneProperty supports default \
         - cfxZones.hasProperty\
 - 2.3.0 - property names are case insensitive \
 - 2.3.1 - getCoalitionFromZoneProperty allows 0, 1, 2 also\
 - 2.4.0 - all zones look for owner attribute, and set it to 0 (neutral) if not present \
 - 2.4.1 - getBoolFromZoneProperty upgraded by expected bool \
         - markZoneWithSmoke raised by 3 meters\
 - 2.4.2 - getClosestZone also returns delta \
 - 2.4.3 - getCoalitionFromZoneProperty() accepts 'all' as neutral \
           createUniqueZoneName()\
           getStringFromZoneProperty returns default if property value = \"\"\
           corrected bug in addZoneToManagedZones\
 - 2.4.4 - getPoint(aZone) returns uip-to-date pos for linked and normal zones\
         - linkUnit can use \"useOffset\" property to keep relative position\
 - 2.4.5 - updated various methods to support getPoint when referencing \
           zone.point  \
 - 2.4.6 - corrected spelling in markZoneWithSmoke\
 - 2.4.7 - copy reference to dcs zone into cfx zone \
 - 2.4.8 - getAllZoneProperties\
 - 2.4.9 - createSimpleZone no longer requires location \
         - parse dcs adds empty .properties = {} if none tehre \
         - createCircleZone adds empty properties \
         - createPolyZone adds empty properties \
 - 2.4.10 - pickRandomZoneFrom now defaults to all cfxZones.zones\
          - getBoolFromZoneProperty also recognizes 0, 1\
          - removed autostart\
 - 2.4.11 - removed typo in get closest zone \
 - 2.4.12 - getStringFromZoneProperty\
 - 2.5.0  - harden getZoneProperty and all getPropertyXXXX\
 - 2.5.1  - markZoneWithSmoke supports alt attribute \
 - 2.5.2  - getPoint also writes through to zone itself for optimization\
          - new method getPositiveRangeFromZoneProperty(theZone, theProperty, default)\
 - 2.5.3  - new getAllGroupsInZone()\
 - 2.5.4  - cleaned up getZoneProperty break on no properties \
          - extractPropertyFromDCS trims key and property \
 - 2.5.5  - pollFlag() centralized for banging \
          - allStaticsInZone\
 - 2.5.6  - flag accessor setFlagValue(), getFlagValue()  \
          - pollFlag supports theZone as final parameter\
          - randomDelayFromPositiveRange\
          - isMEFlag\
 - 2.5.7  - pollFlag supports dml flags\
 - 2.5.8  - flagArrayFromString\
          - getFlagNumber invokes tonumber() before returning result \
 \
--]]--\
cfxZones.verbose = false\
cfxZones.caseSensitiveProperties = false -- set to true to make property names case sensitive \
cfxZones.ups = 1 -- updates per second. updates moving zones\
\
cfxZones.zones = {} -- these are the zone as retrieved from the mission.\
                    -- ALWAYS USE THESE, NEVER DCS's ZONES!!!!\
\
-- a zone has the following attributes\
-- x, z -- coordinate of center. note they have correct x, 0, z coordinates so no y-->z mapping\
-- radius (zero if quad zone)\
-- isCircle (true if quad zone)\
-- poly the quad coords are in the poly attribute and are a \
-- 1..n, wound counter-clockwise as (currently) in DCS:\
-- lower left, lower right upper left, upper right, all coords are x, 0, z \
-- bounds - contain the AABB coords for the zone: ul (upper left), ur, ll (lower left), lr \
--          for both circle and poly, all (x, 0, z)\
\
-- zones can carry information in their names that can get processed into attributes\
-- use \
-- zones can also carry information in their 'properties' tag that ME allows to \
-- edit. cfxZones provides an easy method to access these properties \
--  - getZoneProperty (returns as string)\
--  - getMinMaxFromZoneProperty\
--  - getBoolFromZoneProperty\
--  - getNumberFromZoneProperty\
\
\
-- SUPPORTED PROPERTIES\
-- - \"linkedUnit\" - zone moves with unit of that name. must be exact match\
--   can be combined with other attributes that extend (e.g. scar manager and\
--   limited pilots/airframes \
--\
\
--\
-- readZonesFromDCS is executed exactly once at the beginning\
-- from then on, use only the cfxZones.zones table \
-- WARNING: cfxZones is NOT case-sensitive. All zone names are \
-- indexed by upper case. If you have two zones with same name but \
-- different case, one will be replaced\
--\
\
function cfxZones.readFromDCS(clearfirst)\
    if (clearfirst) then\
        cfxZones.zones = {}\
    end\
    -- not all missions have triggers or zones\
    if not env.mission.triggers then \
        if cfxZones.verbose then \
            trigger.action.outText(\"cf/x zones: no env.triggers defined\", 10)\
        end\
        return\
    end\
    \
    if not env.mission.triggers.zones then \
        if cfxZones.verbose then \
            trigger.action.outText(\"cf/x zones: no zones defined\", 10)\
        end\
        return;\
    end\
\
    -- we only retrieve the data we need. At this point it is name, location and radius\
    -- and put this in our own little  structure. we also convert to all upper case name for index\
    -- and assume that the name may also carry meaning, e.g. 'LZ:' defines a landing zone\
    -- so we can quickly create other sets from this\
    -- zone object. DCS 2.7 introduced quads, so this is supported as well\
    --   name - name in upper case\
    --   isCircle - true if circular zone \
    --   isPoly - true if zone is defined by convex polygon, e.g. quad \
    --   point - vec3 (x 0 z) - zone's in-world center, used to place the coordinate\
    --   radius - number, zero when quad\
    --   bounds - aabb with attributes ul, ur, ll, lr (upper left .. lower right) as (x, 0, z)\
    --   poly - array 1..n of poly points, wound counter-clockwise \
    \
    for i, dcsZone in pairs(env.mission.triggers.zones) do\
        if type(dcsZone) == 'table' then -- hint taken from MIST: verify type when reading from dcs\
                                         -- dcs data is like a box of chocolates...\
            local newZone = {}\
            -- name, converted to upper is used only for indexing\
            -- the original name remains untouched\
            newZone.dcsZone = dcsZone\
            newZone.name = dcsZone.name\
            newZone.isCircle = false\
            newZone.isPoly = false\
            newZone.radius = 0\
            newZone.poly = {}\
            newZone.bounds = {}\
            newZone.properties = {} -- dcs has this too, copy if present\
            if dcsZone.properties then \
                newZone.properties = dcsZone.properties \
            else\
                newZone.properties = {}\
            end -- WARNING: REF COPY. May need to clone \
            \
            local upperName = newZone.name:upper()\
            \
            -- location as 'point'\
            -- WARNING: zones locs are 2D (x,y) pairs, whily y in DCS is altitude.\
            --          so we need to change (x,y) into (x, 0, z). Since Zones have no\
            --          altitude (they are an infinite cylinder) this works. Remember to \
            --          drop y from zone calculations to see if inside. \
            newZone.point = cfxZones.createPoint(dcsZone.x, 0, dcsZone.y)\
\
\
            -- start type processing. if zone.type exists, we have a mission \
            -- created with 2.7 or above, else earlier \
            local zoneType = 0\
            if (dcsZone.type) then \
                zoneType = dcsZone.type \
            end\
            \
            if zoneType == 0 then \
                -- circular zone \
                newZone.isCircle = true \
                newZone.radius = dcsZone.radius\
    \
            elseif zoneType == 2 then\
                -- polyZone\
                newZone.isPoly = true \
                newZone.radius = dcsZone.radius -- radius is still written in DCS, may change later\
                -- now transfer all point in the poly\
                -- note: DCS in 2.7 misspells vertices as 'verticies'\
                -- correct vor this \
                local verts = {}\
                if dcsZone.verticies then verts = dcsZone.verticies \
                else \
                    -- in later versions, this was corrected\
                    verts = dcsZone.vertices -- see if this is ever called\
                end\
                \
                for v=1, #verts do\
                    local dcsPoint = verts[v]\
                    local polyPoint = cfxZones.createPointFromDCSPoint(dcsPoint) -- (x, y) -- (x, 0, y-->z)\
                    newZone.poly[v] = polyPoint\
                end\
            else \
                \
                trigger.action.outText(\"cf/x zones: malformed zone #\" .. i .. \" unknown type \" .. zoneType, 10)\
            end\
            \
\
            -- calculate bounds\
            cfxZones.calculateZoneBounds(newZone) \
\
            -- add to my table\
            cfxZones.zones[upperName] = newZone -- WARNING: UPPER ZONE!!!\
            --trigger.action.outText(\"znd: procced \" .. newZone.name .. \" with radius \" .. newZone.radius, 30)\
        else\
            if cfxZones.verbose then \
                trigger.action.outText(\"cf/x zones: malformed zone #\" .. i .. \" dropped\", 10)\
            end\
        end -- else var not a table\
        \
    end -- for all zones kvp\
end -- readFromDCS\
\
function cfxZones.calculateZoneBounds(theZone)\
    if not (theZone) then return \
    end\
    \
    local bounds = theZone.bounds -- copy ref!\
    \
    if theZone.isCircle then \
        -- aabb are easy: center +/- radius \
        local center = theZone.point\
        local radius = theZone.radius \
        -- dcs uses z+ is down on map\
        -- upper left is center - radius \
        bounds.ul = cfxZones.createPoint(center.x - radius, 0, center.z - radius)\
        bounds.ur = cfxZones.createPoint(center.x + radius, 0, center.z - radius)\
        bounds.ll = cfxZones.createPoint(center.x - radius, 0, center.z + radius)\
        bounds.lr = cfxZones.createPoint(center.x + radius, 0, center.z + radius)\
        \
    elseif theZone.isPoly then\
        local poly = theZone.poly -- ref copy!\
        -- create the four points\
        local ll = cfxZones.createPointFromPoint(poly[1])\
        local lr = cfxZones.createPointFromPoint(poly[1])\
        local ul = cfxZones.createPointFromPoint(poly[1])\
        local ur = cfxZones.createPointFromPoint(poly[1])\
\
        -- now iterate through all points and adjust bounds accordingly \
        for v=2, #poly do \
             local vertex = poly[v]\
             if (vertex.x < ll.x) then ll.x = vertex.x; ul.x = vertex.x end \
             if (vertex.x > lr.x) then lr.x = vertex.x; ur.x = vertex.x end \
             if (vertex.z < ul.z) then ul.z = vertex.z; ur.z = vertex.z end\
             if (vertex.z > ll.z) then ll.z = vertex.z; lr.z = vertex.z end \
            \
        end\
        \
        -- now keep the new point references\
        -- and store them in the zone's bounds\
        bounds.ll = ll\
        bounds.lr = lr\
        bounds.ul = ul\
        bounds.ur = ur \
    else \
        -- huston, we have a problem\
        if cfxZones.verbose then \
            trigger.action.outText(\"cf/x zones: calc bounds: zone \" .. theZone.name .. \" has unknown type\", 30)\
        end\
    end\
    \
end\
\
function cfxZones.createPoint(x, y, z)\
    local newPoint = {}\
    newPoint.x = x\
    newPoint.y = y\
    newPoint.z = z \
    return newPoint\
end\
\
function cfxZones.copyPoint(inPoint) \
    local newPoint = {}\
    newPoint.x = inPoint.x\
    newPoint.y = inPoint.y\
    newPoint.z = inPoint.z \
    return newPoint    \
end\
\
function cfxZones.createHeightCorrectedPoint(inPoint) -- this should be in dcsCommon\
    local cP = cfxZones.createPoint(inPoint.x, land.getHeight({x=inPoint.x, y=inPoint.z}),inPoint.z)\
    return cP\
end\
\
function cfxZones.getHeightCorrectedZonePoint(theZone)\
    return cfxZones.createHeightCorrectedPoint(theZone.point)\
end\
\
function cfxZones.createPointFromPoint(inPoint)\
    return cfxZones.copyPoint(inPoint)\
end\
\
function cfxZones.createPointFromDCSPoint(inPoint) \
    return cfxZones.createPoint(inPoint.x, 0, inPoint.y)\
end\
\
\
function cfxZones.createRandomPointInsideBounds(bounds)\
    local x = math.random(bounds.ll.x, ur.x)\
    local z = math.random(bounds.ll.z, ur.z)\
    return cfxZones.createPoint(x, 0, z)\
end\
\
function cfxZones.addZoneToManagedZones(theZone)\
    local upperName = string.upper(theZone.name) -- newZone.name:upper()\
    cfxZones.zones[upperName] = theZone\
end\
\
function cfxZones.createUniqueZoneName(inName, searchSet)\
    if not inName then return nil end \
    if not searchSet then searchSet = cfxZones.zones end \
    inName = inName:upper()\
    while searchSet[inName] ~= nil do \
        inName = inName .. \"X\"\
    end\
    return inName\
end\
\
function cfxZones.createSimpleZone(name, location, radius, addToManaged)\
    if not radius then radius = 10 end\
    if not addToManaged then addToManaged = false end \
    if not location then \
        location = {}\
    end\
    if not location.x then location.x = 0 end \
    if not location.z then location.z = 0 end \
    \
    local newZone = cfxZones.createCircleZone(name, location.x, location.z, radius)\
    \
    if addToManaged then \
        cfxZones.addZoneToManagedZones(newZone)\
    end\
    return newZone\
end\
\
function cfxZones.createCircleZone(name, x, z, radius) \
    local newZone = {}\
    newZone.isCircle = true\
    newZone.isPoly = false\
    newZone.poly = {}\
    newZone.bounds = {}\
            \
    newZone.name = name\
    newZone.radius = radius\
    newZone.point = cfxZones.createPoint(x, 0, z)\
 \
    -- props \
    newZone.properties = {}\
    \
    -- calculate my bounds\
    cfxZones.calculateZoneBounds(newZone)\
    \
    return newZone\
end\
\
function cfxZones.createPolyZone(name, poly) -- poly must be array of point type\
local newZone = {}\
    newZone.isCircle = false\
    newZone.isPoly = true\
    newZone.poly = {}\
    newZone.bounds = {}\
            \
    newZone.name = name\
    newZone.radius = 0\
    -- copy poly\
    for v=1, #poly do \
        local theVertex = poly[v] \
        newZone.poly[v] = cfxZones.createPointFromPoint(theVertex) \
    end\
    \
    -- properties \
    newZone.properties = {}\
    \
    cfxZones.calculateZoneBounds(newZone)\
end\
\
\
\
function cfxZones.createRandomZoneInZone(name, inZone, targetRadius, entirelyInside)\
    -- create a new circular zone with center placed inside inZone\
    -- if entirelyInside is false, only the zone's center is guaranteed to be inside\
    -- inZone.\
    \
--    trigger.action.outText(\"Zones: creating rZiZ with tr = \" .. targetRadius .. \" for \" .. inZone.name .. \" that as r = \" .. inZone.radius, 10)\
    \
    if inZone.isCircle then \
        local sourceRadius = inZone.radius\
        if entirelyInside and targetRadius > sourceRadius then targetRadius = sourceRadius end\
        if entirelyInside then sourceRadius = sourceRadius - targetRadius end\
    \
        -- ok, let's first create a random percentage value for the new radius\
        local percent = 1 / math.random(100)\
        -- now lets get a random degree\
        local degrees = math.random(360) * 3.14152 / 180 -- ok, it's actually radiants. \
        local r = sourceRadius * percent \
        local x = inZone.point.x + r * math.cos(degrees)\
        local z = inZone.point.z + r * math.sin(degrees)\
        -- construct new zone\
        local newZone = cfxZones.createCircleZone(name, x, z, targetRadius)\
        return newZone\
    \
    elseif inZone.isPoly then \
        -- we have a poly zone. the way we do this is simple:\
        -- generate random x, z with ranges of the bounding box \
        -- until the point falls within the polygon.\
        local newPoint = {}\
        local emergencyBrake = 0\
        repeat\
            newPoint = cfxZones.createRandomPointInsideBounds(inZone.bounds)\
            emergencyBrake = emergencyBrake + 1\
            if (emergencyBrake > 100) then \
                newPoint = cfxZones.copyPoint(inZone.Point)\
                trigger.action.outText(\"CreateZoneInZone: mergency brake for inZone\" .. inZone.name,  10)\
                break\
            end\
        until cfxZones.isPointInsidePoly(newPoint, inZone.poly)\
        \
        -- construct new zone\
        local newZone = cfxZones.createCircleZone(name, newPoint.x, newPoint.z, targetRadius)\
        return newZone\
        \
    else \
        -- zone type unknown\
        trigger.action.outText(\"CreateZoneInZone: unknown zone type for inZone =\" .. inZone.name ,  10)\
        return nil \
    end\
end\
\
-- polygon inside zone calculations\
\
\
-- isleft returns true if point P is to the left of line AB \
-- by determining the sign (up or down) of the normal vector of \
-- the two vectors PA and PB in the y coordinate. We arbitrarily define\
-- left as being > 0, so right is <= 0. As long as we always use the \
-- same comparison, it does not matter what up or down mean.\
-- this is important because we don't know if dcs always winds quads\
-- the same way, we must simply assume that they are wound as a polygon \
function cfxZones.isLeftXZ(A, B, P)\
    return ((B.x - A.x)*(P.z - A.z) - (B.z - A.z)*(P.x - A.x)) > 0\
end\
\
-- returns true/false for inside\
function cfxZones.isPointInsideQuad(thePoint, A, B, C, D) \
    -- Inside test (only convex polygons): \
    -- point lies on the same side of each quad's vertex AB, BC, CD, DA\
    -- how do we find out which side a point lies on? via the cross product\
    -- see isLeft below\
    \
    -- so all we need to do is make sure all results of isLeft for all\
    -- four sides are the same\
    mustMatch = isLeftXZ(A, B, thePoint) -- all test results must be the same and we are ok\
                                       -- they just must be the same side.\
    if (cfxZones.isLeftXZ(B, C, thePoint ~= mustMatch)) then return false end -- on other side than all before\
    if (cfxZones.isLeftXZ(C, D, thePoint ~= mustMatch)) then return false end \
    if (cfxZones.isLeftXZ(D, A, thePoint ~= mustMatch)) then return false end\
    return true\
end\
\
-- generalized version of insideQuad, assumes winding of poly, poly convex, poly closed\
function cfxZones.isPointInsidePoly(thePoint, poly)\
    local mustMatch = cfxZones.isLeftXZ(poly[1], poly[2], thePoint)\
    for v=2, #poly-1 do \
        if cfxZones.isLeftXZ(poly[v], poly[v+1], thePoint) ~= mustMatch then return false end\
    end\
    -- final test\
    if cfxZones.isLeftXZ(poly[#poly], poly[1], thePoint) ~= mustMatch then return false end\
    \
    return true\
end;\
\
function cfxZones.isPointInsideZone(thePoint, theZone)\
    local p = {x=thePoint.x, y = 0, z = thePoint.z} -- zones have no altitude\
    if (theZone.isCircle) then \
        local zp = cfxZones.getPoint(theZone)\
        local d = dcsCommon.dist(p, theZone.point)\
        return d < theZone.radius\
    end \
    \
    if (theZone.isPoly) then \
        --trigger.action.outText(\"zne: isPointInside: \" .. theZone.name .. \" is Polyzone!\", 30)\
        return (cfxZones.isPointInsidePoly(p, theZone.poly))\
    end\
\
    trigger.action.outText(\"isPointInsideZone: Unknown zone type for \" .. outerZone.name, 10)\
end\
\
-- isZoneInZone returns true if center of innerZone is inside  outerZone\
function cfxZones.isZoneInsideZone(innerZone, outerZone) \
    return cfxZones.isPointInsideZone(innerZone.point, outerZone)\
\
    \
end\
\
function cfxZones.getZonesContainingPoint(thePoint, testZones) -- return array \
    if not testZones then \
        testZones = cfxZones.zones \
    end \
    \
    local containerZones = {}\
    for tName, tData in pairs(testZones) do \
        if cfxZones.isPointInsideZone(thePoint, tData) then \
            table.insert(containerZones, tData)\
        end\
    end\
\
    return containerZones\
end\
\
function cfxZones.getFirstZoneContainingPoint(thePoint, testZones)\
    if not testZones then \
        testZones = cfxZones.zones \
    end \
    \
    for tName, tData in pairs(testZones) do \
        if cfxZones.isPointInsideZone(thePoint, tData) then \
            return tData\
        end\
    end\
\
    return nil\
end\
\
function cfxZones.getAllZonesInsideZone(superZone, testZones) -- returnes array!\
    if not testZones then \
        testZones = cfxZones.zones \
    end \
    \
    local containedZones = {}\
    for zName, zData in pairs(testZones) do\
        if cfxZones.isZoneInsideZone(zData, superZone) then \
            if zData ~= superZone then \
                -- we filter superzone because superzone usually resides \
                -- inside itself \
                table.insert(containedZones, zData)\
            end\
        end\
    end\
    return containedZones \
end\
\
function cfxZones.getZonesWithAttributeNamed(attributeName, testZones)\
    if not testZones then testZones = cfxZones.zones end \
    local attributZones = {}\
    for aName,aZone in pairs(testZones) do\
        local attr = cfxZones.getZoneProperty(aZone, attributeName)\
        if attr then \
            -- this zone has the requested attribute\
            table.insert(attributZones, aZone)\
        end\
    end\
    return attributZones\
end\
\
--\
-- units / groups in zone\
--\
function cfxZones.allGroupsInZone(theZone, categ) -- categ is optional, must be code \
    -- warning: does not check for exiting!\
    --trigger.action.outText(\"Zone \" .. theZone.name .. \" radius \" .. theZone.radius, 30)\
    local inZones = {}\
    local coals = {0, 1, 2} -- all coalitions\
    for idx, coa in pairs(coals) do \
        local allGroups = coalition.getGroups(coa, categ)\
        for key, group in pairs(allGroups) do -- iterate all groups\
            if cfxZones.isGroupPartiallyInZone(group, theZone) then\
                table.insert(inZones, group)\
            end\
        end\
    end\
    return inZones\
end\
\
function cfxZones.allStaticsInZone(theZone) -- categ is optional, must be code \
    -- warning: does not check for exiting!\
    local inZones = {}\
    local coals = {0, 1, 2} -- all coalitions\
    for idx, coa in pairs(coals) do \
        local allStats = coalition.getStaticObjects(coa)\
        for key, statO in pairs(allStats) do -- iterate all groups\
            local oP = statO:getPoint()\
            if cfxZones.pointInZone(oP, theZone) then\
                table.insert(inZones, statO)\
            end\
        end\
    end\
    return inZones\
end\
\
function cfxZones.groupsOfCoalitionPartiallyInZone(coal, theZone, categ) -- categ is optional\
    local groupsInZone = {}\
    local allGroups = coalition.getGroups(coal, categ)\
    for key, group in pairs(allGroups) do -- iterate all groups\
        if group:isExist() then\
            if cfxZones.isGroupPartiallyInZone(group, theZone) then\
                table.insert(groupsInZone, group)            \
            end\
        end\
    end\
    return groupsInZone\
end\
\
function cfxZones.isGroupPartiallyInZone(aGroup, aZone)\
    if not aGroup then return false end \
    if not aZone then return false end \
        \
    if not aGroup:isExist() then return false end \
    local allUnits = aGroup:getUnits()\
    for uk, aUnit in pairs (allUnits) do \
        if aUnit:isExist() and aUnit:getLife() > 1 then         \
            local p = aUnit:getPoint()\
            local inzone, percent, dist = cfxZones.pointInZone(p, aZone)\
            if inzone then -- cfxZones.isPointInsideZone(p, aZone) then             \
                --trigger.action.outText(\"zne: YAY <\" .. aUnit:getName() .. \"> IS IN \" .. aZone.name, 30) \
                return true\
            end \
            --trigger.action.outText(\"zne: <\" .. aUnit:getName() .. \"> not in \" .. aZone.name .. \", dist = \" .. dist .. \", rad = \", aZone.radius, 30) \
        end\
    end\
    return false\
end\
\
function cfxZones.isEntireGroupInZone(aGroup, aZone)\
    if not aGroup then return false end \
    if not aZone then return false end \
    if not aGroup:isExist() then return false end \
    local allUnits = aGroup:getUnits()\
    for uk, aUnit in pairs (allUnits) do \
        if aUnit:isExist() and aUnit:getLife() > 1 then \
            local p = aUnit:getPoint()\
            if not cfxZones.isPointInsideZone(p, aZone) then \
                return false\
            end\
        end\
    end\
    return true\
end\
\
\
--\
-- Zone Manipulation\
--\
\
function cfxZones.offsetZone(theZone, dx, dz)\
    -- first, update center \
    theZone.point.x = theZone.point.x + dx\
    theZone.point.z = theZone.point.z + dz \
    \
    -- now process all polygon points - it's empty for circular, so don't worry\
    for v=1, #theZone.poly do \
        theZone.poly[v].x = theZone.poly[v].x + dx\
        theZone.poly[v].z = theZone.poly[v].z + dz \
    end\
end\
\
function cfxZones.moveZoneTo(theZone, x, z)\
    local dx = x - theZone.point.x\
    local dz = z - theZone.point.z \
    cfxZones.offsetZone(theZone, dx, dz)\
end;\
\
function cfxZones.centerZoneOnUnit(theZone, theUnit) \
    local thePoint = theUnit:getPoint()\
    cfxZones.moveZoneTo(theZone, thePoint.x, thePoint.z)\
end\
\
\
--[[\
-- no longer makes sense with poly zones\
function cfxZones.isZoneEntirelyInsideZone(innerZone, outerZone)\
    if (innerZone.radius > outerZone.radius) then return false end -- cant fit inside\
    local d = dcsCommon.dist(innerZone.point, outerZone.point)\
    local reducedR = outerZone.radius - innerZone.radius\
    return d < reducedR\
end;\
--]]\
\
function cfxZones.dumpZones(zoneTable)\
    if not zoneTable then zoneTable = cfxZones.zones end \
    \
    trigger.action.outText(\"Zones START\", 10)\
    for i, zone in pairs(zoneTable) do \
        local myType = \"unknown\"\
        if zone.isCircle then myType = \"Circle\" end\
        if zone.isPoly then myType = \"Poly\" end \
        \
        trigger.action.outText(\"#\".. i .. \": \" .. zone.name .. \" of type \" .. myType, 10)\
    end\
    trigger.action.outText(\"Zones END\", 10)\
end\
\
function cfxZones.stringStartsWith(theString, thePrefix)\
    return theString:find(thePrefix) == 1\
end\
\
function cfxZones.keysForTable(theTable)\
    local keyset={}\
    local n=0\
\
    for k,v in pairs(tab) do\
        n=n+1\
        keyset[n]=k\
    end\
    return keyset\
end\
\
\
--\
-- return all zones that have a specific named property\
--\
function cfxZones.zonesWithProperty(propertyName, searchSet)\
    if not searchSet then searchSet = cfxZones.zones end \
    local theZones = {}\
    for k, aZone in pairs(searchSet) do \
        if not aZone then \
            trigger.action.outText(\"+++zone: nil aZone for \" .. k, 30)\
        else \
            local lU = cfxZones.getZoneProperty(aZone, propertyName)\
            if lU then \
                table.insert(theZones, aZone)\
            end\
        end\
    end    \
    return theZones\
end\
\
--\
-- return all zones from the zone table that begin with string prefix\
--\
function cfxZones.zonesStartingWithName(prefix, searchSet)\
    \
    if not searchSet then searchSet = cfxZones.zones end \
    \
--    trigger.action.outText(\"Enter: zonesStartingWithName for \" .. prefix , 30)\
    local prefixZones = {}\
    prefix = prefix:upper() -- all zones have UPPERCASE NAMES! THEY SCREAM AT YOU\
    for name, zone in pairs(searchSet) do\
--        trigger.action.outText(\"testing \" .. name:upper() .. \" starts with \" .. prefix , 30)\
        if cfxZones.stringStartsWith(name:upper(), prefix) then\
            prefixZones[name] = zone -- note: ref copy!\
            --trigger.action.outText(\"zone with prefix <\" .. prefix .. \"> found: \" .. name, 10)\
        end\
    end\
    \
    return prefixZones\
end\
\
--\
-- return all zones from the zone table that begin with the string or set of strings passed in prefix \
-- if you pass 'true' as second (optional) parameter, it will first look for all zones that begin\
-- with '+' and return only those. Use during debugging to force finding a specific zone\
--\
function cfxZones.zonesStartingWith(prefix, searchSet, debugging)\
    -- you can force zones by having their name start with \"+\"\
    -- which will force them to return immediately if debugging is true for this call\
\
    if (debugging) then \
        local debugZones = cfxZones.zonesStartingWithName(\"+\", searchSet)\
        if not (next(debugZones) == nil) then -- # operator only works on array elements \
            --trigger.action.outText(\"returning zones with prefix <\" .. prefix .. \">\", 10)\
            return debugZones \
        end \
    end\
    \
    --trigger.action.outText(\"#debugZones is  <\" .. #debugZones .. \">\", 10)\
\
    if (type(prefix) == \"string\") then \
        return cfxZones.zonesStartingWithName(prefix, searchSet)\
    end\
    \
    local allZones = {}\
    for i=1, #prefix do \
        -- iterate through all names in prefix set\
        local theName = prefix[i]\
        local newZones = cfxZones.zonesStartingWithName(theName, searchSet)\
        -- add them all to current table\
        for zName, zInfo in pairs(newZones) do \
            allZones[zName] = zInfo -- will also replace doublets\
        end\
    end\
    \
    return allZones\
end\
\
function cfxZones.getZoneByName(aName, searchSet) \
    if not searchSet then searchSet = cfxZones.zones end \
    aName = aName:upper()\
    return searchSet[aName] -- the joys of key value pairs\
end\
\
function cfxZones.getZonesContainingString(aString, searchSet) \
    if not searchSet then searchSet = cfxZones.zones end\
    aString = string.upper(aString)\
    resultSet = {}\
    for zName, zData in pairs(searchSet) do \
        if aString == string.upper(zData.name) then \
            resultSet[zName] = zData\
        end\
    end\
    \
end;\
\
-- filter zones by range to a point. returns indexed set\
function cfxZones.getZonesInRange(point, range, theZones)\
    if not theZones then theZones = cfxZones.zones end\
    \
    local inRangeSet = {}\
    for zName, zData in pairs (theZones) do \
        if dcsCommon.dist(point, zData.point) < range then \
            table.insert(inRangeSet, zData)\
        end\
    end\
    return inRangeSet \
end\
\
-- get closest zone returns the zone that is closest to point \
function cfxZones.getClosestZone(point, theZones)\
    if not theZones then theZones = cfxZones.zones end\
    local currDelta = math.huge \
    local closestZone = nil\
    for zName, zData in pairs(theZones) do \
        local zPoint = cfxZones.getPoint(zData)\
        local delta = dcsCommon.dist(point, zPoint)\
        if (delta < currDelta) then \
            currDelta = delta\
            closestZone = zData\
        end\
    end\
    return closestZone, currDelta \
end\
\
-- return a random zone from the table passed in zones\
function cfxZones.pickRandomZoneFrom(zones)\
    if not zones then zones = cfxZones.zones end\
    local indexedZones = dcsCommon.enumerateTable(zones)\
    local r = math.random(#indexedZones)\
    return indexedZones[r]\
end\
\
-- return an zone element by index \
function cfxZones.getZoneByIndex(theZones, theIndex) \
    local enumeratedZones = dcsCommon.enumerateTable(theZones)\
    if (theIndex > #enumeratedZones) then\
        trigger.action.outText(\"WARNING: zone index \" .. theIndex .. \" out of bounds - max = \" .. #enumeratedZones, 30)\
        return nil end\
    if (theIndex < 1) then return nil end\
    \
    return enumeratedZones[theIndex]\
end\
\
-- place a smoke marker in center of zone, offset by dx, dy \
function cfxZones.markZoneWithSmoke(theZone, dx, dz, smokeColor, alt)\
    if not alt then alt = 5 end \
    local point = cfxZones.getPoint(theZone) --{} -- theZone.point\
    point.x = point.x + dx -- getpoint updates and returns copy \
    point.z = point.z + dz \
    -- get height at point \
    point.y = land.getHeight({x = point.x, y = point.z}) + alt\
    -- height-correct\
    --local newPoint= {x = point.x, y = land.getHeight({x = point.x, y = point.z}) + 3, z= point.z}\
    trigger.action.smoke(point, smokeColor)\
end\
\
-- place a smoke marker in center of zone, offset by radius and degrees \
function cfxZones.markZoneWithSmokePolar(theZone, radius, degrees, smokeColor, alt)\
    local rads = degrees * math.pi / 180\
    local dx = radius * math.sin(rads)\
    local dz = radius * math.cos(rads)\
    cfxZones.markZoneWithSmoke(theZone, dx, dz, smokeColor, alt)\
end\
\
-- place a smoke marker in center of zone, offset by radius and randomized degrees \
function cfxZones.markZoneWithSmokePolarRandom(theZone, radius, smokeColor)\
    local degrees = math.random(360)\
    cfxZones.markZoneWithSmokePolar(theZone, radius, degrees, smokeColor)\
end\
\
\
-- unitInZone returns true if theUnit is inside the zone \
-- the second value returned is the percentage of distance\
-- from center to rim, with 100% being entirely in center, 0 = outside\
-- the third value returned is the distance to center\
function cfxZones.pointInZone(thePoint, theZone)\
    if not (theZone) then return false, 0, 0 end\
        \
    local pflat = {x = thePoint.x, y = 0, z = thePoint.z}\
    \
    local zpoint = cfxZones.getPoint(theZone) -- updates zone if linked \
    local ppoint = thePoint -- xyz\
    local pflat = {x = ppoint.x, y = 0, z = ppoint.z}\
    local dist = dcsCommon.dist(zpoint, pflat)\
    \
    if theZone.isCircle then \
        if theZone.radius <= 0 then \
            return false, 0, 0\
        end\
\
        local success = dist < theZone.radius\
        local percentage = 0\
        if (success) then \
            percentage = 1 - dist / theZone.radius \
        end\
        return success, percentage, dist \
    \
    elseif theZone.isPoly then\
        local success = cfxZones.isPointInsidePoly(pflat, theZone.poly)\
        return success, 0, dist\
    else \
        trigger.action.outText(\"pointInZone: Unknown zone type for \" .. theZone.name, 10)\
    end\
\
    return false\
end\
\
function cfxZones.unitInZone(theUnit, theZone)\
    if not (theUnit) then return false, 0, 0 end\
    if not (theUnit:isExist()) then return false, 0, 0 end\
    -- force zone update if it is linked to another zone \
    -- pointInZone does update\
    local thePoint = theUnit:getPoint()\
    return cfxZones.pointInZone(thePoint, theZone)\
    \
end\
\
-- returns all units of the input set that are inside the zone \
function cfxZones.unitsInZone(theUnits, theZone)\
    if not theUnits then return {} end\
    if not theZone then return {} end\
    \
    local zoneUnits = {}\
    for index, aUnit in pairs(theUnits) do \
        if cfxZones.unitInZone(aUnit, theZone) then \
            table.insert( zoneUnits, aUnit)\
        end\
    end\
    return zoneUnits\
end\
\
function cfxZones.closestUnitToZoneCenter(theUnits, theZone)\
    -- does not care if they really are in zone. call unitsInZone first\
    -- if you need to have them filtered\
    -- theUnits MUST BE ARRAY\
    if not theUnits then return nil end\
    if #theUnits == 0 then return nil end\
    local closestUnit = theUnits[1]\
    for i=2, #theUnits do\
        local aUnit = theUnits[i]\
        if dcsCommon.dist(theZone.point, closestUnit:getPoint()) > dcsCommon.dist(theZone.point, aUnit:getPoint()) then \
            closestUnit = aUnit\
        end\
    end\
    return closestUnit\
end\
\
function cfxZones.anyPlayerInZone(theZone) -- returns first player it finds\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do\
        local playerUnit = pinfo.unit\
        if (cfxZones.unitInZone(playerUnit, theZone)) then \
            return true, playerUnit\
        end\
    end -- for all players \
    return false, nil\
end\
\
\
-- grow zone\
function cfxZones.growZone()\
    -- circular zones simply increase radius\
    -- poly zones: not defined \
    \
end\
\
\
-- creating units in a zone\
function cfxZones.createGroundUnitsInZoneForCoalition (theCoalition, groupName, theZone, theUnits, formation, heading) \
    -- theUnits can be string or table of string \
    if not groupName then groupName = \"G_\"..theZone.name end \
    -- group name will be taken from zone name and prependend with \"G_\"\
    local theGroup = dcsCommon.createGroundGroupWithUnits(groupName, theUnits, theZone.radius, nil, formation)\
    \
    -- turn the entire formation to heading\
    if (not heading) then heading = 0 end\
    dcsCommon.rotateGroupData(theGroup, heading) -- currently, group is still at origin, no cx, cy\
    \
    \
    -- now move the group to center of theZone\
    dcsCommon.moveGroupDataTo(theGroup, \
                          theZone.point.x, \
                          theZone.point.z) -- watchit: Z!!!\
\
\
    -- create the group in the world and return it\
    -- first we need to translate the coalition to a legal \
    -- country. we use UN for neutral, cjtf for red and blue \
    local theSideCJTF = dcsCommon.coalition2county(theCoalition)\
    return coalition.addGroup(theSideCJTF, Group.Category.GROUND, theGroup)\
\
end\
\
-- parsing zone names. The first part of the name until the first blank \" \" \
-- is the prefix and is dropped unless keepPrefix is true. \
-- all others are regarded as key:value pairs and are then added \
-- to the zone \
-- separated by equal sign \"=\" AND MUST NOT CONTAIN BLANKS\
--\
-- example usage \"followZone unit=rotary-1 dx=30 dy=25 rotateWithHeading=true\
--\
-- OLD DEPRECATED TECH -- TO BE DECOMMISSIONED SOON, DO NOT USE\
-- \
--[[--\
function cfxZones.parseZoneNameIntoAttributes(theZone, keepPrefix)\
--    trigger.action.outText(\"Parsing zone:  \".. theZone.name, 30)\
    if not keepPrefix then keepPrefix = false end -- simply for clarity\
    -- now split the name into space-separated strings\
    local attributes = dcsCommon.splitString(theZone.name, \" \")\
    if not keepPrefix then table.remove(attributes, 1) end -- pop prefix\
\
    -- now parse all substrings and add them as attributes to theZone\
    for i=1, #attributes do \
        local a = attributes[i]\
        local kvp = dcsCommon.splitString(a, \"=\")\
        if #kvp == 2 then \
            -- we have key value pair\
            local theKey = kvp[1]\
            local theValue = kvp[2]\
            theZone[theKey] = theValue \
--            trigger.action.outText(\"Zone \".. theZone.name .. \" parsed: Key = \" .. theKey .. \", Value = \" .. theValue, 30)\
        else \
--            trigger.action.outText(\"Zone \".. theZone.name .. \": dropped attribute \" .. a, 30)\
        end\
    end \
end\
--]]--\
-- OLD DEPRECATED TECH -- TO BE DECOMMISSIONED SOON, DO NOT USE\
--[[--\
function cfxZones.processCraterZones ()\
    local craters = cfxZones.zonesStartingWith(\"crater\")\
\
    \
\
    -- all these zones need to be processed and their name infor placed into attributes\
    for cName, cZone in pairs(craters) do\
        cfxZones.parseZoneNameIntoAttributes(cZone)\
        \
        -- blow stuff up at the location of the zone \
        local cPoint = cZone.point\
        cPoint.y = land.getHeight({x = cPoint.x, y = cPoint.z})  -- compensate for ground level\
        trigger.action.explosion(cPoint, 900)\
         \
        -- now interpret and act on the crater info \
        -- to destroy and place fire. \
        \
        -- fire has small, medium, large \
        -- eg. fire=large\
        \
    end\
end\
--]]--\
--\
-- Flag Pulling \
--\
function cfxZones.pollFlag(theFlag, method, theZone) \
    if cfxZones.verbose then \
        trigger.action.outText(\"+++zones: polling flag \" .. theFlag .. \" with \" .. method, 30)\
    end \
    \
    if not theZone then \
        trigger.action.outText(\"+++zones: nil theZone on pollFlag\", 30)\
    end\
    \
    method = method:lower()\
    --trigger.action.outText(\"+++zones: polling \" .. theZone.name .. \" method \" .. method .. \" flag \" .. theFlag, 30)\
    local currVal = cfxZones.getFlagValue(theFlag, theZone)\
    if method == \"inc\" or method == \"f+1\" then \
        --trigger.action.setUserFlag(theFlag, currVal + 1)\
        cfxZones.setFlagValue(theFlag, currVal+1, theZone)\
        \
    elseif method == \"dec\" or method == \"f-1\" then \
        -- trigger.action.setUserFlag(theFlag, currVal - 1)\
        cfxZones.setFlagValue(theFlag, currVal-1, theZone)\
\
    elseif method == \"off\" or method == \"f=0\" then \
        -- trigger.action.setUserFlag(theFlag, 0)\
        cfxZones.setFlagValue(theFlag, 0, theZone)\
\
    elseif method == \"flip\" or method == \"xor\" then \
        if currVal ~= 0 then \
--            trigger.action.setUserFlag(theFlag, 0)\
            cfxZones.setFlagValue(theFlag, 0, theZone)\
\
        else \
            --trigger.action.setUserFlag(theFlag, 1)\
            cfxZones.setFlagValue(theFlag, 1, theZone)\
        end\
        \
    else \
        if method ~= \"on\" and method ~= \"f=1\" then \
            trigger.action.outText(\"+++zones: unknown method <\" .. method .. \"> - using 'on'\", 30)\
        end\
        -- default: on.\
--        trigger.action.setUserFlag(theFlag, 1)\
        cfxZones.setFlagValue(theFlag, 1, theZone)\
\
    end\
    \
    if cfxZones.verbose then\
        local newVal = cfxZones.getFlagValue(theFlag, theZone)\
        trigger.action.outText(\"+++zones: flag <\" .. theFlag .. \"> changed from \" .. currVal .. \" to \" .. newVal, 30)\
    end \
end\
\
function cfxZones.setFlagValue(theFlag, theValue, theZone)\
    local zoneName = \"<dummy>\"\
    if not theZone then \
        trigger.action.outText(\"+++Zne: no zone on setFlagValue\")\
    else \
        zoneName = theZone.name -- for flag wildcards\
    end\
    \
    if type(theFlag) == \"number\" then \
        -- straight set, ME flag \
        trigger.action.setUserFlag(theFlag, theValue)\
        return \
    end\
    \
    -- we assume it's a string now\
    theFlag = dcsCommon.trim(theFlag) -- clear leading/trailing spaces\
    local nFlag = tonumber(theFlag) \
    if nFlag then \
        trigger.action.setUserFlag(theFlag, theValue)\
        return \
    end\
    \
    -- now do wildcard processing. we have alphanumeric\
    if dcsCommon.stringStartsWith(theFlag, \"*\") then  \
        theFlag = zoneName .. theFlag\
    end\
    trigger.action.setUserFlag(theFlag, theValue)\
end \
\
function cfxZones.getFlagValue(theFlag, theZone)\
    local zoneName = \"<dummy>\"\
    if not theZone then \
        trigger.action.outText(\"+++Zne: no zone on getFlagValue\", 30)\
    else \
        zoneName = theZone.name -- for flag wildcards\
    end\
    \
    if type(theFlag) == \"number\" then \
        -- straight get, ME flag \
        return tonumber(trigger.misc.getUserFlag(theFlag))\
    end\
    \
    -- we assume it's a string now\
    theFlag = dcsCommon.trim(theFlag) -- clear leading/trailing spaces\
    local nFlag = tonumber(theFlag) \
    if nFlag then \
        return tonumber(trigger.misc.getUserFlag(theFlag))\
    end\
    \
    -- now do wildcard processing. we have alphanumeric\
    if dcsCommon.stringStartsWith(theFlag, \"*\") then  \
            theFlag = zoneName .. theFlag\
    end\
    return tonumber(trigger.misc.getUserFlag(theFlag))\
end\
\
function cfxZones.isMEFlag(inFlag)\
    -- do NOT use me\
    trigger.action.outText(\"+++zne: warning: deprecated isMEFlag\", 30)\
    return true \
    -- returns true if inFlag is a pure positive number\
--    inFlag = dcsCommon.trim(inFlag)\
--    return dcsCommon.stringIsPositiveNumber(inFlag)\
end\
\
function cfxZones.flagArrayFromString(inString)\
-- original code from RND flag\
    if string.len(inString) < 1 then \
        trigger.action.outText(\"+++zne: empty flags\", 30)\
        return {} \
    end\
    if cfxZones.verbose then \
        trigger.action.outText(\"+++zne: processing <\" .. inString .. \">\", 30)\
    end \
    \
    local flags = {}\
    local rawElements = dcsCommon.splitString(inString, \",\")\
    -- go over all elements \
    for idx, anElement in pairs(rawElements) do \
        if dcsCommon.stringStartsWithDigit(anElement) and  dcsCommon.containsString(anElement, \"-\") then \
            -- interpret this as a range\
            local theRange = dcsCommon.splitString(anElement, \"-\")\
            local lowerBound = theRange[1]\
            lowerBound = tonumber(lowerBound)\
            local upperBound = theRange[2]\
            upperBound = tonumber(upperBound)\
            if lowerBound and upperBound then\
                -- swap if wrong order\
                if lowerBound > upperBound then \
                    local temp = upperBound\
                    upperBound = lowerBound\
                    lowerBound = temp \
                end\
                -- now add add numbers to flags\
                for f=lowerBound, upperBound do \
                    table.insert(flags, tostring(f))\
                end\
            else\
                -- bounds illegal\
                trigger.action.outText(\"+++zne: ignored range <\" .. anElement .. \"> (range)\", 30)\
            end\
        else\
            -- single number\
            f = dcsCommon.trim(anElement) -- DML flag upgrade: accept strings tonumber(anElement)\
            if f then \
                table.insert(flags, f)\
\
            else \
                trigger.action.outText(\"+++zne: ignored element <\" .. anElement .. \"> (single)\", 30)\
            end\
        end\
    end\
    if cfxZones.verbose then \
        trigger.action.outText(\"+++zne: <\" .. #flags .. \"> flags total\", 30)\
    end \
    return flags\
end\
\
--\
-- PROPERTY PROCESSING \
--\
\
function cfxZones.getAllZoneProperties(theZone, caseInsensitive) -- return as dict \
    if not caseInsensitive then caseInsensitive = false end \
    if not theZone then return {} end \
    \
    local dcsProps = theZone.properties -- zone properties in dcs format \
    local props = {}\
    -- dcs has all properties as array with values .key and .value \
    -- so convert them into a dictionary \
    for i=1, #dcsProps do \
        local theProp = dcsProps[i]\
        local theKey = \"dummy\"\
        if string.len(theProp.key) > 0 then theKey = theProp.key end \
        if caseInsensitive then theKey = theKey:upper() end \
        props[theKey] = theProp.value\
    end\
    return props \
end\
\
function cfxZones.extractPropertyFromDCS(theKey, theProperties)\
-- trim\
    theKey = dcsCommon.trim(theKey) \
--    make lower case conversion if not case sensitive\
    if not cfxZones.caseSensitiveProperties then \
        theKey = string.lower(theKey)\
    end\
\
-- iterate all keys and compare to what we are looking for     \
    for i=1, #theProperties do\
        local theP = theProperties[i]\
         \
        local existingKey = dcsCommon.trim(theP.key)  \
        if not cfxZones.caseSensitiveProperties then \
            existingKey = string.lower(existingKey)\
        end\
        if existingKey == theKey then \
            return theP.value\
        end\
    end\
    return nil \
end\
\
function cfxZones.getZoneProperty(cZone, theKey)\
    if not cZone then \
        trigger.action.outText(\"+++zone: no zone in getZoneProperty\", 30)\
        return nil\
    end \
    if not theKey then \
        trigger.action.outText(\"+++zone: no property key in getZoneProperty for zone \" .. cZone.name, 30)\
--        breakme.here = 1\
        return \
    end    \
\
    local props = cZone.properties\
    local theVal = cfxZones.extractPropertyFromDCS(theKey, props)\
    return theVal\
end\
\
function cfxZones.getStringFromZoneProperty(theZone, theProperty, default)\
    \
    if not default then default = \"\" end\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    if not p then return default end\
    if type(p) == \"string\" then \
        if p == \"\" then p = default end \
        return p\
    end\
    return default -- warning. what if it was a number first?\
end\
\
function cfxZones.getMinMaxFromZoneProperty(theZone, theProperty)\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    local theNumbers = dcsCommon.splitString(p, \" \")\
\
    return tonumber(theNumbers[1]), tonumber(theNumbers[2])\
    \
end\
\
function cfxZones.randomDelayFromPositiveRange(minVal, maxVal) \
    if not maxVal then return minVal end \
    if not minVal then return maxVal end \
    local delay = maxVal\
    if minVal > 0 and minVal < delay then \
        -- we want a randomized from time from minTime .. delay\
        local varPart = delay - minVal + 1\
        varPart = dcsCommon.smallRandom(varPart) - 1\
        delay = minVal + varPart\
    end\
    return delay \
end\
\
function cfxZones.getPositiveRangeFromZoneProperty(theZone, theProperty, default)\
    -- reads property as string, and interprets as range 'a-b'. \
    -- if not a range but single number, returns both for upper and lower \
    --trigger.action.outText(\"***Zne: enter with <\" .. theZone.name .. \">: range for property <\" .. theProperty .. \">!\", 30)\
    if not default then default = 0 end \
    local lowerBound = default\
    local upperBound = default \
    \
    local rangeString = cfxZones.getStringFromZoneProperty(theZone, theProperty, \"\")\
    if dcsCommon.containsString(rangeString, \"-\") then \
        local theRange = dcsCommon.splitString(rangeString, \"-\")\
        lowerBound = theRange[1]\
        lowerBound = tonumber(lowerBound)\
        upperBound = theRange[2]\
        upperBound = tonumber(upperBound)\
        if lowerBound and upperBound then\
            -- swap if wrong order\
            if lowerBound > upperBound then \
                local temp = upperBound\
                upperBound = lowerBound\
                lowerBound = temp \
            end\
--            if rndFlags.verbose then \
--            trigger.action.outText(\"+++Zne: detected range <\" .. lowerBound .. \", \" .. upperBound .. \">\", 30)\
--            end\
        else\
            -- bounds illegal\
            trigger.action.outText(\"+++Zne: illegal range  <\" .. rangeString .. \">, using \" .. default .. \"-\" .. default, 30)\
            lowerBound = default\
            upperBound = default \
        end\
    else \
        upperBound = cfxZones.getNumberFromZoneProperty(theZone, theProperty, default) -- between pulses \
        lowerBound = upperBound\
    end\
--    trigger.action.outText(\"+++Zne: returning <\" .. lowerBound .. \", \" .. upperBound .. \">\", 30)\
    return lowerBound, upperBound\
end\
\
function cfxZones.hasProperty(theZone, theProperty) \
    return cfxZones.getZoneProperty(theZone, theProperty) ~= nil \
end\
\
\
function cfxZones.getBoolFromZoneProperty(theZone, theProperty, defaultVal)\
    if not defaultVal then defaultVal = false end \
    if type(defaultVal) ~= \"boolean\" then \
        defaultVal = false \
    end\
\
    if not theZone then \
        trigger.action.outText(\"WARNING: NIL Zone in getBoolFromZoneProperty\", 30)\
        return defaultVal\
    end\
\
\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    if not p then return defaultVal end\
\
    -- make sure we compare so default always works when \
    -- answer isn't exactly the opposite\
    p = p:lower() \
    if defaultVal == false then \
        -- only go true if exact match to yes or true \
        theBool = false \
        theBool = (p == 'true') or (p == 'yes') or p == \"1\"\
        return theBool\
    end\
    \
    local theBool = true \
    -- only go false if exactly no or false or \"0\"\
    theBool = (p ~= 'false') and (p ~= 'no') and (p ~= \"0\") \
    return theBool\
end\
\
function cfxZones.getCoalitionFromZoneProperty(theZone, theProperty, default)\
    if not default then default = 0 end\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    if not p then return default end  \
    if type(p) == \"number\" then -- can't currently really happen\
        if p == 1 then return 1 end \
        if p == 2 then return 2 end \
        return 0\
    end\
    \
    if type(p) == \"string\" then \
        if p == \"1\" then return 1 end \
        if p == \"2\" then return 2 end \
        if p == \"0\" then return 0 end \
        \
        p = p:lower()\
        \
        if p == \"red\" then return 1 end \
        if p == \"blue\" then return 2 end \
        if p == \"neutral\" then return 0 end\
        if p == \"all\" then return 0 end \
        return default \
    end\
    \
    return default \
end\
\
function cfxZones.getNumberFromZoneProperty(theZone, theProperty, default)\
--TODO: trim string \
    if not default then default = 0 end\
    local p = cfxZones.getZoneProperty(theZone, theProperty)\
    p = tonumber(p)\
    if not p then return default else return p end\
end\
\
function cfxZones.getVectorFromZoneProperty(theZone, theProperty, minDims, defaultVal)\
    if not minDims then minDims = 0 end \
    if not defaultVal then defaultVal = 0 end \
    local s = cfxZones.getStringFromZoneProperty(theZone, theProperty, \"\")\
    local sVec = dcsCommon.splitString(s, \",\")\
    local nVec = {}\
    for idx, numString in pairs (sVec) do \
        local n = tonumber(numString)\
        if not n then n = defaultVal end\
        table.insert(nVec, n)\
    end\
    -- make sure vector contains at least minDims values \
    while #nVec < minDims do \
        table.insert(nVec, defaultVal)\
    end\
    \
    return nVec \
end\
\
function cfxZones.getSmokeColorStringFromZoneProperty(theZone, theProperty, default) -- smoke as 'red', 'green', or 1..5\
    if not default then default = \"red\" end \
    local s = cfxZones.getStringFromZoneProperty(theZone, theProperty, default)\
    s = s:lower()\
    s = dcsCommon.trim(s)\
    -- check numbers \
    if (s == \"0\") then return \"green\" end\
    if (s == \"1\") then return \"red\" end\
    if (s == \"2\") then return \"white\" end\
    if (s == \"3\") then return \"orange\" end\
    if (s == \"4\") then return \"blue\" end\
    \
    if s == \"green\" or\
       s == \"red\" or\
       s == \"white\" or\
       s == \"orange\" or\
       s == \"blue\" then return s end\
\
    return default \
end\
\
--\
-- Moving Zones. They contain a link to their unit\
-- they are always located at an offset (x,z) or delta, phi \
-- to their master unit. delta phi allows adjustment for heading\
-- The cool thing about moving zones in cfx is that they do not\
-- require special handling, they are always updated \
-- and work with 'pointinzone' etc automatically\
\
-- Always works on cfx Zones, NEVER on DCS zones.\
--\
-- requires that readFromDCS has been done\
--\
function cfxZones.getPoint(aZone) -- always works, even linked, point can be reused \
    if aZone.linkedUnit then \
        local theUnit = aZone.linkedUnit\
        -- has a link. is link existing?\
        if theUnit:isExist() then \
            -- updates zone position \
            cfxZones.centerZoneOnUnit(aZone, theUnit)\
            cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)\
        end\
    end\
    local thePos = {}\
    thePos.x = aZone.point.x\
    thePos.y = 0 -- aZone.y \
    thePos.z = aZone.point.z\
    -- since we are at it, update the zone as well\
    aZone.point = thePos \
    return thePos \
end\
\
function cfxZones.linkUnitToZone(theUnit, theZone, dx, dy) -- note: dy is really Z, don't get confused!!!!\
    theZone.linkedUnit = theUnit\
    if not dx then dx = 0 end\
    if not dy then dy = 0 end \
    theZone.dx = dx\
    theZone.dy = dy \
end\
\
function cfxZones.updateMovingZones()\
    cfxZones.updateSchedule = timer.scheduleFunction(cfxZones.updateMovingZones, {}, timer.getTime() + 1/cfxZones.ups)\
    -- simply scan all cfx zones for the linkedUnit property and if there\
    -- update the zone's points\
    for aName,aZone in pairs(cfxZones.zones) do\
        if aZone.linkedUnit then \
            local theUnit = aZone.linkedUnit\
            -- has a link. is link existing?\
            if theUnit:isExist() then \
                cfxZones.centerZoneOnUnit(aZone, theUnit)\
                cfxZones.offsetZone(aZone, aZone.dx, aZone.dy)\
                --trigger.action.outText(\"cf/x zones update \" .. aZone.name, 30)\
            end\
        end\
    end\
end\
\
function cfxZones.startMovingZones()\
    -- read all zoness, and look for a property called 'linkedUnit'\
    -- which will make them a linked zone if there is a unit that exists\
    for aName,aZone in pairs(cfxZones.zones) do\
        local lU = cfxZones.getZoneProperty(aZone, \"linkedUnit\")\
        if lU then \
            -- this zone is linked to a unit\
            theUnit = Unit.getByName(lU)\
            local useOffset = cfxZones.getBoolFromZoneProperty(aZone, \"useOffset\", false)\
            if useOffset then aZone.useOffset = true end\
            if theUnit then\
                local dx = 0\
                local dz = 0\
                if useOffset then \
                    local delta = dcsCommon.vSub(aZone.point,theUnit:getPoint()) -- delta = B - A \
                    dx = delta.x \
                    dz = delta.z\
                end\
                cfxZones.linkUnitToZone(theUnit, aZone, dx, dz)\
                --trigger.action.outText(\"cf/x zones: linked \" .. aZone.name .. \" to \" .. theUnit:getName(), 30)\
                if useOffset then \
                    --trigger.action.outText(\"and dx = \" .. dx .. \" dz = \" .. dz, 30)\
                end\
            end\
 \
        end\
    end\
end\
\
--\
-- init\
--\
\
function cfxZones.init()\
    -- read all zones into my own db\
    cfxZones.readFromDCS(true) -- true: erase old\
    \
    -- now, pre-read zone owner for all zones\
    -- note, all zones with this property are by definition owned zones.\
    -- and hence will be read anyway. this will merely ensure that the \
    -- ownership is established right away\
    -- unless owned zones module is missing, in which case \
    -- ownership is still established \
    local pZones = cfxZones.zonesWithProperty(\"owner\")\
    for n, aZone in pairs(pZones) do\
        aZone.owner = cfxZones.getCoalitionFromZoneProperty(aZone, \"owner\", 0)\
    end\
        \
    \
    -- now initialize moving zones\
    cfxZones.startMovingZones()\
    cfxZones.updateMovingZones() -- will auto-repeat\
    \
    trigger.action.outText(\"cf/x Zones v\".. cfxZones.version .. \": loaded\", 10)\
end\
\
-- get everything rolling\
cfxZones.init()\
",
                    ["predicate"] = "a_do_script",
                }, -- end of [2]
                [3] = 
                {
                    ["text"] = "-- cfx player handler for DCS Missions by cf/x AG\
-- \
-- a module that provides easy access to a mission's player data\
-- multi-player only\
--\
\
cfxPlayer = {}\
                           -- a call to cfxPlayer.start()\
cfxPlayer.version = \"3.0.1\"\
--[[-- VERSION HISTORY\
\
- 2.2.3 - fixed isPlayerUnit() wrong return of true instead of nil\
- 2.2.4 - getFirstGroupPlayer\
- 2.3.0 - added event filtering for monitors\
        - limited code clean-up\
        - removed XXXmatchUnitToPlayer\
        - corrected isPlayerUnit once more\
        - removed autostart option\
        - removed detectPlayersLeaving option \
- 3.0.0 - added detection of network players \
        - added new events newPlayer, changePlayer \
        - and leavePlayer (never called)\
- 3.0.1 - isPlayerUnit guard against scenery object or map object \
--]]--\
\
cfxPlayer.verbose = false;\
cfxPlayer.running = false \
cfxPlayer.ups = 1 -- updates per second: how often do we query the players \
                  -- a good value is 1\
cfxPlayer.playerDB = {} -- the list of all player UNITS\
        -- attributes\
            -- name - name of unit occupied by player\
            -- unit - unit this player is controlling\
            -- unitName - same as name\
            -- group - group this unit belongs to. can't change without also changing unit\
            -- groupName - name of group\
            -- coalition\
cfxPlayerGroups = {} -- GLOBAL VAR \
-- list of all current groups that have players in them \
-- can call out to handlers if group is added or removed\
-- use this in MP games to organise messaging and keep score\
-- by default, groupinfo merely contains the .group reference \
-- and is accessed by name as key which is also accessible by .name\
            \
cfxPlayer.netPlayers = {} -- new for version 3: real player detection\
-- a dict sorted by player name that containts the unit name for last pass \
\
cfxPlayer.updateSchedule = 0 -- ID used for scheduling update\
cfxPlayer.coalitionSides = {0, 1, 2} -- we currently have neutral, red, blue\
\
cfxPlayer.monitors = {} -- callbacks for events\
\
---\
-- structure of playerInfo\
--   - name - player's unit name\
--   - unit - the unit the player is occupying. Multi-Crew: many people can be in same unit\
--   - unitName same as name \
\
--   - coalition - the side the unit is on, as a number \
function cfxPlayer.dumpRawPlayers()\
    trigger.action.outText(\"+++ debug: raw player dump ---\", 30)\
    for i=1, #cfxPlayer.coalitionSides do \
        local theSide = cfxPlayer.coalitionSides[i] \
        -- get all players for this side\
        local thePlayers = coalition.getPlayers(theSide) \
        for p=1, #thePlayers do \
            aPlayerUnit = thePlayers[p] -- docs say this is a unit table, not a person table!\
            trigger.action.outText(i .. \"-\" .. p ..\": unit: \" .. aPlayerUnit:getName() .. \" controlled by \" .. aPlayerUnit:getPlayerName() , 30)\
        end\
    end\
    trigger.action.outText(\"+++ debug: END DUMP ----\", 30)\
end\
\
\
function cfxPlayer.getAllPlayers()\
    return cfxPlayer.playerDB -- get entire db. make sure not to screw around with it\
end\
\
\
function cfxPlayer.getPlayerInfoByName(theUnitName) -- note: UNIT name\
    thePlayer = cfxPlayer.playerDB[theUnitName] -- access the entry, not we are accessing by unit name\
    return thePlayer\
end\
\
function cfxPlayer.getPlayerInfoByIndex(theIndex) \
    local enumeratedInfo = dcsCommon.enumerateTable(cfxPlayer.playerDB)\
    if (theIndex > #enumeratedInfo) then\
        trigger.action.outText(\"WARNING: player index \" .. theIndex .. \" out of bounds - max = \" .. #enumeratedInfo, 30)\
        return nil end\
    if (theIndex < 1) then return nil end\
    \
    return enumeratedInfo[theIndex]\
end\
\
-- this is now a true/false function that returns true if unit is player \
function cfxPlayer.XXXmatchUnitToPlayer(theUnit) -- what's difference to getPlayerInfo? GetPlayerInfo ALLOCATES if not exists \
\
    if not (theUnit) then return false end\
    if not (theUnit:isExist()) then return false end \
    \
    -- PATCH: if theUnit:getPlayerName() returns anything but nil\
    -- this is a player unit\
    -- unfortunately, this can sometimes fail\
    -- so make sure the function existst\
    -- it failed because the next level up function \
    -- returned true if i returned anything but nil, and I return \
    -- true or false, both not nil \
    -- this proc works \
    if not theUnit.getPlayerName then return false end \
    \
    local pName = theUnit:getPlayerName()\
    if pName ~= nil then \
        -- trigger.action.outText(\"+++matchUnit: player name \" .. pName .. \" for unit \" .. theUnit:getName(), 30)\
        return true \
    end \
    \
    if (true) then \
        return false\
    end \
    \
    -- ignmore old code below\
\
    for pname, pInfo in pairs(cfxPlayer.playerDB) do \
        if (pInfo.unit == theUnit) then \
            return pInfo\
        end\
    end\
    return nil\
end\
\
function cfxPlayer.XXXisPlayerUnitAlt(theUnit)\
    for pname, pInfo in pairs(cfxPlayer.playerDB) do \
        if (pInfo.unit == theUnit) then \
            return true\
        end\
    end\
    return false\
end\
\
function cfxPlayer.isPlayerUnit(theUnit)\
    -- new patch. simply check if getPlayerName returns something\
    if not theUnit then return false end \
    if not theUnit.getPlayerName then return false end -- map/static object \
    local pName = theUnit:getPlayerName()\
    if pName then return true end \
    return false \
    --\
    -- fixed, erroneously expected a nil from matchUnitToPlayer \
    --return (cfxPlayer.matchUnitToPlayer(theUnit)) -- was: ~=nil, wrong because match returns true/false\
end\
\
\
\
function cfxPlayer.getPlayerUnitType(thePlayerInfo) -- \
    if (thePlayerInfo) then \
        theUnit = thePlayerInfo.unit\
        if (theUnit) and (theUnit:isExist()) then \
            return theUnit:getTypeName()\
        end\
    end\
    return nil \
end\
\
\
-- get player's unit info\
-- accesses player DB and returns the player's info record for the\
-- player's Unit. If record does not exist in db, a new record is allocated\
-- returns true if verification succeeeds: player unit existed before, and\
-- false otherwise. in the latter case, A NEW playerInfo object is returned\
function cfxPlayer.getPlayerInfo(theUnit)\
    local playerName = theUnit:getPlayerName() -- retrieve the name \
    --- PATCH!!!!!!!\
    --- on multi-crew, we only have the pilot as getPlayerName. \
    --- we now switch to the unit's name instead \
    playerName = theUnit:getName() \
    \
    -- trigger.action.outText(\"Player: \".. playerName, 10)\
\
    local existingPlayer = cfxPlayer.getPlayerInfoByName(playerName) -- try and access DB\
    if existingPlayer then\
        -- this player exists in the db. return the record\
        return true, existingPlayer;\
\
    else\
        -- this is a new player.\
        -- set up a new playerinfo record for this name\
        local newPlayerInfo = {}\
        newPlayerInfo.name = playerName\
        newPlayerInfo.unit = theUnit\
        newPlayerInfo.unitName = theUnit:getName()\
        newPlayerInfo.group = theUnit:getGroup()\
        newPlayerInfo.groupName = newPlayerInfo.group:getName()\
        newPlayerInfo.coalition = theUnit:getCoalition() -- seems to work when first param is class self\
        -- note that this record did not exist, and return record\
        return false, newPlayerInfo\
    end\
    \
end;\
\
function cfxPlayer.getSinglePlayerAirframe()\
    -- ALWAYS return a string! This is for debugging purposes\
    local thePlayers = {}\
    local count = 0\
    local theAirframe = \"(none)\"\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do \
        count = count + 1\
        theAirframe = pinfo.unit:getTypeName()\
    end\
    if count < 2 then return theAirframe end -- also returns if count == 0\
    return \"<Multiplayer Not Yet Supported>\"\
end\
\
function cfxPlayer.getAnyPlayerAirframe()\
    -- use this for debugging, in single-player missions, or where it \
    -- is unimportant which player, just a player\
    -- assumes that all players use the same airframe or are in the \
    -- same group / unit \
    for pname, pinfo in pairs(cfxPlayer.playerDB) do \
        if (pinfo.unit:isExist()) then \
            -- player may just have crashed or left\
            local theAirframe = pinfo.unit:getTypeName()\
            return theAirframe -- we simply stop after first successfuly access\
        end\
    end\
    return \"error: no player\"\
end\
\
function cfxPlayer.getFirstGroupPlayerName(theGroup)\
 -- get the name of player of the first \
 -- player-controlled unit I come across in \
 -- this group \
    local allGroupUnits = theGroup:getUnits()\
    for ukey, uvalue in pairs(allGroupUnits) do \
        -- iterate units in group\
        if (uvalue:isExist())  then -- and cfxPlayer.isPlayerUnit(uvalue)) \
            -- player may just have crashed or left\
            -- but all units in the same group have the same type when they are aircraft\
            if cfxPlayer.isPlayerUnit(uvalue) then \
                return uvalue:getPlayerName(), uvalue \
            end\
        end\
    end\
    return nil \
end\
\
function cfxPlayer.getAnyGroupPlayerAirframe(theGroup)\
    -- get the first player-driven unit in the group\
    -- and pass back the airframe that is being used \
    local allGroupUnits = theGroup:getUnits()\
    for ukey, uvalue in pairs(allGroupUnits) do \
        \
        if (uvalue:isExist())  then -- and cfxPlayer.isPlayerUnit(uvalue)) \
            -- player may just have crashed or left\
            -- but all units in the same group have the same type when they are aircraft\
            local theAirframe = uvalue:getTypeName()\
            return theAirframe -- we simply stop after first successfuly access\
        end\
    end\
    return \"error: no live player in group \"\
end\
\
\
\
function cfxPlayer.getAnyPlayerPosition()\
    -- use this for debugging, in single-player missions, or where it \
    -- is unimportant which player, just a player\
    -- will cause issues when you derive location info or group info \
    -- from that player\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do\
        if (pinfo.unit:isExist()) then \
            local thePoint = pinfo.unit:getPoint()\
            return thePoint -- we simply stop after first successfuly access\
        end\
    end\
    return nil\
end\
\
function cfxPlayer.getAnyGroupPlayerPosition(theGroup)\
    -- enter with dcs group to search for player units within\
    -- step one: get all units that belong to that group\
    local allGroupUnits = theGroup:getUnits()\
    -- we now iterate all returned units and look for \
    -- a unit that is a player unit.\
    for ukey, uvalue in pairs(allGroupUnits) do \
        -- we currently assume single-unit groups for players\
        if (uvalue:isExist()) then -- and cfxPlayer.isPlayerUnit(uvalue))\
            -- player may just have crashed or left\
            local thePoint = uvalue:getPoint()\
            return thePoint -- we simply stop after first successfuly access\
        end\
    \
    end\
    return nil\
end\
\
function cfxPlayer.getAnyGroupPlayerInfo(theGroup)\
    for pname, pinfo in pairs(cfxPlayer.playerDB) do \
        if (pinfo.unit:isExist() and pinfo.group == theGroup) then \
            return pinfo -- we simply stop after first successfuly access\
        end\
    end\
    return \"error: no player\"\
end\
\
\
function cfxPlayer.getAllPlayerGroups()\
    -- merely accessot. better would be returning a copy \
    return cfxPlayerGroups    \
end\
\
function cfxPlayer.getGroupDataForGroupNamed(name)\
    if not name then return nil end \
    return cfxPlayerGroups[name]\
end\
\
function cfxPlayer.getPlayersInGroup(theGroup)\
    if not theGroup then return {} end\
    if not theGroup:isExist() then return {} end \
    local gName = theGroup:getName()\
    local thePlayers = {}\
    \
    for pname, pinfo in pairs(cfxPlayer.playerDB) do         \
        local pgName = \"\"\
        if pinfo.group:isExist() then pgName = pinfo.group:getName() end \
        if (gName == pgName) then \
            table.insert(thePlayers, pinfo)\
        end\
    end\
    return thePlayers\
end\
\
-- update() is called regularly to check up on the players\
-- when a mismatch to last player state is found, callbacks \
-- can be invoked\
\
function cfxPlayer.update()\
    \
    -- first, re-schedule my next invocation\
    cfxPlayer.updateSchedule = timer.scheduleFunction(cfxPlayer.update, {}, timer.getTime() + 1/cfxPlayer.ups)\
    \
    -- now scan the coalitions for all players\
    local currCount = 0 -- number of players found this pass\
    local currDB = {} -- db of player units this pass\
    local currPlayerUnitsByNames = {}    \
    -- iterate over all colaitions \
    for i=1, #cfxPlayer.coalitionSides do \
        local theSide = cfxPlayer.coalitionSides[i] \
        -- get all player units for this side\
        local thePlayers = coalition.getPlayers(theSide) -- returns UNITs!!!\
\
        for p=1, #thePlayers do \
            -- we now iterate the Units and compare what we find\
            local thePlayerUnit = thePlayers[p]\
            local isExistingPlayerUnit, theInfo = cfxPlayer.getPlayerInfo(thePlayerUnit)\
            \
            if (not isExistingPlayerUnit) then \
                -- add Unit (not player!) to db\
                cfxPlayer.playerDB [theInfo.name] = theInfo\
                cfxPlayer.invokeMonitorsForEvent(\"new\", \"Player Unit \" .. theInfo.name .. \" entered mission\", theInfo, {})\
\
            else\
                -- player's unit existed last time around\
                -- see if something changed:\
    \
-- currently, we track units, not players. side changes for units can't happen AT ALL \
                \
                if theInfo.coalition ~= thePlayerUnit:getCoalition() then    \
                    local theData = {}\
                    theData.old = theInfo.coalition\
                    theData.new = thePlayerUnit:getCoalition()\
\
                    -- we invoke a callback\
                    cfxPlayer.invokeMonitorsForEvent(\"side\", \"Player \" .. theInfo.name .. \" switched sides to \" .. thePlayerUnit:getCoalition(), theInfo, theData)\
\
                end;\
\
-- we now check if the player has changed groups\
-- sinced we track units, this CANT HAPPEN AT ALL \
\
                if theInfo.group ~= thePlayerUnit:getGroup() then \
                    local theData = {}\
                    theData.old = theInfo.group\
                    theData.new = thePlayerUnit:getGroup()\
                    cfxPlayer.invokeMonitorsForEvent(\"group\", \"Player changed group to \" .. thePlayerUnit:getGroup():getName(), theInfo, theData)\
                    trigger.action.outText(\"+++ debug: Player \" .. theInfo.name .. \" changed GROUP to: \" .. thePlayerUnit:getGroup():getName(), 30)\
                end\
\
                -- we should now check if the player has changed units\
-- since we track units, this cant happen at all\
                if theInfo.unit ~= thePlayerUnit then\
                    -- player changed unit \
                    local theData = {}\
                    theData.old = theInfo.unit\
                    -- the old unit's name is still available in theInfo.unitName \
                    theData.oldUnitName = theInfo.unitName \
                    theData.new = thePlayerUnit\
                    -- update Player Info\
                    cfxPlayer.invokeMonitorsForEvent(\"unit\", \"Player changed unit to \" .. thePlayerUnit:getName(), theInfo, theData)\
                    \
                end\
                -- update the playerEntry. always done\
                theInfo.unit = thePlayerUnit\
                theInfo.unitName = thePlayerUnit:getName()\
                theInfo.coalition = thePlayerUnit:getCoalition()\
                theInfo.group = thePlayerUnit:getGroup()        \
            end;\
            \
            -- add this entry to current pass db so we can detect\
            -- any discrepancies to last pass\
            currDB[theInfo.name] = theInfo \
            \
            -- now update current network player name db\
            local playerUnitName = thePlayerUnit:getName()\
            if not thePlayerUnit:isExist() then playerUnitName = \"<none>\" end \
            currPlayerUnitsByNames[thePlayerUnit:getPlayerName()] = playerUnitName\
        end -- for all player units of this side\
    end -- for all sides\
    \
    -- we can now check if a player unit has disappeared    \
    -- we do this by checking that all old entries from cfxPlayer.playerDB\
    -- have an existing counterpart in new currDB\
    for name, info in pairs(cfxPlayer.playerDB) do\
        local matchingEntry = currDB[name]\
        if matchingEntry then \
            -- allright nothing to do\
        else\
            -- whoa, this record is missing!\
            -- do we care?\
            if true then -- (cfxPlayer.detectPlayersLeaving) then\
                -- yes! trigger an event\
                cfxPlayer.invokeMonitorsForEvent(\"leave\", \"Player left mission\", info, {})\
                -- we don't need to destroy entry, as we simply replace the\
                -- playerDB with currDB at end of update\
            else \
                -- no, just copy old data over. They'll be back\
                currDB[name] = info\
            end\
        end \
    end;\
    \
    -- we now perform a group check and update all groups for players \
    local currPlayerGroups = {}\
    for pName, pInfo in pairs(currDB) do \
        -- retrieve player unit and make sure it still exists\
        local theUnit = pInfo.unit\
        if theUnit:isExist() then \
            -- yeah, it exists allright. let's get to the group\
            local theGroup = theUnit:getGroup()\
            local gName = theGroup:getName()\
            -- see if this group is new\
            local thePGroup = cfxPlayerGroups[gName]\
            if not thePGroup then \
                -- allocate new group\
                thePGroup = {}\
                thePGroup.group = theGroup\
                thePGroup.name = gName \
                thePGroup.primeUnit = theUnit -- may be used as fallback\
                thePGroup.primeUnitName = theUnit:getName() -- also fallback only\
                thePGroup.id = theGroup:getID()\
                cfxPlayer.invokeMonitorsForEvent(\"newGroup\", \"New Player Group \" .. gName .. \" appeared\", nil, thePGroup)\
            end\
            currPlayerGroups[gName] = thePGroup -- update group table\
        end\
    end\
\
    -- now check if a player group has disappeared\
    for gkey, gval in pairs(cfxPlayerGroups) do \
        if not currPlayerGroups[gkey] then \
            cfxPlayer.invokeMonitorsForEvent(\"removeGroup\", \"A Player Group \" .. gkey .. \" vanished\", nil, gval) -- gval is OLD set, contains group \
        end\
    end\
    \
    -- version 3 addion: track network players\
    -- see if a new player has appeared \
    for aPlayerName, aPlayerUnitName in pairs(currPlayerUnitsByNames) do \
        -- see if this name was already in last \
        if cfxPlayer.netPlayers[aPlayerName] then \
            -- yes. but was it the same unit?\
            if cfxPlayer.netPlayers[aPlayerName] == currPlayerUnitsByNames[aPlayerName] then \
                -- all is well, no change \
            else \
                -- player has changed units \
                -- since they can't disappear, \
                -- this event can happen \
                local data = {}\
                data.oldUnitName = cfxPlayer.netPlayers[aPlayerName]\
                data.newUnitName = aPlayerUnitName\
                data.playerName = aPlayerName\
                if aPlayerUnitName == \"\" then aPlayerUnitName = \"<none>\" end \
                if aPlayerUnitName == \"<none>\" then \
                    -- unit no longer exists, player probably dead,\
                    -- parachuting or spectating. Maybe even left game\
                    -- resgisters as 'change' -- is 'left unit'\
                    cfxPlayer.invokeMonitorsForEvent(\"changePlayer\", \"A Player left unit \" .. data.oldUnitName, nil, data)\
                else \
                    -- changed to new unit\
                    cfxPlayer.invokeMonitorsForEvent(\"changePlayer\", \"A Player changed to unit \" .. aPlayerUnitName, nil, data)\
                end \
            end\
        else \
            -- this is a new player\
            local data = {}\
            data.playerName = aPlayerName\
            data.newUnitName = aPlayerUnitName\
            cfxPlayer.invokeMonitorsForEvent(\"newPlayer\", \"New Player appeared \" .. aPlayerName .. \" in unit \" .. aPlayerUnitName, nil, data)\
        end\
    end\
\
    -- version 3: detect if a player left \
    for oldPlayerName, oldUnitName in pairs(cfxPlayer.netPlayers) do \
        if not currPlayerUnitsByNames[oldPlayerName] then \
            --local data = {}\
            --data.playerName = oldPlayerName\
            --data.oldUnitName = oldUnitName\
            --cfxPlayer.invokeMonitorsForEvent(\"leavePlayer\", \"Player \" .. oldPlayerName .. \" disappeared from unit \" .. oldUnitName, nil, data)\
            --\
            -- we keep the player in the db by copying \
            -- it over and set the unit name to \"\"\
            -- will cause at least once 'change' event later \
            -- probably two in MP\
            currPlayerUnitsByNames[oldPlayerName] = \"<none>\"\
        end\
    end\
    \
    -- update playerGroups for this cycle\
    cfxPlayerGroups = currPlayerGroups\
    \
    -- update network player for this c<cle \
    cfxPlayer.netPlayers = currPlayerUnitsByNames\
    \
    -- finally, we simply replace the old db with the new one\
    cfxPlayer.playerDB = currDB;\
end\
\
function cfxPlayer.getAllNetPlayerNames ()\
    local themAll = {}\
    for aName, aUnitName in cfxPlayer.netPlayers do \
        table.insert(themAll, aName)\
    end\
    return themAll\
end\
\
function cfxPlayer.getPlayerUnitName(aPlayerName) \
    if not aPlayerName then return nil end \
    return cfxPlayer.netPlayers[aPlayerName]\
end\
\
function cfxPlayer.isPlayerSeated(aPlayerName)\
    local unitName = cfxPlayer.getPlayerUnitName(aPlayerName)\
    if not unitName then return false end \
    if unitName == \"\" or unitName == \"<none>\" then return false end \
    return true \
end\
\
-- add a monitor to be notified of player events\
-- may provide a whitelist of events as array of strings\
function cfxPlayer.addMonitor(callback, events)\
    local newMonitor = {}\
    newMonitor.callback = callback\
    newMonitor.events = events \
    cfxPlayer.monitors[callback] = newMonitor\
end;\
\
function cfxPlayer.removeMonitor(callback) \
    if (cfxMonitos[callback]) then \
        cfxMonitos[callback] = nil \
    end\
end\
\
function cfxPlayer.invokeMonitorsForEvent(evType, description, player, data)\
    for callback, monitor in pairs(cfxPlayer.monitors) do\
        -- should filter if evType is in monitor.events\
        if monitor.events and #monitor.events > 0 then \
            -- only invoke if this event is listed\
            if dcsCommon.arrayContainsString(monitor.events, evType) then \
                monitor.callback(evType, description, player, data)\
            end\
        else \
            monitor.callback(evType, description, player, data)\
        end\
    end\
end\
\
function cfxPlayer.getAllExistingPlayerUnitsRaw()\
    local apu = {}\
    for i=1, #cfxPlayer.coalitionSides do \
        local theSide = cfxPlayer.coalitionSides[i] \
        -- get all players for this side\
        local thePlayers = coalition.getPlayers(theSide) \
        for p=1, #thePlayers do \
            local aUnit = thePlayers[p]\
            if aUnit and aUnit:isExist() then \
                table.insert(apu, aUnit)\
            end\
        end\
    end\
    return apu \
end\
\
-- evType that can actually happen are 'new', 'leave' for units,\
-- 'newGroup' and 'removeGroup' for groups     \
function cfxPlayer.defaultMonitor(evType, description, info, data)\
    if cfxPlayer.verbose then\
        trigger.action.outText(\"+++Plr - evt '\".. evType ..\"': <\" .. description .. \">\", 30)\
        if (info) then \
            trigger.action.outText(\"+++Plr: for unit named: \" .. info.name, 30) \
        else \
            --trigger.action.outText(\"+++Plr: no player data\", 30)\
        end\
        --trigger.action.outText(\"+++Plr: desc: '\".. evType ..\"'<\" .. description .. \">\", 30)\
        -- we ignore the data block\
    end\
end\
\
function cfxPlayer.start()\
    trigger.action.outText(\"cf/x player v\".. cfxPlayer.version .. \": started\", 10)\
    cfxPlayer.running = true\
    cfxPlayer.update()    \
end\
\
function cfxPlayer.stop()\
    if cfxPlayer.verbose then \
        trigger.action.outText(\"cf/x player v\".. cfxPlayer.version .. \": stopped\", 10)\
    end\
    timer.removeFunction(cfxPlayer.updateSchedule) -- will require another start() to resume\
    cfxPlayer.running = false\
end\
\
function cfxPlayer.init()\
    trigger.action.outText(\"cf/x player v\".. cfxPlayer.version .. \": loaded\", 10)\
    -- when verbose, we also add a monitor to display player event\
    if cfxPlayer.verbose then \
        cfxPlayer.addMonitor(cfxPlayer.defaultMonitor, {})\
        trigger.action.outText(\"cf/x player isd verbose\", 10)\
    end\
    \
    cfxPlayer.start()\
end\
\
-- get everything rolling, but will only start if autostart is true\
cfxPlayer.init()\
\
--TODO: player status: ground, air, dead, none \
-- TODO: event when status changes ground/air/...",
                    ["predicate"] = "a_do_script",
                }, -- end of [3]
                [4] = 
                {
                    ["text"] = "cfxGroups = {}\
cfxGroups.version = \"1.1.0\"\
--[[--\
\
Module to read Unit data from DCS and make it available to scripts\
DOES NOT KEEP TRACK OF MISSION-CREATED GROUPS!!!!\
Main use is to access player groups for slot blocking etc since these \
groups can't be allocated dynamically\
\
Version history\
\
 1.0.0 - initial version\
 1.1.0 - for each player unit, store point(x, 0, y), and action for first WP, as well as name \
 \
--]]--\
\
cfxGroups.groups = {} -- all groups, indexed by name \
\
--[[-- group objects are \
    {\
        name= \"\", \
        coalition = \"\" (red, blue, neutral), \
        coanum = # (0, 1, 2 for neutral, red, blue)\
        category = \"\" (helicopter, ship, plane, vehicle, static),\
        hasPlayer = true/false,\
        playerUnits = {} (for each player unit in group: name, point, action)\
        \
    }\
    \
--]]--\
\
function cfxGroups.fetchAllGroupsFromDCS()\
    -- a mission is a lua table that is loaded by executing the miz. it builds\
    -- the environment mission table, accessible as env.mission \
    -- iterate the \"coalition\" table of the mission (note: NOT coalitionS)\
    -- inspired by mist, GIANT tip o'the hat to Grimes!    \
    \
    for coa_name_miz, coa_data in pairs(env.mission.coalition) do -- iterate all coalitions\
        local coa_name = coa_name_miz\
        if string.lower(coa_name_miz) == 'neutrals' then -- convert \"neutrals\" to \"neutral\", singular\
            coa_name = 'neutral'\
        end\
        -- directly convert coalition into number for easier access later\
        local coaNum = 0\
        if coa_name == \"red\" then coaNum = 1 end \
        if coa_name == \"blue\" then coaNum = 2 end \
        \
        if type(coa_data) == 'table' then\
            if coa_data.country then -- make sure there a country table for this coalition\
                for cntry_id, cntry_data in pairs(coa_data.country) do -- iterate all countries for this \
                    local countryName = string.lower(cntry_data.name)\
                    if type(cntry_data) == 'table' then    --just making sure\
                        for obj_type_name, obj_type_data in pairs(cntry_data) do\
                            if obj_type_name == \"helicopter\" or obj_type_name == \"ship\" or obj_type_name == \"plane\" or obj_type_name == \"vehicle\" or obj_type_name == \"static\" then --should be an unncessary check\
                                local category = obj_type_name\
                                if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then    --there's a group!\
\
                                    for group_num, group_data in pairs(obj_type_data.group) do\
                                        if group_data and group_data.units and type(group_data.units) == 'table' then    --making sure again- this is a valid group\
                                            local groupName = group_data.name\
                                            if env.mission.version > 7 then -- translate raw to actual \
                                                groupName = env.getValueDictByKey(groupName)\
                                            end\
                                            local hasPlayer = false \
                                            local playerUnits = {}\
                                            for unit_num, unit_data in pairs(group_data.units) do -- iterate units\
                                                -- see if there is at least one player in group \
                                                if unit_data.skill then \
                                                    if unit_data.skill == \"Client\" or  unit_data.skill == \"Player\" then\
                                                        -- this is player unit. save it, remember\
                                                        hasPlayer = true \
                                                        local playerData = {}\
                                                        playerData.name = unit_data.name\
                                                        playerData.point = {}\
                                                        playerData.point.x = unit_data.x\
                                                        playerData.point.y = 0\
                                                        playerData.point.z = unit_data.y\
                                                        playerData.action = \"none\" -- default \
                                                        \
                                                        -- access initial waypoint data by 'reaching up'\
                                                        -- into group data and extract route.points[1]\
                                                        if group_data.route and group_data.route.points and (#group_data.route.points > 0) then \
                                                            playerData.action = group_data.route.points[1].action\
                                                        end\
                                                        table.insert(playerUnits, playerData)\
                                                    end                                                        \
                                                end\
                                            end --for all units in group\
                        \
                                            local entry = {}\
                                            entry.name = groupName\
                                            entry.coalition = coa_name\
                                            entry.coaNum = coaNum \
                                            entry.category  = category\
                                            entry.hasPlayer = hasPlayer \
                                            entry.playerUnits = playerUnits\
                                            -- add to db\
                                            cfxGroups.groups[groupName] = entry\
                                            \
                                        end --if has group_data and group_data.units then\
                                    end --for all groups in category \
                                end --if has category data \
                            end --if plane, helo etc... category\
                        end --for all objects in country \
                    end --if has country data \
                end --for all countries in coalition\
            end --if coalition has country table \
        end -- if there is coalition data  \
    end --for all coalitions in mission \
end\
\
-- simply dump all groups to the screen\
function cfxGroups.showAllGroups()\
    for gName, gData in pairs (cfxGroups.groups) do \
        local isP = \"(NPC)\"\
        if gData.hasPlayer then isP = \"*PLAYER GROUP (\".. #gData.playerUnits ..\")*\" end\
        trigger.action.outText(gData.name.. \": \" .. isP .. \" - \" .. gData.category .. \", F:\" .. gData.coalition\
        .. \" (\" .. gData.coaNum .. \")\", 30)\
    end\
end\
\
-- return all cfxGroups that can have players in them\
-- includes groups that currently are not or not anymore alive\
function cfxGroups.getPlayerGroup()\
    local playerGroups = {}\
    for gName, gData in pairs (cfxGroups.groups) do \
        if gData.hasPlayer then\
            table.insert(playerGroups, gData)\
        end\
    end\
    return playerGroups \
end\
\
-- return all group names that can have players in them\
-- includes groups that currently are not or not anymore alive\
function cfxGroups.getPlayerGroupNames()\
    local playerGroups = {}\
    for gName, gData in pairs (cfxGroups.groups) do \
        if gData.hasPlayer then\
            table.insert(playerGroups, gName)\
        end\
    end\
    return playerGroups \
end\
\
\
function cfxGroups.start()\
    cfxGroups.fetchAllGroupsFromDCS() -- read all groups from mission. \
--    cfxGroups.showAllGroups()\
    \
    trigger.action.outText(\"cfxGroups version \" .. cfxGroups.version .. \" started\", 30)\
    return true \
    \
end\
\
cfxGroups.start() \
\
 ",
                    ["predicate"] = "a_do_script",
                }, -- end of [4]
                [5] = 
                {
                    ["text"] = "cfxMX = {}\
cfxMX.version = \"1.1.0\"\
--[[--\
 Mission data decoder. Access to ME-built mission structures\
 \
 Copyright (c) 2022 by Christian Franz and cf/x AG\
 \
 Version History\
   1.0.0 - initial version \
   1.0.1 - getStaticFromDCSbyName()\
   1.1.0 - getStaticFromDCSbyName also copies groupID when not fetching orig\
         - on start up collects a cross reference table of all \
           original group id \
         - add linkUnit for statics \
   \
 \
--]]--\
cfxMX.groupNamesByID = {}\
cfxMX.groupIDbyName = {}\
cfxMX.groupDataByName = {}\
\
\
function cfxMX.getGroupFromDCSbyName(aName, fetchOriginal)\
    if not fetchOriginal then fetchOriginal = false end \
    -- fetch the group description for goup named aName (if exists)\
    -- returned structure must be parsed for useful information \
    -- returns data, category, countyID and coalitionID \
    -- unless fetchOriginal is true, creates a deep clone of \
    -- group data structure \
        \
    for coa_name_miz, coa_data in pairs(env.mission.coalition) do -- iterate all coalitions\
        local coa_name = coa_name_miz\
        if string.lower(coa_name_miz) == 'neutrals' then -- remove 's' at neutralS\
            coa_name = 'neutral'\
        end\
        -- directly convert coalition into number for easier access later\
        local coaNum = 0\
        if coa_name == \"red\" then coaNum = 1 end \
        if coa_name == \"blue\" then coaNum = 2 end \
        \
        if type(coa_data) == 'table' then -- coalition = {bullseye, nav_points, name, county}, \
                                          -- with county being an array \
            if coa_data.country then -- make sure there a country table for this coalition\
                for cntry_id, cntry_data in pairs(coa_data.country) do -- iterate all countries for this \
                    -- per country = {id, name, vehicle, helicopter, plane, ship, static}\
                    local countryName = string.lower(cntry_data.name)\
                    local countryID = cntry_data.id \
                    if type(cntry_data) == 'table' then    -- filter strings .id and .name \
                        for obj_type_name, obj_type_data in pairs(cntry_data) do\
                            if obj_type_name == \"helicopter\" or \
                               obj_type_name == \"ship\" or \
                               obj_type_name == \"plane\" or \
                               obj_type_name == \"vehicle\" or \
                               obj_type_name == \"static\" \
                            then -- (so it's not id or name)\
                                local category = obj_type_name\
                                if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then    --there's at least one group!\
                                    for group_num, group_data in pairs(obj_type_data.group) do\
                                        if group_data.name == aName then \
                                            local theGroup = group_data\
                                            -- usually we return a copy of this \
                                            if not fetchOriginal then \
                                                theGroup = dcsCommon.clone(group_data)\
                                            end\
                                            return theGroup, category, countryID  \
                                        end\
                                    end\
                                end --if has category data \
                            end --if plane, helo etc... category\
                        end --for all objects in country \
                    end --if has country data \
                end --for all countries in coalition\
            end --if coalition has country table \
        end -- if there is coalition data  \
    end --for all coalitions in mission \
    return nil, \"none\", \"none\"\
end\
\
function cfxMX.getStaticFromDCSbyName(aName, fetchOriginal)\
    if not fetchOriginal then fetchOriginal = false end \
    -- fetch the static description for static named aName (if exists)\
    -- returned structure must be parsed for useful information \
    -- returns data, category, countyID and parent group name \
    -- unless fetchOriginal is true, creates a deep clone of \
    -- static data structure \
        \
    for coa_name_miz, coa_data in pairs(env.mission.coalition) do -- iterate all coalitions\
        local coa_name = coa_name_miz\
        if string.lower(coa_name_miz) == 'neutrals' then -- remove 's' at neutralS\
            coa_name = 'neutral'\
        end\
        -- directly convert coalition into number for easier access later\
        local coaNum = 0\
        if coa_name == \"red\" then coaNum = 1 end \
        if coa_name == \"blue\" then coaNum = 2 end \
        \
        if type(coa_data) == 'table' then -- coalition = {bullseye, nav_points, name, county}, \
                                          -- with county being an array \
            if coa_data.country then -- make sure there a country table for this coalition\
                for cntry_id, cntry_data in pairs(coa_data.country) do -- iterate all countries for this \
                    -- per country = {id, name, vehicle, helicopter, plane, ship, static}\
                    local countryName = string.lower(cntry_data.name)\
                    local countryID = cntry_data.id \
                    if type(cntry_data) == 'table' then    -- filter strings .id and .name \
                        for obj_type_name, obj_type_data in pairs(cntry_data) do\
                            if obj_type_name == \"static\"\
--                               obj_type_name == \"helicopter\" or \
--                               obj_type_name == \"ship\" or \
--                               obj_type_name == \"plane\" or \
--                               obj_type_name == \"vehicle\" or \
--                               obj_type_name == \"static\" \
                            then -- (only look at statics)\
                                local category = obj_type_name\
                                if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then    --there's at least one static in group!\
                                    for group_num, group_data in pairs(obj_type_data.group) do\
                                        -- get linkUnit info if it exists\
                                        local linkUnit = nil \
                                        if group_data and group_data.route and group_data.route and group_data.route.points[1] then \
                                            linkUnit = group_data.route.points[1].linkUnit\
                                            if linkUnit then \
                                                --trigger.action.outText(\"MX: found missing link to \" .. linkUnit .. \" in \" .. group_data.name, 30)\
                                            end \
                                        end \
                                        \
                                        if group_data and group_data.units and type(group_data.units) == 'table' \
                                        then --make sure - again - that this is a valid group\
                                            for unit_num, unit_data in pairs(group_data.units) do -- iterate units\
                                                if unit_data.name == aName then \
                                                    local groupName = group_data.name\
                                                    local theStatic = unit_data\
                                                    if not fetchOriginal then \
                                                        theStatic = dcsCommon.clone(unit_data)\
                                                        -- copy group ID from group above\
                                                        theStatic.groupId = group_data.groupId  \
                                                        -- copy linked unit data \
                                                        theStatic.linkUnit = linkUnit\
                                                        \
                                                    end\
                                                    return theStatic, category, countryID, groupName  \
                                                \
                                                end -- if name match\
                                            end -- for all units \
                                        end -- has groups \
                                    \
                                    end -- is a static \
                                end --if has category data \
                            end --if plane, helo etc... category\
                        end --for all objects in country \
                    end --if has country data \
                end --for all countries in coalition\
            end --if coalition has country table \
        end -- if there is coalition data  \
    end --for all coalitions in mission \
    return nil, \"<none>\", \"<none>\", \"<no group name>\"\
end\
\
function cfxMX.createCrossReference()\
    for coa_name_miz, coa_data in pairs(env.mission.coalition) do -- iterate all coalitions\
        local coa_name = coa_name_miz\
        if string.lower(coa_name_miz) == 'neutrals' then -- remove 's' at neutralS\
            coa_name = 'neutral'\
        end\
        -- directly convert coalition into number for easier access later\
        local coaNum = 0\
        if coa_name == \"red\" then coaNum = 1 end \
        if coa_name == \"blue\" then coaNum = 2 end \
        \
        if type(coa_data) == 'table' then -- coalition = {bullseye, nav_points, name, county}, \
                                          -- with county being an array \
            if coa_data.country then -- make sure there a country table for this coalition\
                for cntry_id, cntry_data in pairs(coa_data.country) do -- iterate all countries for this \
                    -- per country = {id, name, vehicle, helicopter, plane, ship, static}\
                    local countryName = string.lower(cntry_data.name)\
                    local countryID = cntry_data.id \
                    if type(cntry_data) == 'table' then    -- filter strings .id and .name \
                        for obj_type_name, obj_type_data in pairs(cntry_data) do\
                            if obj_type_name == \"helicopter\" or \
                               obj_type_name == \"ship\" or \
                               obj_type_name == \"plane\" or \
                               obj_type_name == \"vehicle\" or \
                               obj_type_name == \"static\" \
                            then -- (so it's not id or name)\
                                local category = obj_type_name\
                                if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then    --there's at least one group!\
                                    for group_num, group_data in pairs(obj_type_data.group) do\
                                        local aName = group_data.name \
                                        local aID = group_data.groupId\
                                        cfxMX.groupNamesByID[aID] = aName\
                                        cfxMX.groupIDbyName[aName] = aID\
                                        cfxMX.groupDataByName[aName] = group_data\
                                    end\
                                end --if has category data \
                            end --if plane, helo etc... category\
                        end --for all objects in country \
                    end --if has country data \
                end --for all countries in coalition\
            end --if coalition has country table \
        end -- if there is coalition data  \
    end --for all coalitions in mission \
end\
\
function cfxMX.catText2ID(inText) \
    local outCat = 0 -- airplane \
    local c = inText:lower()\
    if c == \"helicopter\" then outCat = 1 end \
    if c == \"ship\" then outCat = 3 end \
    if c == \"plane\" then outCat = 0 end -- redundant \
    if c == \"vehicle\" then outCat = 2 end \
    if c == \"train\" then outCat = 4 end \
    if c == \"static\" then outCat = -1 end \
    return outCat\
end\
 \
function cfxMX.start()\
    cfxMX.createCrossReference()\
    trigger.action.outText(\"cfxMX: \"..#cfxMX.groupNamesByID .. \" groups processed successfully\", 30)\
end\
\
-- start \
cfxMX.start()\
\
",
                    ["predicate"] = "a_do_script",
                }, -- end of [5]
                [6] = 
                {
                    ["text"] = "raiseFlag = {}\
raiseFlag.version = \"1.0.1\"\
raiseFlag.verbose = false \
raiseFlag.requiredLibs = {\
    \"dcsCommon\", -- always\
    \"cfxZones\", -- Zones, of course \
}\
raiseFlag.flags = {} \
--[[--\
    Raise A Flag module -- (c) 2022 by Christian Franz and cf/x AG\
    \
    Version History\
    1.0.0 - initial release \
    1.0.1 - synonym \"raiseFlag!\"\
    \
--]]--\
function raiseFlag.addRaiseFlag(theZone)\
    table.insert(raiseFlag.flags, theZone)\
end\
\
function raiseFlag.getRaiseFlagByName(aName) \
    for idx, aZone in pairs(raiseFlag.flags) do \
        if aName == aZone.name then return aZone end \
    end\
    if raiseFlag.verbose then \
        trigger.action.outText(\"+++rFlg: no raiseFlag with name <\" .. aName ..\">\", 30)\
    end \
    \
    return nil \
end\
\
--\
-- read attributes\
--\
function raiseFlag.createRaiseFlagWithZone(theZone)\
    -- get flag from faiseFlag itself\
    if cfxZones.hasProperty(theZone, \"raiseFlag\") then\
        theZone.raiseFlag = cfxZones.getStringFromZoneProperty(theZone, \"raiseFlag\", \"<none>\") -- the flag to raise \
    else \
        theZone.raiseFlag = cfxZones.getStringFromZoneProperty(theZone, \"raiseFlag!\", \"<none>\") -- the flag to raise \
    end \
    \
    theZone.flagValue = cfxZones.getNumberFromZoneProperty(theZone, \"value\", 1) -- value to set to\
\
    theZone.minAfterTime, theZone.maxAfterTime = cfxZones.getPositiveRangeFromZoneProperty(theZone, \"afterTime\", -1)\
\
    if cfxZones.hasProperty(theZone, \"stopFlag?\") then \
        theZone.triggerStopFlag = cfxZones.getStringFromZoneProperty(theZone, \"stopFlag?\", \"none\")\
        theZone.lastTriggerStopValue = cfxZones.getFlagValue(theZone.triggerStopFlag, theZone) -- save last value\
    end\
    \
    theZone.scheduleID = nil \
    theZone.raiseStopped = false \
    \
    -- now simply schedule for invocation\
    local args = {}\
    args.theZone = theZone\
    if theZone.minAfterTime < 1 then \
        timer.scheduleFunction(raiseFlag.triggered, args, timer.getTime() + 0.5)\
    else\
        local delay = cfxZones.randomDelayFromPositiveRange(theZone.minAfterTime, theZone.maxAfterTime)        \
        timer.scheduleFunction(raiseFlag.triggered, args, timer.getTime() + delay)\
    end\
end\
\
function raiseFlag.triggered(args)\
    local theZone = args.theZone \
    if theZone.raiseStopped then return end \
    -- if we get here, we aren't stopped and do the flag pull\
    cfxZones.setFlagValue(theZone.raiseFlag, theZone.flagValue, theZone)\
end\
\
--\
-- update \
--\
function raiseFlag.update()\
    -- call me in a second to poll triggers\
    timer.scheduleFunction(raiseFlag.update, {}, timer.getTime() + 1)\
        \
    for idx, aZone in pairs(raiseFlag.flags) do\
        -- make sure to re-start before reading time limit\
        if aZone.triggerStopFlag then \
            local currTriggerVal = cfxZones.getFlagValue(aZone.triggerStopFlag, theZone)\
            if currTriggerVal ~= aZone.lastTriggerStopValue\
            then \
                theZone.raiseStopped = true -- we are done, no flag! \
            end\
        end\
    end\
end\
\
--\
-- config & go!\
--\
\
function raiseFlag.readConfigZone()\
    local theZone = cfxZones.getZoneByName(\"raiseFlagConfig\") \
    if not theZone then \
        if raiseFlag.verbose then \
            trigger.action.outText(\"+++rFlg: NO config zone!\", 30)\
        end \
        return \
    end \
    \
    raiseFlag.verbose = cfxZones.getBoolFromZoneProperty(theZone, \"verbose\", false)\
    \
    if raiseFlag.verbose then \
        trigger.action.outText(\"+++rFlg: read config\", 30)\
    end \
end\
\
function raiseFlag.start()\
    -- lib check\
    if not dcsCommon.libCheck then \
        trigger.action.outText(\"cfx raise flag requires dcsCommon\", 30)\
        return false \
    end \
    if not dcsCommon.libCheck(\"cfx Raise Flag\", raiseFlag.requiredLibs) then\
        return false \
    end\
    \
    -- read config \
    raiseFlag.readConfigZone()\
    \
    -- process cloner Zones \
    local attrZones = cfxZones.getZonesWithAttributeNamed(\"raiseFlag\")\
    for k, aZone in pairs(attrZones) do \
        raiseFlag.createRaiseFlagWithZone(aZone) -- process attributes\
        raiseFlag.addRaiseFlag(aZone) -- add to list\
    end\
    -- try synonym\
    attrZones = cfxZones.getZonesWithAttributeNamed(\"raiseFlag!\")\
    for k, aZone in pairs(attrZones) do \
        raiseFlag.createRaiseFlagWithZone(aZone) -- process attributes\
        raiseFlag.addRaiseFlag(aZone) -- add to list\
    end\
    \
    -- start update \
    raiseFlag.update()\
    \
    trigger.action.outText(\"cfx raiseFlag v\" .. raiseFlag.version .. \" started.\", 30)\
    return true \
end\
\
-- let's go!\
if not raiseFlag.start() then \
    trigger.action.outText(\"cfx Raise Flag aborted: missing libraries\", 30)\
    raiseFlag = nil \
end",
                    ["predicate"] = "a_do_script",
                }, -- end of [6]
                [7] = 
                {
                    ["text"] = "pulseFlags = {}\
pulseFlags.version = \"1.1.0\"\
pulseFlags.verbose = false \
pulseFlags.requiredLibs = {\
    \"dcsCommon\", -- always\
    \"cfxZones\", -- Zones, of course \
}\
--[[--\
    Pulse Flags: DML module to regularly change a flag \
    \
    Copyright 2022 by Christian Franz and cf/x \
    \
    Version History\
    - 1.0.0 Initial version \
    - 1.0.1 pause behavior debugged \
    - 1.0.2 zero pulse optional initial pulse suppress\
    - 1.0.3 pollFlag switched to cfxZones \
            uses randomDelayFromPositiveRange\
            flag! now is string \
            WARNING: still needs full alphaNum flag upgrade \
    - 1.1.0 Full DML flag integration \
            removed zone!\
            made pulse and pulse! the out flag carrier\
            done!\
            pulsesDone! synonym\
            pausePulse? synonym\
            pulseMethod synonym\
            startPulse? synonym \
            pulseStopped synonym\
    \
--]]--\
\
pulseFlags.pulses = {}\
\
function pulseFlags.addPulse(aZone)\
    table.insert(pulseFlags.pulses, aZone)\
end\
\
--\
-- create a pulse \
--\
\
function pulseFlags.createPulseWithZone(theZone)\
    if cfxZones.hasProperty(theZone, \"pulse\") then \
        theZone.pulseFlag = cfxZones.getStringFromZoneProperty(theZone, \"pulse\", \"*none\") -- the flag to pulse \
    end\
\
    if cfxZones.hasProperty(theZone, \"pulse!\") then \
        theZone.pulseFlag = cfxZones.getStringFromZoneProperty(theZone, \"pulse!\", \"*none\") -- the flag to pulse \
    end\
    \
    -- time can be number, or number-number range\
    theZone.minTime, theZone.time = cfxZones.getPositiveRangeFromZoneProperty(theZone, \"time\", 1)\
    if pulseFlags.verbose then \
        trigger.action.outText(\"***PulF: zone <\" .. theZone.name .. \"> time is <\".. theZone.minTime ..\", \" .. theZone.time .. \"!\", 30)\
    end \
    \
    theZone.pulses = cfxZones.getNumberFromZoneProperty(theZone, \"pulses\", -1)\
    theZone.pulsesLeft = 0 -- will start new cycle \
        \
    -- trigger flags \
    if cfxZones.hasProperty(theZone, \"activate?\") then \
        theZone.activatePulseFlag = cfxZones.getStringFromZoneProperty(theZone, \"activate?\", \"none\")\
        theZone.lastActivateValue = cfxZones.getFlagValue(theZone.activatePulseFlag, theZone) -- trigger.misc.getUserFlag(theZone.activatePulseFlag) -- save last value\
    end\
    \
    if cfxZones.hasProperty(theZone, \"startPulse?\") then \
        theZone.activatePulseFlag = cfxZones.getStringFromZoneProperty(theZone, \"startPulse?\", \"none\")\
        theZone.lastActivateValue = cfxZones.getFlagValue(theZone.activatePulseFlag, theZone) -- trigger.misc.getUserFlag(theZone.activatePulseFlag) -- save last value\
    end\
    \
    if cfxZones.hasProperty(theZone, \"pause?\") then \
        theZone.pausePulseFlag = cfxZones.getStringFromZoneProperty(theZone, \"pause?\", \"*none\")\
        theZone.lastPauseValue = cfxZones.getFlagValue(theZone.lastPauseValue, theZone)-- trigger.misc.getUserFlag(theZone.pausePulseFlag) -- save last value\
    end\
    \
    if cfxZones.hasProperty(theZone, \"pausePulse?\") then \
        theZone.pausePulseFlag = cfxZones.getStringFromZoneProperty(theZone, \"pausePulse?\", \"*none\")\
        theZone.lastPauseValue = cfxZones.getFlagValue(theZone.lastPauseValue, theZone)-- trigger.misc.getUserFlag(theZone.pausePulseFlag) -- save last value\
    end\
    \
    theZone.pulsePaused = cfxZones.getBoolFromZoneProperty(theZone, \"paused\", false)\
    \
    if cfxZones.hasProperty(theZone, \"pulseStopped\") then \
        theZone.pulsePaused = cfxZones.getBoolFromZoneProperty(theZone, \"pulseStopped\", false)\
    end\
    \
    theZone.method = cfxZones.getStringFromZoneProperty(theZone, \"method\", \"flip\")\
    \
    if cfxZones.hasProperty(theZone, \"pulseMethod\") then\
        theZone.method = cfxZones.getStringFromZoneProperty(theZone, \"pulseMethod\", \"flip\")\
    end\
    -- done flag \
    if cfxZones.hasProperty(theZone, \"done+1\") then \
        theZone.pulseDoneFlag = cfxZones.getStringFromZoneProperty(theZone, \"done+1\", \"*none\")\
    end\
    if cfxZones.hasProperty(theZone, \"pulsesDone!\") then \
        theZone.pulseDoneFlag = cfxZones.getStringFromZoneProperty(theZone, \"pulsesDone!\", \"*none\")\
    end\
    if cfxZones.hasProperty(theZone, \"done!\") then \
        theZone.pulseDoneFlag = cfxZones.getStringFromZoneProperty(theZone, \"done!\", \"*none\")\
    end\
\
    theZone.pulsing = false -- not running \
    theZone.hasPulsed = false \
    theZone.zeroPulse = cfxZones.getBoolFromZoneProperty(theZone, \"zeroPulse\", true)\
end\
\
--\
-- update \
-- \
\
\
function pulseFlags.doPulse(args) \
    local theZone = args[1]\
    -- check if we have been paused. if so, simply \
    -- exit with no new schedule \
    if theZone.pulsePaused then \
        theZone.pulsing = false \
        return \
    end \
    \
    -- do a poll on flags\
    -- first, we only do an initial pulse if zeroPulse is set\
    if theZone.hasPulsed or theZone.zeroPulse then \
        if pulseFlags.verbose then \
            trigger.action.outText(\"+++pulF: will bang \" .. theZone.pulseFlag, 30);\
        end\
        \
        cfxZones.pollFlag(theZone.pulseFlag, theZone.method, theZone) \
    \
        -- decrease count\
        if theZone.pulses > 0 then\
            -- only do this if ending\
            theZone.pulsesLeft = theZone.pulsesLeft - 1\
            \
            -- see if we are done \
            if theZone.pulsesLeft < 1 then \
                -- increment done flag if set \
                if theZone.pulseDoneFlag then \
                    --local currVal = cfxZones.getFlagValue(theZone.pulseDoneFlag, theZone)-- trigger.misc.getUserFlag(theZone.pulseDoneFlag)\
                    cfxZones.pollFlag(theZone.pulseDoneFlag, \"inc\", theZone) -- trigger.action.setUserFlag(theZone.pulseDoneFlag, currVal + 1)\
                end\
                if pulseFlags.verbose then \
                    trigger.action.outText(\"***PulF: pulse <\" .. theZone.name .. \"> ended!\", 30)\
                end \
                theZone.pulsing = false \
                theZone.pulsePaused = true \
                return \
            end\
        end\
    else \
        if pulseFlags.verbose then \
            trigger.action.outText(\"***PulF: pulse <\" .. theZone.name .. \"> delaying zero pulse!\", 30)\
        end\
    end\
    \
    theZone.hasPulsed = true -- we are past initial pulse\
    \
    -- if we get here, schedule next pulse\
    local delay = cfxZones.randomDelayFromPositiveRange(theZone.minTime, theZone.time)\
    \
    \
    -- schedule in delay time \
    theZone.timerID = timer.scheduleFunction(pulseFlags.doPulse, args, timer.getTime() + delay)\
    if pulseFlags.verbose then \
        trigger.action.outText(\"+++PulF: pulse <\" .. theZone.name .. \"> rescheduled in \" .. delay, 30)\
    end \
end\
 \
\
-- start new pulse, will reset \
function pulseFlags.startNewPulse(theZone)\
    theZone.pulsesLeft = theZone.pulses\
    local args = {theZone}\
    theZone.pulsing = true \
    if pulseFlags.verbose then \
        trigger.action.outText(\"+++PulF: starting pulse <\" .. theZone.name .. \">\", 30)\
    end \
    pulseFlags.doPulse(args) \
end\
\
function pulseFlags.update()\
    -- call me in a second to poll triggers\
    timer.scheduleFunction(pulseFlags.update, {}, timer.getTime() + 1)\
    \
    for idx, aZone in pairs(pulseFlags.pulses) do\
        -- see if pulse is running \
        if aZone.pulsing then \
            -- this zone has a pulse and has scheduled \
            -- a new pulse, nothing to do\
        \
        else \
            -- this zone has not scheduled a new pulse \
            -- let's see why \
            if aZone.pulsePaused then \
                -- ok, zone is paused. all clear \
            else \
                -- zone isn't paused. we need to start the zone \
                pulseFlags.startNewPulse(aZone)\
            end\
        end\
        \
        -- see if we got a pause or activate command\
        if aZone.activatePulseFlag then \
            local currTriggerVal = cfxZones.getFlagValue(aZone.activatePulseFlag, aZone) -- trigger.misc.getUserFlag(aZone.activatePulseFlag)\
            if currTriggerVal ~= aZone.lastActivateValue\
            then \
                if pulseFlags.verbose then \
                    trigger.action.outText(\"+++PulF: activating <\" .. aZone.name .. \">\", 30)\
                end \
                aZone.lastActivateValue = currTriggerVal\
                aZone.pulsePaused = false -- will start anew \
                \
            end\
        end\
        \
        if aZone.pausePulseFlag then \
            local currTriggerVal = cfxZones.getFlagValue(aZone.pausePulseFlag, aZone)-- trigger.misc.getUserFlag(aZone.pausePulseFlag)\
            if currTriggerVal ~= aZone.lastPauseValue\
            then \
                if pulseFlags.verbose then \
                    trigger.action.outText(\"+++PulF: pausing <\" .. aZone.name .. \">\", 30)\
                end \
                aZone.lastPauseValue = currTriggerVal\
                aZone.pulsePaused = true  -- prevents new start \
                if aZone.timerID then \
                     timer.removeFunction(aZone.timerID)\
                     aZone.timerID = nil \
                end \
            end\
        end\
    end\
end\
\
--\
-- start module and read config \
--\
function pulseFlags.readConfigZone()\
    -- note: must match exactly!!!!\
    local theZone = cfxZones.getZoneByName(\"pulseFlagsConfig\") \
    if not theZone then \
        if pulseFlags.verbose then \
            trigger.action.outText(\"+++PulF: NO config zone!\", 30)\
        end \
        return \
    end \
    \
    pulseFlags.verbose = cfxZones.getBoolFromZoneProperty(theZone, \"verbose\", false)\
    \
    if pulseFlags.verbose then \
        trigger.action.outText(\"+++PulF: read config\", 30)\
    end \
end\
\
function pulseFlags.start()\
    -- lib check\
    if not dcsCommon.libCheck then \
        trigger.action.outText(\"PulseFlags requires dcsCommon\", 30)\
        return false \
    end \
    if not dcsCommon.libCheck(\"cfx Pulse Flags\", \
        pulseFlags.requiredLibs) then\
        return false \
    end\
    \
    -- read config \
    pulseFlags.readConfigZone()\
    \
    -- process RND Zones \
    local attrZones = cfxZones.getZonesWithAttributeNamed(\"pulse\")\
    \
    -- now create a pulse gen for each one and add them\
    -- to our watchlist \
    for k, aZone in pairs(attrZones) do \
        pulseFlags.createPulseWithZone(aZone) -- process attribute and add to zone\
        pulseFlags.addPulse(aZone) -- remember it so we can pulse it\
    end\
    \
    local attrZones = cfxZones.getZonesWithAttributeNamed(\"pulse!\")\
    \
    -- now create a pulse gen for each one and add them\
    -- to our watchlist \
    for k, aZone in pairs(attrZones) do \
        pulseFlags.createPulseWithZone(aZone) -- process attribute and add to zone\
        pulseFlags.addPulse(aZone) -- remember it so we can pulse it\
    end\
    \
    -- start update in 1 second \
    --pulseFlags.update()\
    timer.scheduleFunction(pulseFlags.update, {}, timer.getTime() + 1)\
    \
    trigger.action.outText(\"cfx Pulse Flags v\" .. pulseFlags.version .. \" started.\", 30)\
    return true \
end\
\
-- let's go!\
if not pulseFlags.start() then \
    trigger.action.outText(\"cf/x Pulse Flags aborted: missing libraries\", 30)\
    pulseFlags = nil \
end",
                    ["predicate"] = "a_do_script",
                }, -- end of [7]
                [8] = 
                {
                    ["text"] = "rndFlags = {}\
rndFlags.version = \"1.1.0\"\
rndFlags.verbose = false \
rndFlags.requiredLibs = {\
    \"dcsCommon\", -- always\
    \"cfxZones\", -- Zones, of course \
}\
--[[\
    Random Flags: DML module to select flags at random\
    and then change them\
    \
    Copyright 2022 by Christian Franz and cf/x \
    \
    Version History\
    1.0.0 - Initial Version \
    1.1.0 - DML flag conversion:\
                flagArrayFromString: strings OK, trim \
                remove pollFlag\
                pollFlag from cfxZones, include zone \
                randomBetween for pollSize\
                pollFlag to bang done with inc\
                getFlagValue in update \
                some code clean-up\
                rndMethod synonym \
--]]\
rndFlags.rndGen = {}\
\
function rndFlags.addRNDZone(aZone)\
    table.insert(rndFlags.rndGen, aZone)\
end\
\
function rndFlags.flagArrayFromString(inString)\
    if string.len(inString) < 1 then \
        trigger.action.outText(\"+++RND: empty flags\", 30)\
        return {} \
    end\
    if rndFlags.verbose then \
        trigger.action.outText(\"+++RND: processing <\" .. inString .. \">\", 30)\
    end \
    \
    local flags = {}\
    local rawElements = dcsCommon.splitString(inString, \",\")\
    -- go over all elements \
    for idx, anElement in pairs(rawElements) do \
        if dcsCommon.stringStartsWithDigit(anElement) and  dcsCommon.containsString(anElement, \"-\") then \
            -- interpret this as a range\
            local theRange = dcsCommon.splitString(anElement, \"-\")\
            local lowerBound = theRange[1]\
            lowerBound = tonumber(lowerBound)\
            local upperBound = theRange[2]\
            upperBound = tonumber(upperBound)\
            if lowerBound and upperBound then\
                -- swap if wrong order\
                if lowerBound > upperBound then \
                    local temp = upperBound\
                    upperBound = lowerBound\
                    lowerBound = temp \
                end\
                -- now add add numbers to flags\
                for f=lowerBound, upperBound do \
                    table.insert(flags, f)\
\
                end\
            else\
                -- bounds illegal\
                trigger.action.outText(\"+++RND: ignored range <\" .. anElement .. \"> (range)\", 30)\
            end\
        else\
            -- single number\
            f = dcsCommon.trim(anElement) -- DML flag upgrade: accept strings tonumber(anElement)\
            if f then \
                table.insert(flags, f)\
\
            else \
                trigger.action.outText(\"+++RND: ignored element <\" .. anElement .. \"> (single)\", 30)\
            end\
        end\
    end\
    if rndFlags.verbose then \
        trigger.action.outText(\"+++RND: <\" .. #flags .. \"> flags total\", 30)\
    end \
    return flags\
end\
\
--\
-- create rnd gen from zone \
--\
function rndFlags.createRNDWithZone(theZone)\
    local flags = cfxZones.getStringFromZoneProperty(theZone, \"flags!\", \"\")\
    if flags == \"\" then \
        -- let's try alternate spelling without \"!\"\
        flags = cfxZones.getStringFromZoneProperty(theZone, \"flags\", \"\") \
    end \
    -- now build the flag array from strings\
    local theFlags = rndFlags.flagArrayFromString(flags)\
    theZone.myFlags = theFlags\
\
\
    theZone.pollSizeMin, theZone.pollSize = cfxZones.getPositiveRangeFromZoneProperty(theZone, \"pollSize\", 1)\
    if rndFlags.verbose then \
        trigger.action.outText(\"+++RND: pollSize is <\" .. theZone.pollSizeMin .. \", \" .. theZone.pollSize .. \">\", 30)\
    end\
             \
    \
    theZone.remove = cfxZones.getBoolFromZoneProperty(theZone, \"remove\", false)\
\
    -- trigger flag \
    if cfxZones.hasProperty(theZone, \"f?\") then \
        theZone.triggerFlag = cfxZones.getStringFromZoneProperty(theZone, \"f?\", \"none\")\
    end\
    \
    if cfxZones.hasProperty(theZone, \"in?\") then \
        theZone.triggerFlag = cfxZones.getStringFromZoneProperty(theZone, \"in?\", \"none\")\
    end\
    \
    if cfxZones.hasProperty(theZone, \"rndPoll?\") then \
        theZone.triggerFlag = cfxZones.getStringFromZoneProperty(theZone, \"rndPoll?\", \"none\")\
    end\
    \
    if theZone.triggerFlag then \
        theZone.lastTriggerValue = cfxZones.getFlagValue(theZone.triggerFlag, theZone) --trigger.misc.getUserFlag(theZone.triggerFlag) -- save last value\
    end\
    \
    theZone.onStart = cfxZones.getBoolFromZoneProperty(theZone, \"onStart\", false)\
    \
    if not theZone.onStart and not theZone.triggerFlag then \
        theZone.onStart = true \
    end\
    \
    theZone.rndMethod = cfxZones.getStringFromZoneProperty(theZone, \"method\", \"on\")\
    if cfxZones.hasProperty(theZone, \"rndMethod\") then \
        theZone.rndMethod = cfxZones.getStringFromZoneProperty(theZone, \"rndMethod\", \"on\")\
    end\
    \
    theZone.reshuffle = cfxZones.getBoolFromZoneProperty(theZone, \"reshuffle\", false)\
    if theZone.reshuffle then \
        -- create a backup copy we can reshuffle from \
        theZone.flagStore = dcsCommon.copyArray(theFlags)\
    end\
    \
    -- done flag \
    if cfxZones.hasProperty(theZone, \"done+1\") then \
        theZone.doneFlag = cfxZones.getStringFromZoneProperty(theZone, \"done+1\", \"none\")\
    end\
end\
\
function rndFlags.reshuffle(theZone)\
    if rndFlags.verbose then \
        trigger.action.outText(\"+++RND: reshuffling zone \" .. theZone.name, 30)\
    end\
    theZone.myFlags = dcsCommon.copyArray(theZone.flagStore)\
end\
\
--\
-- fire RND\
-- \
\
function rndFlags.fire(theZone) \
    -- fire this rnd \
    -- create a local copy of all flags \
    if theZone.reshuffle and #theZone.myFlags < 1 then \
        rndFlags.reshuffle(theZone)\
    end\
    \
    local availableFlags = dcsCommon.copyArray(theZone.myFlags) \
    \
    -- do this pollSize times \
    local pollSize = dcsCommon.randomBetween(theZone.pollSizeMin, theZone.pollSize)\
\
    \
    if #availableFlags < 1 then \
        if rndFlags.verbose then \
            trigger.action.outText(\"+++RND: RND \" .. theZone.name .. \" ran out of flags. aborting fire\", 30)\
        end\
        \
        if theZone.doneFlag then\
            cfxZones.pollFlag(theZone.doneFlag, \"inc\", theZone)\
        end\
        \
        return \
    end\
    \
    if rndFlags.verbose then \
        trigger.action.outText(\"+++RND: firing RND \" .. theZone.name .. \" with pollsize \" .. pollSize .. \" on \" .. #availableFlags .. \" set size\", 30)\
    end\
    \
    for i=1, pollSize do \
        -- check there are still flags left \
        if #availableFlags < 1 then \
            trigger.action.outText(\"+++RND: no flags left in \" .. theZone.name .. \" in index \" .. i, 30)\
            theZone.myFlags = {} \
            if theZone.reshuffle then \
                rndFlags.reshuffle(theZone)\
            end\
            return \
        end\
        \
        -- select a flag, enforce uniqueness\
        local theFlagIndex = dcsCommon.smallRandom(#availableFlags)\
        \
        -- poll this flag and remove from available\
        local theFlag = table.remove(availableFlags,theFlagIndex)\
        \
        --rndFlags.pollFlag(theFlag, theZone.rndMethod)\
        if rndFlags.verbose then \
            trigger.action.outText(\"+++RND: polling \" .. theFlag .. \" with \" .. theZone.rndMethod, 30)\
        end\
        \
        cfxZones.pollFlag(theFlag, theZone.rndMethod, theZone) \
    end\
    \
    -- remove if requested\
    if theZone.remove then \
        theZone.myFlags = availableFlags\
    end\
end\
\
--\
-- update \
--\
function rndFlags.update()\
    -- call me in a second to poll triggers\
    timer.scheduleFunction(rndFlags.update, {}, timer.getTime() + 1)\
    \
    for idx, aZone in pairs(rndFlags.rndGen) do\
        if aZone.triggerFlag then \
            local currTriggerVal = cfxZones.getFlagValue(aZone.triggerFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerFlag)\
            if currTriggerVal ~= aZone.lastTriggerValue\
            then \
                if rndFlags.verbose then \
                    trigger.action.outText(\"+++RND: triggering \" .. aZone.name, 30)\
                end \
                rndFlags.fire(aZone)\
                aZone.lastTriggerValue = currTriggerVal\
            end\
\
        end\
    end\
end\
\
--\
-- start cycle: force all onStart to fire \
--\
function rndFlags.startCycle()\
    for idx, theZone in pairs(rndFlags.rndGen) do\
        if theZone.onStart then \
            if rndFlags.verbose then \
                trigger.action.outText(\"+++RND: starting \" .. theZone.name, 30)\
            end \
            rndFlags.fire(theZone)\
        end\
    end\
end\
\
\
--\
-- start module and read config \
--\
function rndFlags.readConfigZone()\
    -- note: must match exactly!!!!\
    local theZone = cfxZones.getZoneByName(\"rndFlagsConfig\") \
    if not theZone then \
        if rndFlags.verbose then \
            trigger.action.outText(\"***RND: NO config zone!\", 30)\
        end \
        return \
    end \
    \
    rndFlags.verbose = cfxZones.getBoolFromZoneProperty(theZone, \"verbose\", false)\
    \
    if rndFlags.verbose then \
        trigger.action.outText(\"***RND: read config\", 30)\
    end \
end\
\
function rndFlags.start()\
    -- lib check\
    if not dcsCommon.libCheck then \
        trigger.action.outText(\"RNDFlags requires dcsCommon\", 30)\
        return false \
    end \
    if not dcsCommon.libCheck(\"cfx Random Flags\", \
        rndFlags.requiredLibs) then\
        return false \
    end\
    \
    -- read config \
    rndFlags.readConfigZone()\
    \
    -- process RND Zones \
    local attrZones = cfxZones.getZonesWithAttributeNamed(\"RND\")\
    \
    -- now create an rnd gen for each one and add them\
    -- to our watchlist \
    for k, aZone in pairs(attrZones) do \
        rndFlags.createRNDWithZone(aZone) -- process attribute and add to zone\
        rndFlags.addRNDZone(aZone) -- remember it so we can smoke it\
    end\
    \
    -- start cycle \
    timer.scheduleFunction(rndFlags.startCycle, {}, timer.getTime() + 0.25)\
    \
    -- start update \
    timer.scheduleFunction(rndFlags.update, {}, timer.getTime() + 1)\
    \
    trigger.action.outText(\"cfx random Flags v\" .. rndFlags.version .. \" started.\", 30)\
    return true \
end\
\
-- let's go!\
if not rndFlags.start() then \
    trigger.action.outText(\"cf/x RND Flags aborted: missing libraries\", 30)\
    rndFlags = nil \
end\
\
-- TODO: move flags to RND!, rename RND to RND!, deprecate flags!\
",
                    ["predicate"] = "a_do_script",
                }, -- end of [8]
                [9] = 
                {
                    ["text"] = "delayFlag = {}\
delayFlag.version = \"1.1.0\"\
delayFlag.verbose = false  \
delayFlag.requiredLibs = {\
    \"dcsCommon\", -- always\
    \"cfxZones\", -- Zones, of course \
}\
delayFlag.flags = {}\
\
--[[--\
    delay flags - simple flag switch & delay, allows for randomize\
    and dead man switching \
    \
    Copyright (c) 2022 by Christian Franz and cf/x AG\
    \
    Version History\
    1.0.0 - Initial Version \
    1.0.1 - message attribute \
    1.0.2 - slight spelling correction \
          - using cfxZones for polling \
          - removed pollFlag \
    1.0.3 - bug fix for config zone name\
          - removed message attribute, moved to own module \
          - triggerFlag --> triggerDelayFlag\
    1.0.4 - startDelay\
    1.1.0 - DML flag upgrade \
          - removed onStart. use local raiseFlag instead \
          - delayDone! synonym\
          - pauseDelay?\
          - unpauseDelay?\
    \
--]]--\
\
function delayFlag.addDelayZone(theZone)\
    table.insert(delayFlag.flags, theZone)\
end\
\
function delayFlag.getDelayZoneByName(aName) \
    for idx, aZone in pairs(delayFlag.flags) do \
        if aName == aZone.name then return aZone end \
    end\
    if delayFlag.verbose then \
        trigger.action.outText(\"+++dlyF: no delay flag with name <\" .. aName ..\">\", 30)\
    end \
    \
    return nil \
end\
\
--\
-- read attributes \
-- \
--\
-- create rnd gen from zone \
--\
function delayFlag.createTimerWithZone(theZone)\
    -- delay\
    theZone.delayMin, theZone.delayMax = cfxZones.getPositiveRangeFromZoneProperty(theZone, \"timeDelay\", 1) -- same as zone signature \
    if delayFlag.verbose then \
        trigger.action.outText(\"+++dlyF: time delay is <\" .. theZone.delayMin .. \", \" .. theZone.delayMax .. \"> seconds\", 30)\
    end\
    \
\
    -- trigger flag \
    if cfxZones.hasProperty(theZone, \"f?\") then \
        theZone.triggerDelayFlag = cfxZones.getStringFromZoneProperty(theZone, \"f?\", \"none\")\
    end\
    \
    if cfxZones.hasProperty(theZone, \"in?\") then \
        theZone.triggerDelayFlag = cfxZones.getStringFromZoneProperty(theZone, \"in?\", \"none\")\
    end\
    \
    if cfxZones.hasProperty(theZone, \"startDelay?\") then \
        theZone.triggerDelayFlag = cfxZones.getStringFromZoneProperty(theZone, \"startDelay?\", \"none\")\
    end\
    \
    if theZone.triggerDelayFlag then \
        theZone.lastDelayTriggerValue = cfxZones.getFlagValue(theZone.triggerDelayFlag, theZone) -- trigger.misc.getUserFlag(theZone.triggerDelayFlag) -- save last value\
    end\
    \
    \
    theZone.method = cfxZones.getStringFromZoneProperty(theZone, \"method\", \"flip\")\
    \
    -- out flag \
    if cfxZones.hasProperty(theZone, \"out!\") then \
        theZone.delayDoneFlag = cfxZones.getStringFromZoneProperty(theZone, \"out!\", -1)\
    end\
    \
    if cfxZones.hasProperty(theZone, \"delayDone!\") then \
        theZone.delayDoneFlag = cfxZones.getStringFromZoneProperty(theZone, \"delayDone!\", -1)\
    end\
\
    -- stop the press!\
    if cfxZones.hasProperty(theZone, \"stopDelay?\") then \
        theZone.triggerStopDelay = cfxZones.getStringFromZoneProperty(theZone, \"stopDelay?\", \"none\")\
        theZone.lastTriggerStopValue = cfxZones.getFlagValue(theZone.triggerStopDelay, theZone)\
    end\
    \
    \
    \
    \
    -- init \
    theZone.delayRunning = false \
    theZone.timeLimit = -1 \
\
end\
\
\
--\
-- update \
-- \
\
function delayFlag.startDelay(theZone) \
    -- refresh timer \
    theZone.delayRunning = true\
    \
    -- set new expiry date \
    local delayMax = theZone.delayMax\
    local delayMin = theZone.delayMin\
    local delay = delayMax \
    \
    if delayMin ~= delayMax then \
        -- pick random in range , say 3-7 --> 5 s!\
        local delayDiff = (delayMax - delayMin) + 1 -- 7-3 + 1\
        delay = dcsCommon.smallRandom(delayDiff) - 1 --> 0-4\
        delay = delay + delayMin \
        if delay > theZone.delayMax then delay = theZone.delayMax end \
        if delay < 1 then delay = 1 end \
        \
        if delayFlag.verbose then \
            trigger.action.outText(\"+++dlyF: delay \" .. theZone.name .. \" range \" .. delayMin .. \"-\" .. delayMax .. \": selected \" .. delay, 30)\
        end\
    end\
    \
    theZone.timeLimit = timer.getTime() + delay \
end\
\
function delayFlag.update()\
    -- call me in a second to poll triggers\
    timer.scheduleFunction(delayFlag.update, {}, timer.getTime() + 1)\
    \
    local now = timer.getTime() \
    \
    for idx, aZone in pairs(delayFlag.flags) do\
        -- see if we need to stop \
        if aZone.triggerStopDelay then \
            local currTriggerVal = cfxZones.getFlagValue(aZone.triggerStopDelay, aZone)\
            if currTriggerVal ~= lastTriggerStopValue then \
                aZone.delayRunning = false -- simply stop.\
                if delayFlag.verbose then \
                    trigger.action.outText(\"+++dlyF: stopped delay \" .. aZone.name, 30)\
                end \
            end \
        end        \
        \
        -- make sure to re-start before reading time limit\
        if aZone.triggerDelayFlag then \
            local currTriggerVal = cfxZones.getFlagValue(aZone.triggerDelayFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerDelayFlag)\
            if currTriggerVal ~= aZone.lastDelayTriggerValue\
            then \
                if delayFlag.verbose then \
                    if aZone.delayRunning then \
                        trigger.action.outText(\"+++dlyF: re-starting timer \" .. aZone.name, 30)    \
                    else \
                        trigger.action.outText(\"+++dlyF: init timer for \" .. aZone.name, 30)\
                    end\
                end \
                delayFlag.startDelay(aZone) -- we restart even if running \
                aZone.lastDelayTriggerValue = currTriggerVal\
            end\
        end\
        \
        if aZone.delayRunning then \
            -- check expiry \
            if now > aZone.timeLimit then \
                -- end timer \
                aZone.delayRunning = false \
                -- poll flag \
                cfxZones.pollFlag(aZone.delayDoneFlag, aZone.method, aZone)\
                if delayFlag.verbose then \
                    trigger.action.outText(\"+++dlyF: banging on \" .. aZone.delayDoneFlag, 30)\
                end \
            end\
        end\
        \
    end\
end\
\
--\
-- START \
--\
function delayFlag.readConfigZone()\
    local theZone = cfxZones.getZoneByName(\"delayFlagsConfig\") \
    if not theZone then \
        if delayFlag.verbose then \
            trigger.action.outText(\"+++dlyF: NO config zone!\", 30)\
        end \
        return \
    end \
    \
    delayFlag.verbose = cfxZones.getBoolFromZoneProperty(theZone, \"verbose\", false)\
    \
    if delayFlag.verbose then \
        trigger.action.outText(\"+++dlyF: read config\", 30)\
    end \
end\
\
--[[--\
function delayFlag.onStart()\
    for idx, theZone in pairs(delayFlag.flags) do \
        if theZone.onStart then \
            if delayFlag.verbose then \
                trigger.action.outText(\"+++dlyF: onStart for <\"..theZone.name .. \">\", 30)\
            end\
            delayFlag.startDelay(theZone) \
        end \
    end\
end\
--]]--\
\
function delayFlag.start()\
    -- lib check\
    if not dcsCommon.libCheck then \
        trigger.action.outText(\"cfx Delay Flags requires dcsCommon\", 30)\
        return false \
    end \
    if not dcsCommon.libCheck(\"cfx Delay Flags\", \
        delayFlag.requiredLibs) then\
        return false \
    end\
    \
    -- read config \
    delayFlag.readConfigZone()\
    \
    -- process cloner Zones \
    local attrZones = cfxZones.getZonesWithAttributeNamed(\"timeDelay\")\
    for k, aZone in pairs(attrZones) do \
        delayFlag.createTimerWithZone(aZone) -- process attributes\
        delayFlag.addDelayZone(aZone) -- add to list\
    end\
    \
    -- kick onStart\
    --delayFlag.onStart()\
    \
    -- start update \
    delayFlag.update()\
    \
    trigger.action.outText(\"cfx Delay Flag v\" .. delayFlag.version .. \" started.\", 30)\
    return true \
end\
\
-- let's go!\
if not delayFlag.start() then \
    trigger.action.outText(\"cfx Delay Flag aborted: missing libraries\", 30)\
    delayFlag = nil \
end",
                    ["predicate"] = "a_do_script",
                }, -- end of [9]
                [10] = 
                {
                    ["text"] = "cloneZones = {}\
cloneZones.version = \"1.3.0\"\
cloneZones.verbose = false  \
cloneZones.requiredLibs = {\
    \"dcsCommon\", -- always\
    \"cfxZones\", -- Zones, of course \
    \"cfxMX\", \
}\
cloneZones.cloners = {}\
cloneZones.callbacks = {}\
cloneZones.unitXlate = {}\
cloneZones.groupXlate = {} -- used to translate original groupID to cloned. only holds last spawned group id \
cloneZones.uniqueCounter = 9200000 -- we start group numbering here \
--[[--\
    Clones Groups from ME mission data\
    Copyright (c) 2022 by Christian Franz and cf/x AG\
    \
    Version History\
    1.0.0 - initial version \
    1.0.1 - preWipe attribute\
    1.1.0 - support for static objects\
          - despawn? attribute \
    1.1.1 - despawnAll: isExist guard \
          - map in? to f? \
    1.2.0 - Lua API integration: callbacks \
          - groupXlate struct\
          - unitXlate struct \
          - resolveReferences \
          - getGroupsInZone rewritten for data \
          - static resolve \
          - linkUnit resolve \
          - clone? synonym\
          - empty! and method attributes\
    1.3.0 - DML flag upgrade \
    \
--]]--\
\
--\
-- adding / removing from list \
--\
function cloneZones.addCloneZone(theZone)\
    table.insert(cloneZones.cloners, theZone)\
end\
\
function cloneZones.getCloneZoneByName(aName) \
    for idx, aZone in pairs(cloneZones.cloners) do \
        if aName == aZone.name then return aZone end \
    end\
    if cloneZones.verbose then \
        trigger.action.outText(\"+++clnZ: no clone with name <\" .. aName ..\">\", 30)\
    end \
    \
    return nil \
end\
\
--\
-- callbacks \
--\
\
function cloneZones.addCallback(theCallback)\
    if not theCallback then return end \
    table.insert(cloneZones.callbacks, theCallback)\
end\
\
-- reasons for callback \
-- \"will despawn group\" - args is the group about to be despawned\
-- \"did spawn group\" -- args is group that was spawned\
-- \"will despawn static\"\
-- \"did spawn static\"\
-- \"spawned\" -- completed spawn cycle. args contains .groups and .statics spawned \
-- \"empty\" -- all spawns have been killed, args is empty \
-- \"wiped\" -- preWipe executed \
-- \"<none\" -- something went wrong \
\
function cloneZones.invokeCallbacks(theZone, reason, args)\
    if not theZone then return end \
    if not reason then reason = \"<none>\" end \
    if not args then args = {} end \
    \
    -- invoke anyone who wants to know that a group \
    -- of people was rescued.\
    for idx, cb in pairs(cloneZones.callbacks) do \
        cb(theZone, reason, args)\
    end\
end\
\
-- group translation orig id \
\
--\
-- reading zones\
--\
function cloneZones.partOfGroupDataInZone(theZone, theUnits)\
    local zP = cfxZones.getPoint(theZone)\
    zP.y = 0\
    \
    for idx, aUnit in pairs(theUnits) do \
        local uP = {}\
        uP.x = aUnit.x \
        uP.y = 0\
        uP.z = aUnit.y -- !! y-z\
        local dist = dcsCommon.dist(uP, zP)\
        if dist <= theZone.radius then return true  end \
    end \
    return false \
end\
\
function cloneZones.allGroupsInZoneByData(theZone) \
    local theGroupsInZone = {}\
    local radius = theZone.radius \
    for groupName, groupData in pairs(cfxMX.groupDataByName) do \
        if groupData.units then \
            if cloneZones.partOfGroupDataInZone(theZone, groupData.units) then \
                theGroup = Group.getByName(groupName)\
                table.insert(theGroupsInZone, theGroup)\
            end\
        end\
    end\
    return theGroupsInZone\
end\
\
function cloneZones.createClonerWithZone(theZone) -- has \"Cloner\"\
    if cloneZones.verbose then \
        trigger.action.outText(\"+++clnZ: new cloner \" .. theZone.name, 30)\
    end\
\
    local localZones = cloneZones.allGroupsInZoneByData(theZone)  \
    local localObjects = cfxZones.allStaticsInZone(theZone)\
    theZone.cloner = true -- this is a cloner zoner \
    theZone.mySpawns = {}\
    theZone.myStatics = {}\
    theZone.origin = cfxZones.getPoint(theZone) -- save reference point for all groupVectors \
    \
    -- source tells us which template to use. it can be the following:\
    -- nothing (no attribute) - then we use whatever groups are in zone to \
    -- spawn as template \
    -- name of another spawner that provides the template \
    -- we can't simply use a group name as we lack the reference \
    -- location for delta \
    if cfxZones.hasProperty(theZone, \"source\") then \
        theZone.source = cfxZones.getStringFromZoneProperty(theZone, \"source\", \"<none>\")\
        if theZone.source == \"<none>\" then theZone.source = nil end \
    end \
    \
    if not theZone.source then \
        theZone.cloneNames = {} -- names of the groups. only present in template spawners\
        theZone.staticNames = {} -- names of all statics. only present in templates\
        \
        for idx, aGroup in pairs(localZones) do\
            local gName = aGroup:getName()\
            if gName then \
                table.insert(theZone.cloneNames, gName)\
                table.insert(theZone.mySpawns, aGroup) -- collect them for initial despawn\
                -- now get group data and save a lookup for \
                -- resolving internal references \
                local rawData, cat, ctry = cfxMX.getGroupFromDCSbyName(gName)\
                local origID = rawData.groupId\
--                cloneZones.templateGroups[gName] = origID \
--                cloneZones.templateGroupsReverse[origID] = gName\
            end     \
        end\
        \
        for idx, aStatic in pairs (localObjects) do \
            local sName = aStatic:getName()\
            if sName then \
                table.insert(theZone.staticNames, sName)\
                table.insert(theZone.myStatics, aStatic)\
            end\
        end\
        \
        cloneZones.despawnAll(theZone) \
        if (#theZone.cloneNames + #theZone.staticNames)    < 1 then \
            if cloneZones.verbose then \
                trigger.action.outText(\"+++clnZ: WARNING - Template in clone zone <\" .. theZone.name .. \"> is empty\", 30)\
            end \
            theZone.cloneNames = nil\
            theZone.staticNames = nil \
        end\
        if cloneZones.verbose then \
            trigger.action.outText(theZone.name .. \" clone template saved\", 30)\
        end\
    end\
    \
    -- f? and spawn? and other synonyms map to the same \
    if cfxZones.hasProperty(theZone, \"f?\") then \
        theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, \"f?\", \"none\")\
    end\
    \
    if cfxZones.hasProperty(theZone, \"in?\") then \
        theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, \"in?\", \"none\")\
    end\
    \
    if cfxZones.hasProperty(theZone, \"spawn?\") then \
        theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, \"spawn?\", \"none\")\
    end\
    \
    if cfxZones.hasProperty(theZone, \"clone?\") then \
        theZone.spawnFlag = cfxZones.getStringFromZoneProperty(theZone, \"clone?\", \"none\")\
    end\
    \
    if theZone.spawnFlag then \
        theZone.lastSpawnValue = cfxZones.getFlagValue(theZone.spawnFlag, theZone)\
    end\
    \
    -- deSpawn?\
    if cfxZones.hasProperty(theZone, \"deSpawn?\") then \
        theZone.deSpawnFlag = cfxZones.getStringFromZoneProperty(theZone, \"deSpawn?\", \"none\")\
    end\
    \
    if cfxZones.hasProperty(theZone, \"deClone?\") then \
        theZone.deSpawnFlag = cfxZones.getStringFromZoneProperty(theZone, \"deClone?\", \"none\")\
    end\
    \
    if theZone.deSpawnFlag then \
        theZone.lastDeSpawnValue = cfxZones.getFlagValue(theZone.deSpawnFlag, theZone)\
    end\
    \
    -- to be deprecated\
    theZone.onStart = cfxZones.getBoolFromZoneProperty(theZone, \"onStart\", false)\
    \
    theZone.moveRoute = cfxZones.getBoolFromZoneProperty(theZone, \"moveRoute\", false)\
    \
    theZone.preWipe = cfxZones.getBoolFromZoneProperty(theZone, \"preWipe\", false)\
    \
    -- to be deprecated\
    if cfxZones.hasProperty(theZone, \"empty+1\") then \
        theZone.emptyFlag = cfxZones.getStringFromZoneProperty(theZone, \"empty+1\", \"<None>\") -- note string on number default\
    end\
    \
    if cfxZones.hasProperty(theZone, \"empty!\") then \
        theZone.emptyBangFlag = cfxZones.getStringFromZoneProperty(theZone, \"empty!\", \"<None>\") -- note string on number default\
    end\
    \
    theZone.method = cfxZones.getStringFromZoneProperty(theZone, \"method\", \"inc\")\
    \
    if cfxZones.hasProperty(theZone, \"masterOwner\") then \
        theZone.masterOwner = cfxZones.getStringFromZoneProperty(theZone, \"masterOwner\", \"<none>\")\
    end\
    \
    theZone.turn = cfxZones.getNumberFromZoneProperty(theZone, \"turn\", 0)\
    \
    -- we end with clear plate \
end\
\
-- \
-- spawning, despawning\
--\
\
function cloneZones.despawnAll(theZone) \
    if cloneZones.verbose then \
        trigger.action.outText(\"wiping <\" .. theZone.name .. \">\", 30)\
    end \
    for idx, aGroup in pairs(theZone.mySpawns) do \
        --trigger.action.outText(\"++clnZ: despawn all \" .. aGroup.name, 30)\
        \
        if aGroup:isExist() then \
            cloneZones.invokeCallbacks(theZone, \"will despawn group\", aGroup)\
            Group.destroy(aGroup)\
        end \
    end\
    for idx, aStatic in pairs(theZone.myStatics) do \
        -- warning! may be mismatch because we are looking at groups\
        -- not objects. let's see\
        if aStatic:isExist() then \
            if cloneZones.verbose then \
                trigger.action.outText(\"Destroying static <\" .. aStatic:getName() .. \">\", 30)\
            end \
            cloneZones.invokeCallbacks(theZone, \"will despawn static\", aStatic)\
            Object.destroy(aStatic) -- we don't aStatio:destroy() to find out what it is\
        end \
    end\
    theZone.mySpawns = {}\
    theZone.myStatics = {}\
end\
\
function cloneZones.updateLocationsInGroupData(theData, zoneDelta, adjustAllWaypoints)\
    \
    -- remember that zoneDelta's [z] modifies theData's y!!\
    theData.x = theData.x + zoneDelta.x \
    theData.y = theData.y + zoneDelta.z -- !!!\
    local units = theData.units \
    for idx, aUnit in pairs(units) do \
        aUnit.x = aUnit.x + zoneDelta.x \
        aUnit.y = aUnit.y + zoneDelta.z -- again!!!!\
    end\
    -- now modifiy waypoints. we ALWAYS adjust the  \
    -- first waypoint, but only all others if asked \
    -- to \
    local theRoute = theData.route \
    if theRoute then \
        local thePoints = theRoute.points \
        if thePoints and #thePoints > 0 then \
            if adjustAllWaypoints then  \
                for i=1, #thePoints do \
                    thePoints[i].x = thePoints[i].x + zoneDelta.x \
                    thePoints[i].y = thePoints[i].y + zoneDelta.z -- (!!)\
\
                end\
            else \
                -- only first point \
                thePoints[1].x = thePoints[1].x + zoneDelta.x \
                thePoints[1].y = thePoints[1].y + zoneDelta.z -- (!!)\
            end \
            \
            -- if there is an airodrome id given in first waypoint, \
            -- adjust for closest location \
            local firstPoint = thePoints[1]\
            if firstPoint.airdromeId then \
                trigger.action.outText(\"first: airdrome adjust for \" .. theData.name .. \" now is \" .. firstPoint.airdromeId, 30)\
                local loc = {}\
                loc.x = firstPoint.x\
                loc.y = 0\
                loc.z = firstPoint.y \
                local bestAirbase = dcsCommon.getClosestAirbaseTo(loc)\
                firstPoint.airdromeId = bestAirbase:getID()\
                trigger.action.outText(\"first: adjusted to \" .. firstPoint.airdromeId, 30)\
            end\
            \
            -- adjust last point (landing)\
            if #thePoints > 1 then \
                local lastPoint = thePoints[#thePoints]\
                if firstPoint.airdromeId then \
                    trigger.action.outText(\"last: airdrome adjust for \" .. theData.name .. \" now is \" .. lastPoint.airdromeId, 30)\
                    local loc = {}\
                    loc.x = lastPoint.x\
                    loc.y = 0\
                    loc.z = lastPoint.y \
                    local bestAirbase = dcsCommon.getClosestAirbaseTo(loc)\
                    lastPoint.airdromeId = bestAirbase:getID()\
                    trigger.action.outText(\"last: adjusted to \" .. lastPoint.airdromeId, 30)\
                end\
            \
            end\
        end\
    end\
end\
function cloneZones.uniqueID()\
    local uid = cloneZones.uniqueCounter\
    cloneZones.uniqueCounter = cloneZones.uniqueCounter + 1\
    return uid \
end\
\
function cloneZones.uniqueNameGroupData(theData)  \
    theData.name = dcsCommon.uuid(theData.name)\
    local units = theData.units \
    for idx, aUnit in pairs(units) do \
        aUnit.name = dcsCommon.uuid(aUnit.name)\
    end \
end \
\
function cloneZones.uniqueIDGroupData(theData)\
    theData.groupId = cloneZones.uniqueID()\
end\
\
function cloneZones.uniqueIDUnitData(theData)\
    if not theData then return end \
    if not theData.units then return end \
    local units = theData.units \
    for idx, aUnit in pairs(units) do \
        aUnit.CZorigID = aUnit.unitId \
        aUnit.unitId = cloneZones.uniqueID()\
        aUnit.CZTargetID = aUnit.unitId\
    end \
\
end\
\
function cloneZones.resolveOwnership(spawnZone, ctry)\
    if not spawnZone.masterOwner then return ctry end \
\
    local masterZone = cfxZones.getZoneByName(spawnZone.masterOwner)\
    if not masterZone then \
        trigger.action.outText(\"+++clnZ: cloner \" .. spawnZone.name .. \" could not fine master owner <\" .. spawnZone.masterOwner .. \">\", 30)\
        return ctry \
    end\
    \
    if not masterZone.owner then \
        return ctry \
    end\
    \
    ctry = dcsCommon.getACountryForCoalition(masterZone.owner)\
    return ctry \
end\
\
--\
-- resolve external group references \
-- \
\
function cloneZones.resolveGroupID(gID, rawData, dataTable, reason)\
    local resolvedID = gID\
    local myOName = rawData.CZorigName\
    local groupName = cfxMX.groupNamesByID[gID]\
    --trigger.action.outText(\"Resolve for <\" .. myOName .. \"> the external ID: \" .. gID .. \" --> \" .. groupName .. \" for <\" .. reason.. \"> task\", 30)\
    \
    -- first, check if this an internal reference, i.e. inside the same \
    -- zone template \
    for idx, otherData in pairs(dataTable) do\
        -- look in own data table \
        if otherData.CZorigName == groupName then \
            -- using cfxMX for clarity only (name access)\
            resolvedID = otherData.CZTargetID\
            --trigger.action.outText(\"resolved (internally) \" .. gID .. \" to \" .. resolvedID, 30)\
            return resolvedID\
        end\
    end\
    \
    -- now check if we have spawned this before \
    local lastClone = cloneZones.groupXlate[gID]\
    if lastClone then \
        resolvedID = lastClone\
        --trigger.action.outText(\"resolved (EXT) \" .. gID .. \" to \" .. resolvedID, 30)\
        return resolvedID    \
    end\
    \
    -- if we get here, reference is not to a cloned item \
    --trigger.action.outText(\"resolved \" .. gID .. \" to \" .. resolvedID, 30)\
    return resolvedID\
end \
\
function cloneZones.resolveUnitID(uID, rawData, dataTable, reason)\
-- also resolves statics as they share ID with units \
    local resolvedID = uID\
    --trigger.action.outText(\"Resolve reference to unitId <\" .. uID .. \"> for <\" .. reason.. \"> task\", 30)\
    \
    -- first, check if this an internal reference, i.e. inside the same \
    -- zone template \
    for idx, otherData in pairs(dataTable) do\
        -- iterate all units\
        for idy, aUnit in pairs(otherData.units) do \
            if aUnit.CZorigID == uID then \
                resolvedID = aUnit.CZTargetID\
                --trigger.action.outText(\"resolved (internally) \" .. uID .. \" to \" .. resolvedID, 30)\
                return resolvedID\
            end\
        end        \
\
    end\
    \
    -- now check if we have spawned this before \
    local lastClone = cloneZones.unitXlate[uID]\
    if lastClone then \
        resolvedID = lastClone\
        --trigger.action.outText(\"resolved (U-EXT) \" .. uID .. \" to \" .. resolvedID, 30)\
        return resolvedID    \
    end\
    \
    -- if we get here, reference is not to a cloned item \
    --trigger.action.outText(\"resolved G-\" .. uID .. \" to \" .. resolvedID, 30)\
    return resolvedID\
end \
\
function cloneZones.resolveStaticLinkUnit(uID)\
    local resolvedID = uID\
    local lastClone = cloneZones.unitXlate[uID]\
    if lastClone then \
        resolvedID = lastClone\
        --trigger.action.outText(\"resolved (U-EXT) \" .. uID .. \" to \" .. resolvedID, 30)\
        return resolvedID    \
    end\
    return resolvedID\
end\
\
function cloneZones.resolveWPReferences(rawData, theZone, dataTable)\
-- check to see if we really need data table, as we have theZone \
-- perform a check of route for group or unit references \
    if not rawData then return end \
    local myOName = rawData.CZorigName \
\
    if rawData.route and rawData.route.points then \
        local points = rawData.route.points \
        for idx, aPoint in pairs(points) do \
            -- check if there is a link unit here and resolve \
            if aPoint.linkUnit then \
                local gID = aPoint.linkUnit\
                local resolvedID = cloneZones.resolveUnitID(gID, rawData, dataTable, \"linkUnit\")\
                aPoint.linkUnit = resolvedID\
                --trigger.action.outText(\"resolved link unit to \"..resolvedID .. \" for \" .. rawData.name, 30)\
            end\
            \
            -- iterate all tasks assigned to point\
            local task = aPoint.task\
            if task and task.params and task.params.tasks then\
                local tasks = task.params.tasks \
                for idy, taskData in pairs(tasks) do\
                    -- resolve group references in TASKS\
                    if taskData.id and taskData.params and taskData.params.groupId\
                    then \
                        -- we resolve group reference \
                        local gID = taskData.params.groupId\
                        local resolvedID = cloneZones.resolveGroupID(gID, rawData, dataTable, taskData.id)\
                        taskData.params.groupId = resolvedID\
                        \
                    end\
                    \
                    -- resolve unit references in TASKS\
                    if taskData.id and taskData.params and taskData.params.unitId\
                    then \
                        -- we don't look for keywords, we simply resolve \
                        local uID = taskData.params.unitId \
                        local resolvedID = cloneZones.resolveUnitID(uID, rawData, dataTable, taskData.id)\
                        taskData.params.unitId = resolvedID\
                    end\
                    \
                    -- resolve unit references in ACTIONS\
                    if taskData.params and taskData.params.action and \
                    taskData.params.action.params and taskData.params.action.params.unitId then \
                        local uID = taskData.params.action.params.unitId \
                        local resolvedID = cloneZones.resolveUnitID(uID, rawData, dataTable, \"Action\")\
                        taskData.params.action.params.unitId = resolvedID\
                    end\
                end    \
            end\
        end\
    end \
end \
\
function cloneZones.resolveReferences(theZone, dataTable) \
    -- when an action refers to another group, we check if \
    -- the group referred to is also a clone, and update \
    -- the reference to the newest incardnation \
    \
    for idx, rawData in pairs(dataTable) do \
        -- resolve references in waypoints\
        cloneZones.resolveWPReferences(rawData, theZone, dataTable)\
    end\
end\
\
function cloneZones.spawnWithTemplateForZone(theZone, spawnZone)\
    -- theZone is the cloner with the template\
    -- spawnZone is the spawner with settings \
    --if not spawnZone then spawnZone = theZone end \
    local newCenter = cfxZones.getPoint(spawnZone) \
    -- calculate zoneDelta, is added to all vectors \
    local zoneDelta = dcsCommon.vSub(newCenter, theZone.origin)\
    \
    local spawnedGroups = {}\
    local spawnedStatics = {}\
    local dataToSpawn = {}\
    \
    for idx, aGroupName in pairs(theZone.cloneNames) do \
        local rawData, cat, ctry = cfxMX.getGroupFromDCSbyName(aGroupName)\
        rawData.CZorigName = rawData.name -- save original group name\
        local origID = rawData.groupId -- save original group ID \
        rawData.CZorigID = origID \
        cloneZones.uniqueIDGroupData(rawData) -- assign unique ID we know \
        cloneZones.uniqueIDUnitData(rawData) -- assign unique ID for units -- saves old unitId as CZorigID\
        rawData.CZTargetID = rawData.groupId -- save \
        if rawData.name ~= aGroupName then \
            trigger.action.outText(\"Clone: FAILED name check\", 30)\
        end\
        \
        -- now use raw data to spawn and see if it works outabox\
        local theCat = cfxMX.catText2ID(cat)\
        rawData.CZtheCat = theCat -- save cat \
        \
        -- update their position if not spawning to exact same location \
        cloneZones.updateLocationsInGroupData(rawData, zoneDelta, spawnZone.moveRoute)\
        \
        -- apply turning \
        dcsCommon.rotateGroupData(rawData, spawnZone.turn, newCenter.x, newCenter.z)\
        \
        -- make sure unit and group names are unique \
        cloneZones.uniqueNameGroupData(rawData)\
        \
        -- see what country we spawn for\
        ctry = cloneZones.resolveOwnership(spawnZone, ctry)\
        rawData.CZctry = ctry -- save ctry \
        table.insert(dataToSpawn, rawData)\
    end \
    \
    -- now resolve references to other cloned units for all raw data\
    -- we must do this BEFORE we spawn\
    cloneZones.resolveReferences(theZone, dataToSpawn)\
    \
    -- now spawn all raw data \
    for idx, rawData in pairs (dataToSpawn) do \
        -- now spawn and save to clones\
        local theGroup = coalition.addGroup(rawData.CZctry, rawData.CZtheCat, rawData)\
        table.insert(spawnedGroups, theGroup)\
        \
        --trigger.action.outText(\"spawned group \" .. rawData.name .. \"consisting of\", 30)\
        \
        -- update groupXlate table \
        local newGroupID = theGroup:getID() -- new ID assigned by DCS\
        local origID = rawData.CZorigID -- before we materialized\
        cloneZones.groupXlate[origID] = newGroupID\
        -- now also save all units for references     \
        -- and verify assigned vs target ID \
        for idx, aUnit in pairs(rawData.units) do \
            -- access the proposed name \
            local uName = aUnit.name \
            local gUnit = Unit.getByName(uName)\
            if gUnit then \
                -- unit exists. compare planned and assigned ID\
                local uID = tonumber(gUnit:getID())\
                if uID == aUnit.CZTargetID then \
                    --trigger.action.outText(\"unit \" .. uName .. \"#\"..uID, 30)\
                    -- all good \
                else \
                    trigger.action.outText(\"clnZ: post-clone verification failed for unit <\" .. uName .. \">: ÎD mismatch: \" .. uID .. \" -- \" .. aUnit.CZTargetID, 30)\
                end \
                cloneZones.unitXlate[aUnit.CZorigID] = uID \
            else \
                trigger.action.outText(\"clnZ: post-clone verifiaction failed for unit <\" .. uName .. \">: not found\", 30) \
            end \
        end\
        \
        -- check if our assigned ID matches the handed out by \
        -- DCS\
        if newGroupID == rawData.CZTargetID then \
            -- we are good\
        else \
            trigger.action.outText(\"clnZ: MISMATCH \" .. rawData.name .. \" target ID \" .. rawData.CZTargetID .. \" does not match \" .. newGroupID, 30)\
        end \
\
        cloneZones.invokeCallbacks(theZone, \"did spawn group\", theGroup)\
    end\
\
    -- static spawns \
    for idx, aStaticName in pairs(theZone.staticNames) do \
        local rawData, cat, ctry, parent = cfxMX.getStaticFromDCSbyName(aStaticName) -- returns a UNIT data block\
        \
        if not rawData then\
            trigger.action.outText(\"Static Clone: no such group <\"..aStaticName .. \">\", 30)            \
        elseif rawData.name == aStaticName then \
            -- all good\
        else \
            trigger.action.outText(\"Static Clone: FAILED name check for <\" .. aStaticName .. \">\", 30)\
        end\
        local origID = rawData.unitId -- save original unit ID\
        rawData.CZorigID = origID \
                \
        -- now use raw data to spawn and see if it works outabox\
        --local theCat = cfxMX.catText2ID(cat) -- will be \"static\"\
        \
        -- move origin \
        rawData.x = rawData.x + zoneDelta.x \
        rawData.y = rawData.y + zoneDelta.z -- !!!\
    \
        -- apply turning \
        dcsCommon.rotateUnitData(rawData, spawnZone.turn, newCenter.x, newCenter.z)\
        \
        -- make sure static name is unique and remember original \
        rawData.name = dcsCommon.uuid(rawData.name)\
        rawData.unitId = cloneZones.uniqueID()  \
        rawData.CZTargetID = rawData.unitId \
        \
        -- see what country we spawn for\
        ctry = cloneZones.resolveOwnership(spawnZone, ctry)\
        \
        -- handle linkUnit if provided  \
        if rawData.linkUnit then \
            --trigger.action.outText(\"has link to \" .. rawData.linkUnit, 30)\
            local lU = cloneZones.resolveStaticLinkUnit(rawData.linkUnit)\
            --trigger.action.outText(\"resolved to \" .. lU, 30)\
            rawData.linkUnit = lU \
            if not rawData.offsets then \
                rawData.offsets = {}\
                rawData.offsets.angle = 0\
                rawData.offsets.x = 0\
                rawData.offsets.y = 0\
                --trigger.action.outText(\"clnZ: link required offset for \" .. rawData.name, 30)\
            end \
            rawData.offsets.y = rawData.offsets.y - zoneDelta.z \
            rawData.offsets.x = rawData.offsets.x - zoneDelta.x \
            rawData.offsets.angle = rawData.offsets.angle + spawnZone.turn\
            rawData.linkOffset = true \
--            trigger.action.outText(\"zone deltas are \" .. zoneDelta.x .. \", \" .. zoneDelta.y, 30)\
        end\
        \
        local theStatic = coalition.addStaticObject(ctry, rawData)\
        local newStaticID = tonumber(theStatic:getID()) \
        table.insert(spawnedStatics, theStatic)\
        -- we don't mix groups with units, so no lookup tables for \
        -- statics \
        if newStaticID == rawData.CZTargetID then \
--            trigger.action.outText(\"Static ID OK: \" .. newStaticID  .. \" for \" .. rawData.name, 30)\
        else \
            trigger.action.outText(\"Static ID mismatch: \" .. newStaticID .. \" vs (target) \" .. rawData.CZTargetID .. \" for \" .. rawData.name, 30)\
        end\
        cloneZones.unitXlate[origID] = newStaticID -- same as units \
        \
        cloneZones.invokeCallbacks(theZone, \"did spawn static\", theStatic)\
        --]]--\
        if cloneZones.verbose then \
            trigger.action.outText(\"Static spawn: spawned \" .. aStaticName, 30)\
        end \
    end    \
    local args = {}\
    args.groups = spawnedGroups\
    args.statics = spawnedStatics\
    cloneZones.invokeCallbacks(theZone, \"spawned\", args)\
    return spawnedGroups, spawnedStatics \
end\
\
function cloneZones.spawnWithCloner(theZone) \
    if not theZone then \
        trigger.action.outText(\"+++clnZ: nil zone on spawnWithCloner\", 30)\
        return \
    end\
    if not theZone.cloner then \
        trigger.action.outText(\"+++clnZ: spawnWithCloner invoked with non-cloner <\" .. theZone.name .. \">\", 30)\
        return \
    end \
    \
    -- force spawn with this spawner \
    local templateZone = theZone\
    if theZone.source then \
        -- we use a different zone for templates\
        -- souce can be a comma separated list\
        local templateName = theZone.source\
        if dcsCommon.containsString(templateName, \",\") then \
            local allNames = templateName \
            local templates = dcsCommon.splitString(templateName, \",\")\
            templateName = dcsCommon.pickRandom(templates)\
            templateName = dcsCommon.trim(templateName) \
            if cloneZones.verbose then \
                trigger.action.outText(\"+++clnZ: picked random template <\" .. templateName ..\"> for from <\" .. allNames .. \"> for cloner \" .. theZone.name, 30)\
            end \
        end\
        \
        local newTemplate = cloneZones.getCloneZoneByName(templateName)\
        if not newTemplate then \
            if cloneZones.verbose then \
                trigger.action.outText(\"+++clnZ: no clone source with name <\" .. templateName ..\"> for cloner \" .. theZone.name, 30)\
            end  \
            return \
        end\
        templateZone = newTemplate \
    end\
    \
    -- make sure our template is filled \
    if not templateZone.cloneNames then \
        if cloneZones.verbose then \
            trigger.action.outText(\"+++clnZ: clone source template <\".. templateZone.name .. \"> for clone zone <\" .. theZone.name ..\"> is empty\", 30)\
        end \
        return \
    end\
\
    -- pre-Wipe?\
    if theZone.preWipe then \
        cloneZones.despawnAll(theZone)\
        cloneZones.invokeCallbacks(theZone, \"wiped\", {})\
    end\
    \
\
    local theClones, theStatics = cloneZones.spawnWithTemplateForZone(templateZone, theZone)\
    -- reset hasClones so we know our spawns are full and we can \
    -- detect complete destruction\
    if (theClones and #theClones > 0) or \
       (theStatics and #theStatics > 0)\
    then \
        theZone.hasClones = true \
        theZone.mySpawns = theClones \
        theZone.myStatics = theStatics \
    else \
        theZone.hasClones = false \
        theZone.mySpawns = {}\
        theZone.myStatics = {}\
    end\
end\
\
function cloneZones.countLiveUnits(theZone)\
    if not theZone then return 0 end \
    local count = 0\
    -- count units \
    if theZone.mySpawns then \
        for idx, aGroup in pairs(theZone.mySpawns) do \
            if aGroup:isExist() then \
                local allUnits = aGroup:getUnits()\
                for idy, aUnit in pairs(allUnits) do \
                    if aUnit:isExist() and aUnit:getLife() >= 1 then \
                        count = count + 1\
                    end\
                end\
            end\
        end\
    end\
    \
    -- count statics \
    if theZone.myStatics then \
        for idx, aStatic in pairs(theZone.myStatics) do \
            if aStatic:isExist() and aStatic:getLife() >= 1 then \
                count = count + 1\
            end\
        end\
    end\
    return count \
end\
\
function cloneZones.hasLiveUnits(theZone)\
    if not theZone then return 0 end \
    if theZone.mySpawns then \
        for idx, aGroup in pairs(theZone.mySpawns) do \
            if aGroup:isExist() then \
                local allUnits = aGroup:getUnits()\
                for idy, aUnit in pairs(allUnits) do \
                    if aUnit:isExist() and aUnit:getLife() >= 1 then \
                        return true\
                    end\
                end\
            end\
        end\
    end \
    \
    if theZone.myStatics then \
        for idx, aStatic in pairs(theZone.myStatics) do \
            if aStatic:isExist() and aStatic.getLife() >= 1 then \
                return true \
            end \
        end\
    end\
    \
    return false\
end\
\
-- old code, deprecated\
--[[--\
function cloneZones.pollFlag(flagNum, method)\
    -- we currently ignore method \
    local num = trigger.misc.getUserFlag(flagNum)\
    trigger.action.setUserFlag(flagNum, num+1)\
end\
--]]--\
--\
-- UPDATE\
--\
function cloneZones.update()\
    timer.scheduleFunction(cloneZones.update, {}, timer.getTime() + 1)\
    \
    for idx, aZone in pairs(cloneZones.cloners) do\
        -- see if deSpawn was pulled. Must run before spawn\
        if aZone.deSpawnFlag then \
            local currTriggerVal = cfxZones.getFlagValue(aZone.deSpawnFlag, aZone) -- trigger.misc.getUserFlag(aZone.deSpawnFlag)\
            if currTriggerVal ~= aZone.lastDeSpawnValue then \
                if cloneZones.verbose then \
                    trigger.action.outText(\"+++clnZ: DEspawn triggered for <\" .. aZone.name .. \">\", 30)\
                end \
                cloneZones.despawnAll(aZone)\
                aZone.lastDeSpawnValue = currTriggerVal\
            end\
        end\
        \
        -- see if we got spawn? command\
        if aZone.spawnFlag then \
            local currTriggerVal = cfxZones.getFlagValue(aZone.spawnFlag, aZone) -- trigger.misc.getUserFlag(aZone.spawnFlag)\
            if currTriggerVal ~= aZone.lastSpawnValue\
            then \
                if cloneZones.verbose then \
                    trigger.action.outText(\"+++clnZ: spawn triggered for <\" .. aZone.name .. \">\", 30)\
                end \
                cloneZones.spawnWithCloner(aZone)\
                aZone.lastSpawnValue = currTriggerVal\
            end\
        end\
        \
        -- empty handling \
        local isEmpty = cloneZones.countLiveUnits(aZone) < 1 and aZone.hasClones        \
        if isEmpty then \
            -- see if we need to bang a flag \
            if aZone.emptyFlag then \
                --cloneZones.pollFlag(aZone.emptyFlag)\
                cfxZones.pollFlag(aZone.emptyFlag, 'inc', aZone)\
            end \
            \
            if aZone.emptyBangFlag then \
                cfxZones.pollFlag(aZone.emptyBangFlag, aZone.method, aZone)\
                if cloneZones.verbose then \
                    trigger.action.outText(\"+++clnZ: bang! on \" .. aZone.emptyBangFlag, 30)\
                end\
            end\
            -- invoke callbacks \
            cloneZones.invokeCallbacks(aZone, \"empty\", {}) \
            \
            -- prevent isEmpty next pass\
            aZone.hasClones = false \
        end\
        \
    end\
end\
\
function cloneZones.onStart()\
    --trigger.action.outText(\"+++clnZ: Enter atStart\", 30)\
    for idx, theZone in pairs(cloneZones.cloners) do \
        if theZone.onStart then \
            if cloneZones.verbose then \
                trigger.action.outText(\"+++clnZ: atStart will spawn for <\"..theZone.name .. \">\", 30)\
            end\
            cloneZones.spawnWithCloner(theZone) \
            \
        end \
    end\
end\
\
--\
-- START \
--\
function cloneZones.readConfigZone()\
    local theZone = cfxZones.getZoneByName(\"cloneZonesConfig\") \
    if not theZone then \
        if cloneZones.verbose then \
            trigger.action.outText(\"+++clnZ: NO config zone!\", 30)\
        end \
        return \
    end \
    \
    cloneZones.verbose = cfxZones.getBoolFromZoneProperty(theZone, \"verbose\", false)\
    \
    if cloneZones.verbose then \
        trigger.action.outText(\"+++clnZ: read config\", 30)\
    end \
end\
\
function cloneZones.start()\
    -- lib check\
    if not dcsCommon.libCheck then \
        trigger.action.outText(\"cfx Clone Zones requires dcsCommon\", 30)\
        return false \
    end \
    if not dcsCommon.libCheck(\"cfx Clone Zones\", \
        cloneZones.requiredLibs) then\
        return false \
    end\
    \
    -- read config \
    cloneZones.readConfigZone()\
    \
    -- process cloner Zones \
    local attrZones = cfxZones.getZonesWithAttributeNamed(\"cloner\")\
    \
    -- now create an rnd gen for each one and add them\
    -- to our watchlist \
    for k, aZone in pairs(attrZones) do \
        cloneZones.createClonerWithZone(aZone) -- process attribute and add to zone\
        cloneZones.addCloneZone(aZone) -- remember it so we can smoke it\
    end\
    \
    -- run through onStart \
    cloneZones.onStart() \
    \
    -- start update \
    cloneZones.update()\
    \
    trigger.action.outText(\"cfx Clone Zones v\" .. cloneZones.version .. \" started.\", 30)\
    return true \
end\
\
\
-- let's go!\
if not cloneZones.start() then \
    trigger.action.outText(\"cf/x Clone Zones aborted: missing libraries\", 30)\
    cloneZones = nil \
end\
\
--[[-- callback testing \
czcb = {}\
function czcb.callback(theZone, reason, args)\
    trigger.action.outText(\"clone CB: \" .. theZone.name .. \" with \" .. reason, 30)\
end\
cloneZones.addCallback(czcb.callback)\
--]]--\
\
--[[--\
    to resolve tasks \
\
    - AFAC \
        - FAC Assign group \
    - set freq for unit \
--]]--",
                    ["predicate"] = "a_do_script",
                }, -- end of [10]
                [11] = 
                {
                    ["text"] = "messenger = {}\
messenger.version = \"1.1.0\"\
messenger.verbose = false \
messenger.requiredLibs = {\
    \"dcsCommon\", -- always\
    \"cfxZones\", -- Zones, of course \
}\
messenger.messengers = {} \
--[[--\
    Version History\
    1.0.0 - initial version \
    1.0.1 - messageOut? synonym\
          - spelling types in about \
    1.1.0 - DML flag support \
          - clearScreen option\
          - inValue?\
          - message preprocessor \
    \
--]]--\
\
function messenger.addMessenger(theZone)\
    table.insert(messenger.messengers, theZone)\
end\
\
function messenger.getMessengerByName(aName) \
    for idx, aZone in pairs(messenger.messengers) do \
        if aName == aZone.name then return aZone end \
    end\
    if messenger.verbose then \
        trigger.action.outText(\"+++msgr: no messenger with name <\" .. aName ..\">\", 30)\
    end \
    \
    return nil \
end\
\
--\
-- read attributes\
--\
function messenger.createMessengerDownWithZone(theZone)\
    -- start val - a range\
    theZone.message = cfxZones.getStringFromZoneProperty(theZone, \"message\", \"\") \
\
    theZone.spaceBefore = cfxZones.getBoolFromZoneProperty(theZone, \"spaceBefore\", false)\
    theZone.spaceAfter = cfxZones.getBoolFromZoneProperty(theZone, \"spaceAfter\", false)\
\
    theZone.soundFile = cfxZones.getStringFromZoneProperty(theZone, \"soundFile\", \"<none>\") \
\
    theZone.clearScreen = cfxZones.getBoolFromZoneProperty(theZone, \"clearScreen\", false)\
    \
    -- alternate version: messages: list of messages, need string parser first\
    \
    theZone.duration = cfxZones.getNumberFromZoneProperty(theZone, \"duration\", 30)\
    \
    -- trigger flag f? in? messageOut?\
    if cfxZones.hasProperty(theZone, \"f?\") then \
        theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, \"f?\", \"none\")\
    end\
    \
    -- can also use in? for counting. we always use triggerMessagerFlag \
    if cfxZones.hasProperty(theZone, \"in?\") then \
        theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, \"in?\", \"none\")\
    end\
    \
    if cfxZones.hasProperty(theZone, \"messageOut?\") then \
        theZone.triggerMessagerFlag = cfxZones.getStringFromZoneProperty(theZone, \"messageOut?\", \"none\")\
    end\
    \
    if theZone.triggerMessagerFlag then \
        theZone.lastMessageTriggerValue = cfxZones.getFlagValue(theZone.triggerMessagerFlag, theZone)-- trigger.misc.getUserFlag(theZone.triggerMessagerFlag) -- save last value\
    end\
    \
    if cfxZones.hasProperty(theZone, \"coalition\") then \
        theZone.coalition = cfxZones.getCoalitionFromZoneProperty(theZone, \"coalition\", 0)\
    end \
    \
    -- flag whose value can be read \
    if cfxZones.hasProperty(theZone, \"messageValue?\") then \
        theZone.messageValue = cfxZones.getStringFromZoneProperty(theZone, \"messageValue?\", \"<none>\") \
    end\
    \
end\
\
--\
-- Update \
--\
function messenger.getMessage(theZone)\
    local msg = theZone.message\
    -- see if it has a \"$val\" in there \
    local zName = theZone.name \
    if not zName then zName = \"<strange!>\" end \
    local zVal = \"<n/a>\"\
    if theZone.messageValue then \
        zVal = cfxZones.getFlagValue(theZone.messageValue, theZone)\
        zVal = tostring(zVal)\
        if not zVal then zVal = \"<err>\" end \
    end \
    \
    \
    -- replace *zone and *value wildcards \
    msg = string.gsub(msg, \"*name\", zName)\
    msg = string.gsub(msg, \"*value\", zVal)\
    \
    return msg \
end\
\
function messenger.isTriggered(theZone)\
    -- this module has triggered \
    local fileName = \"l10n/DEFAULT/\" .. theZone.soundFile\
    local msg = messenger.getMessage(theZone)\
    \
    if theZone.spaceBefore then msg = \"\\n\"..msg end \
    if theZone.spaceAfter then msg = msg .. \"\\n\" end \
    \
    if theZone.coalition then \
        trigger.action.outTextForCoalition(theZone.coalition, msg, theZone.duration, theZone.clearScreen)\
        trigger.action.outSoundForCoalition(theZone.coalition, fileName)\
    else \
        -- out to all \
        trigger.action.outText(msg, theZone.duration, theZone.clearScreen)\
        trigger.action.outSound(fileName)\
    end\
end\
\
function messenger.update()\
    -- call me in a second to poll triggers\
    timer.scheduleFunction(messenger.update, {}, timer.getTime() + 1)\
        \
    for idx, aZone in pairs(messenger.messengers) do\
        -- make sure to re-start before reading time limit\
        if aZone.triggerMessagerFlag then \
            local currTriggerVal = cfxZones.getFlagValue(aZone.triggerMessagerFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerMessagerFlag)\
            if currTriggerVal ~= aZone.lastMessageTriggerValue\
            then \
                if messenger.verbose then \
                    trigger.action.outText(\"+++msgr: triggered on in?\", 30)\
                end\
                messenger.isTriggered(aZone)\
                aZone.lastMessageTriggerValue = cfxZones.getFlagValue(aZone.triggerMessagerFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerMessagerFlag) -- save last value\
            end\
        end\
    end\
end\
\
--\
-- Config & Start\
--\
function messenger.readConfigZone()\
    local theZone = cfxZones.getZoneByName(\"messengerConfig\") \
    if not theZone then \
        if messenger.verbose then \
            trigger.action.outText(\"+++msgr: NO config zone!\", 30)\
        end \
        return \
    end \
    \
    messenger.verbose = cfxZones.getBoolFromZoneProperty(theZone, \"verbose\", false)\
    \
    if messenger.verbose then \
        trigger.action.outText(\"+++msgr: read config\", 30)\
    end \
end\
\
function messenger.start()\
    -- lib check\
    if not dcsCommon.libCheck then \
        trigger.action.outText(\"cfx Messenger requires dcsCommon\", 30)\
        return false \
    end \
    if not dcsCommon.libCheck(\"cfx Messenger\", messenger.requiredLibs) then\
        return false \
    end\
    \
    -- read config \
    messenger.readConfigZone()\
    \
    -- process cloner Zones \
    local attrZones = cfxZones.getZonesWithAttributeNamed(\"messenger\")\
    for k, aZone in pairs(attrZones) do \
        messenger.createMessengerDownWithZone(aZone) -- process attributes\
        messenger.addMessenger(aZone) -- add to list\
    end\
    \
    -- start update \
    messenger.update()\
    \
    trigger.action.outText(\"cfx Messenger v\" .. messenger.version .. \" started.\", 30)\
    return true \
end\
\
-- let's go!\
if not messenger.start() then \
    trigger.action.outText(\"cfx Messenger aborted: missing libraries\", 30)\
    messenger = nil \
end\
\
--[[--\
Wildcard extension: \
  messageValue supports multiple flags like 1-3, *hi ther, *bingo and then *value[name] returns that value     \
--]]--",
                    ["predicate"] = "a_do_script",
                }, -- end of [11]
                [12] = 
                {
                    ["text"] = "countDown = {}\
countDown.version = \"1.2.1\"\
countDown.verbose = true \
countDown.ups = 1 \
countDown.requiredLibs = {\
    \"dcsCommon\", -- always\
    \"cfxZones\", -- Zones, of course \
}\
\
--[[--\
    count down on flags to generate new signal on out \
    Copyright (c) 2022 by Christian Franz and cf/x AG\
    \
    Version History\
    1.0.0 - initial version \
    1.1.0 - Lua interface: callbacks \
          - corrected verbose (erroneously always suppressed)\
          - triggerFlag --> triggerCountFlag \
    1.1.1 - corrected bug in invokeCallback \
    1.2.0 - DML Flags \
          - counterOut!\
          - ups config \
    1.2.1 - disableCounter?\
    \
--]]--\
\
countDown.counters = {}\
countDown.callbacks = {}\
\
--\
-- add/remove zones\
--\
function countDown.addCountDown(theZone)\
    table.insert(countDown.counters, theZone)\
end\
\
function countDown.getCountDownZoneByName(aName) \
    for idx, aZone in pairs(countDown.counters) do \
        if aName == aZone.name then return aZone end \
    end\
    if countDown.verbose then \
        trigger.action.outText(\"+++cntD: no count down with name <\" .. aName ..\">\", 30)\
    end \
    \
    return nil \
end\
\
\
--\
-- callbacks \
--\
function countDown.addCallback(theCallback)\
    if not theCallback then return end \
    table.insert(countDown.callbacks, theCallback)\
end\
\
function countDown.invokeCallbacks(theZone, val, tminus, zero, belowZero, looping)\
    if not val then val = 1 end \
    if not tminus then tminus = false end \
    if not zero then zero = false end \
    if not belowZero then belowZero = false end \
    \
    -- invoke anyone who wants to know that a group \
    -- of people was rescued.\
    for idx, cb in pairs(countDown.callbacks) do \
        cb(theZone, val, tminus, zero, belowZero, looping)\
    end\
end\
--\
-- read attributes\
--\
function countDown.createCountDownWithZone(theZone)\
    -- start val - a range\
    theZone.startMinVal, theZone.startMaxVal = cfxZones.getPositiveRangeFromZoneProperty(theZone, \"countDown\", 1) -- we know this exists\
    theZone.currVal = dcsCommon.randomBetween(theZone.startMinVal, theZone.startMaxVal)\
    \
    if countDown.verbose then \
        trigger.action.outText(\"+++cntD: initing count down <\" .. theZone.name .. \"> with \" .. theZone.currVal, 30)\
    end\
    \
    \
    -- loop \
    theZone.loop = cfxZones.getBoolFromZoneProperty(theZone, \"loop\", false)\
\
    -- extend after zero\
    theZone.belowZero = cfxZones.getBoolFromZoneProperty(theZone, \"belowZero\", false)\
    \
    -- method \
    theZone.method = cfxZones.getStringFromZoneProperty(theZone, \"method\", \"flip\")\
    \
    -- trigger flag \"count\" / \"start?\"\
    if cfxZones.hasProperty(theZone, \"count?\") then \
        theZone.triggerCountFlag = cfxZones.getStringFromZoneProperty(theZone, \"count?\", \"<none>\")\
    end\
\
    \
    -- can also use in? for counting. we always use triggerCountFlag \
    if cfxZones.hasProperty(theZone, \"in?\") then \
        theZone.triggerCountFlag = cfxZones.getStringFromZoneProperty(theZone, \"in?\", \"<none>\")\
    end\
    \
    if theZone.triggerCountFlag then \
        theZone.lastCountTriggerValue = cfxZones.getFlagValue(theZone.triggerCountFlag, theZone) -- trigger.misc.getUserFlag(theZone.triggerCountFlag) -- save last value\
    end\
    \
    -- zero! bang \
    if cfxZones.hasProperty(theZone, \"zero!\") then \
        theZone.zeroFlag = cfxZones.getStringFromZoneProperty(theZone, \"zero!\", \"<none>\")\
    end\
    \
    if cfxZones.hasProperty(theZone, \"out!\") then \
        theZone.zeroFlag = cfxZones.getStringFromZoneProperty(theZone, \"out!\", \"<none>\")\
    end\
    \
    -- TMinus! bang \
    if cfxZones.hasProperty(theZone, \"tMinus!\") then \
        theZone.tMinusFlag = cfxZones.getStringFromZoneProperty(theZone, \"tMinus!\", \"<none>\")\
    end\
    \
    -- counterOut val \
    if cfxZones.hasProperty(theZone, \"counterOut!\") then \
        theZone.counterOut = cfxZones.getStringFromZoneProperty(theZone, \"counterOut!\", \"<none>\")\
    end\
    \
    -- disableFlag \
    theZone.counterDisabled = false \
    if cfxZones.hasProperty(theZone, \"disableCounter?\") then \
        theZone.disableCounterFlag = cfxZones.getStringFromZoneProperty(theZone, \"disableCounter?\", \"<none>\")\
        theZone.disableCounterFlagVal = cfxZones.getFlagValue(theZone.disableCounterFlag, theZone)\
    end\
end\
\
--\
-- Update \
--\
function countDown.isTriggered(theZone)\
    -- this module has triggered \
    local val = theZone.currVal - 1 -- decrease counter \
    if countDown.verbose then \
        trigger.action.outText(\"+++cntD: enter triggered: val now: \" .. val, 30)\
    end\
    local tMinus = false \
    local zero = false \
    local belowZero = false \
    local looping = false \
    \
    if theZone.counterOut then \
        cfxZones.setFlagValue(theZone.counterOut, val, theZone)\
    end\
    \
    if val > 0 then \
        tMinus = true \
        -- see if we need to bang Tminus \
        if theZone.tMinusFlag then \
            if countDown.verbose then \
                trigger.action.outText(\"+++cntD: TMINUTS\", 30)\
            end\
            cfxZones.pollFlag(theZone.tMinusFlag, theZone.method, theZone)\
        end\
        \
    elseif val == 0 then \
        -- reached zero \
        zero = true \
        if theZone.zeroFlag then \
            if countDown.verbose then \
                trigger.action.outText(\"+++cntD: ZERO\", 30)\
            end\
            cfxZones.pollFlag(theZone.zeroFlag, theZone.method, theZone)\
        end\
        \
        if theZone.loop then \
            -- restart time\
            looping = true \
            if countDown.verbose then \
                trigger.action.outText(\"+++cntD: Looping\", 30)\
            end\
            val = dcsCommon.randomBetween(theZone.startMinVal, theZone.startMaxVal)\
        end \
        \
    else \
        -- below zero\
        belowZero = true \
        if theZone.belowZero and theZone.zeroFlag then\
            if countDown.verbose then \
                trigger.action.outText(\"+++cntD: Below Zero\", 30)\
            end\
            cfxZones.pollFlag(theZone.zeroFlag, theZone.method, theZone)\
        end \
        \
    end\
    \
    -- callbacks \
    countDown.invokeCallbacks(theZone, val, tMinus, zero, belowZero, looping)\
    \
    -- update & return \
    theZone.currVal = val \
    \
end\
\
function countDown.update()\
    -- call me in a second/ups to poll triggers\
    timer.scheduleFunction(countDown.update, {}, timer.getTime() + 1/countDown.ups)\
        \
    for idx, aZone in pairs(countDown.counters) do\
        -- make sure to re-start before reading time limit\
        if aZone.triggerCountFlag and not aZone.counterDisabled then \
            local currTriggerVal = cfxZones.getFlagValue(aZone.triggerCountFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerCountFlag)\
            if currTriggerVal ~= aZone.lastCountTriggerValue\
            then \
                if countDown.verbose then \
                    trigger.action.outText(\"+++cntD: triggered on in?\", 30)\
                end\
                countDown.isTriggered(aZone)\
                aZone.lastCountTriggerValue = cfxZones.getFlagValue(aZone.triggerCountFlag, aZone) -- trigger.misc.getUserFlag(aZone.triggerCountFlag) -- save last value\
            end\
        end\
        \
        if aZone.disableCounterFlag then \
            local currVal = cfxZones.getFlagValue(aZone.disableCounterFlag, aZone)\
            if currVal ~= aZone.disableCounterFlagVal then \
                if countDown.verbose then \
                    trigger.action.outText(\"+++cntD: disabling counter \" .. aZone.name, 30)\
                end\
                aZone.counterDisabled = true \
            end\
        end\
    end\
end\
\
--\
-- Config & Start\
--\
function countDown.readConfigZone()\
    local theZone = cfxZones.getZoneByName(\"countDownConfig\") \
    if not theZone then \
        if countDown.verbose then \
            trigger.action.outText(\"+++cntD: NO config zone!\", 30)\
        end \
        return \
    end \
    \
    countDown.ups = cfxZones.getNumberFromZoneProperty(theZone, \"ups\", 1)\
    -- slowest is once avery 1000 seconds = 17 minutes, doesn't make much sense slower than 1/second anyway \
    \
    if countDown.ups < 0.001 then countDown.ups = 0.001 end \
    \
    countDown.verbose = cfxZones.getBoolFromZoneProperty(theZone, \"verbose\", false)\
    \
    if countDown.verbose then \
        trigger.action.outText(\"+++cntD: read config\", 30)\
    end \
end\
\
function countDown.start()\
    -- lib check\
    if not dcsCommon.libCheck then \
        trigger.action.outText(\"cfx Count Down requires dcsCommon\", 30)\
        return false \
    end \
    if not dcsCommon.libCheck(\"cfx Count Down\", countDown.requiredLibs) then\
        return false \
    end\
    \
    -- read config \
    countDown.readConfigZone()\
    \
    -- process cloner Zones \
    local attrZones = cfxZones.getZonesWithAttributeNamed(\"countDown\")\
    for k, aZone in pairs(attrZones) do \
        countDown.createCountDownWithZone(aZone) -- process attributes\
        countDown.addCountDown(aZone) -- add to list\
    end\
    \
    \
    -- start update \
    countDown.update()\
    \
    trigger.action.outText(\"cfx Count Down v\" .. countDown.version .. \" started.\", 30)\
    return true \
end\
\
-- let's go!\
if not countDown.start() then \
    trigger.action.outText(\"cfx Count Down aborted: missing libraries\", 30)\
    countDown = nil \
end\
\
-- additions: range for start value to randomize ",
                    ["predicate"] = "a_do_script",
                }, -- end of [12]
                [13] = 
                {
                    ["text"] = "unitZone={}\
unitZone.version = \"1.0.0\"\
unitZone.verbose = false \
unitZone.ups = 1 \
unitZone.requiredLibs = {\
    \"dcsCommon\", -- always\
    \"cfxZones\", -- Zones, of course \
}\
unitZone.unitZones = {}\
\
function unitZone.addUnitZone(theZone)\
    table.insert(unitZone.unitZones, theZone)\
end\
\
function unitZone.getUnitZoneByName(aName) \
    for idx, aZone in pairs(unitZone.unitZones) do \
        if aName == aZone.name then return aZone end \
    end\
    if unitZone.verbose then \
        trigger.action.outText(\"+++uZne: no unitZone with name <\" .. aName ..\">\", 30)\
    end \
    \
    return nil \
end\
\
function unitZone.string2cat(filterString)\
\
    if not filterString then return 2 end -- default ground \
    filterString = filterString:lower()\
    filterString = dcsCommon.trim(filterString)\
\
    local catNum = tonumber(filterString)\
    if catNum then \
        if catNum < 0 then catNum = 0 end \
        if catNum > 4 then catNum = 4 end \
        return catNum \
    end\
    \
    catNum = 2 -- ground default \
    if dcsCommon.stringStartsWith(filterString, \"grou\") then catNum = 2 end \
    if dcsCommon.stringStartsWith(filterString, \"air\") then catNum = 0 end\
    if dcsCommon.stringStartsWith(filterString, \"hel\") then catNum = 1 end\
    if dcsCommon.stringStartsWith(filterString, \"shi\") then catNum = 3 end\
    if dcsCommon.stringStartsWith(filterString, \"trai\") then catNum = 4 end\
\
    return catNum\
end\
\
function unitZone.createUnitZone(theZone)\
    -- start val - a range\
    theZone.lookFor = cfxZones.getStringFromZoneProperty(theZone, \"lookFor\", \"cfx no unit supplied\") \
    if dcsCommon.stringEndsWith(theZone.lookFor, \"*\") then \
        theZone.lookForBeginsWith = true \
        theZone.lookFor = dcsCommon.removeEnding(theZone.lookFor, \"*\") \
    end\
    \
    theZone.matching = cfxZones.getStringFromZoneProperty(theZone, \"matching\", \"group\") -- group, player [, name, type]\
    theZone.matching = dcsCommon.trim(theZone.matching:lower())\
    if theZone.matching == \"groups\" then theZone.matching = \"group\" end -- some simplification \
    if theZone.matching == \"players\" then theZone.matching = \"player\" end -- some simplification \
\
    theZone.coalition = cfxZones.getCoalitionFromZoneProperty(theZone, \"coalition\", 0) -- 0 = all\
\
    theZone.enterZone = cfxZones.getStringFromZoneProperty(theZone, \"enterZone!\", \"<none>\")\
    theZone.exitZone = cfxZones.getStringFromZoneProperty(theZone, \"exitZone!\", \"<none>\")    \
    theZone.changeZone = cfxZones.getStringFromZoneProperty(theZone, \"changeZone!\", \"<none>\")\
    \
    if cfxZones.hasProperty(theZone, \"filterFor\") then \
        local filterString = cfxZones.getStringFromZoneProperty(theZone, \"filterFor\", \"1\") -- ground \
        theZone.filterFor = unitZone.string2cat(filterString)\
        if unitZone.verbose then \
            trigger.action.outText(\"+++uZne: filtering \" .. theZone.filterFor .. \" in \" .. theZone.name, 30)\
        end \
    end    \
    \
    -- now get initial zone status ?\
    theZone.lastStatus = unitZone.checkZoneStatus(theZone)\
    \
    trigger.action.outText(\"unit zone \" .. theZone.name, 30)\
end\
\
\
--\
-- process zone \
--\
\
function unitZone.collectGroups(theZone)\
    local collector = {}\
    if theZone.matching == \"player\" then \
        -- collect all players matching coalition\
        if theZone.coalition == 1 or theZone.coalition == 0 then \
            local allPlayers = coalition.getPlayers(1)\
            for idx, pUnit in pairs(allPlayers) do \
                table.insert(collector, pUnit)\
            end\
        end \
        if theZone.coalition == 2 or theZone.coalition == 0 then \
            local allPlayers = coalition.getPlayers(2)\
            for idx, pUnit in pairs(allPlayers) do \
                table.insert(collector, pUnit)\
            end\
        end\
    elseif theZone.matching == \"group\" then \
        if theZone.coalition == 1 or theZone.coalition == 0 then \
            local allGroups = coalition.getGroups(1, theZone.filterFor)\
\
            for idx, pUnit in pairs(allGroups) do \
                table.insert(collector, pUnit)\
            end\
        end \
        if theZone.coalition == 2 or theZone.coalition == 0 then \
            local allGroups = coalition.getGroups(2, theZone.filterFor)\
\
            for idx, pUnit in pairs(allGroups) do \
                table.insert(collector, pUnit)\
            end\
        end\
    else \
        trigger.action.outText(\"+++uZne: unknown matching: \" .. theZone.matching, 30)\
        return {}\
    end\
    \
    return collector\
end\
\
function unitZone.checkZoneStatus(theZone)\
    -- returns true (at least one unit found in zone)\
    -- or false (no unit found in zone)\
    \
    -- collect all groups to inspect \
    local theGroups = unitZone.collectGroups(theZone)\
    local lookFor = theZone.lookFor\
    -- now see if the groups match name and then check inside status for each \
    local playerCheck = theZone.matching == \"player\"\
    if playerCheck then \
        -- we check the names for players only \
        for idx, pUnit in pairs(theGroups) do \
            local puName=pUnit:getName()\
            local hasMatch = false \
            if theZone.lookForBeginsWith then \
                hasMatch = dcsCommon.stringStartsWith(puName, lookFor)\
            else \
                hasMatch = puName == lookFor \
            end\
            if hasMatch then \
                if cfxZones.unitInZone(pUnit, theZone) then \
                    return true\
                end\
            end\
        end \
        \
    else \
        -- we perform group cehck \
        for idx, aGroup in pairs(theGroups) do \
            local gName=aGroup:getName()\
            local hasMatch = false \
            if theZone.lookForBeginsWith then \
                hasMatch = dcsCommon.stringStartsWith(gName, lookFor)\
            else \
                hasMatch = gName == lookFor \
            end\
            if hasMatch and aGroup:isExist() then \
                -- check all living units in zone \
                local gUnits = aGroup:getUnits()\
                for idy, aUnit in pairs (gUnits) do\
                    --trigger.action.outText(\"trying \" .. gName,10)\
                    if cfxZones.unitInZone(aUnit, theZone) then \
                        return true\
                    end\
                end\
            end\
        end\
    end\
    return false \
end\
\
--\
-- update \
--\
function unitZone.bangState(theZone, newState)\
    cfxZones.pollFlag(theZone.changeZone, \"inc\", theZone)\
            \
    if newState then \
        cfxZones.pollFlag(theZone.enterZone, \"inc\", theZone)\
    else \
        cfxZones.pollFlag(theZone.exitZone, \"inc\", theZone)\
    end\
end\
\
function unitZone.update()\
    -- call me in a second to poll triggers\
    timer.scheduleFunction(unitZone.update, {}, timer.getTime() + 1/unitZone.ups)\
        \
    for idx, aZone in pairs(unitZone.unitZones) do\
        -- scan all zones \
        local newState = unitZone.checkZoneStatus(aZone)\
\
        if newState ~= aZone.lastStatus then \
            -- bang on change! \
            unitZone.bangState(aZone, newState)\
            aZone.lastStatus = newState \
        end\
    end\
end\
\
--\
-- Config & Start\
--\
function unitZone.readConfigZone()\
    local theZone = cfxZones.getZoneByName(\"unitZoneConfig\") \
    if not theZone then \
        if unitZone.verbose then \
            trigger.action.outText(\"+++uZne: NO config zone!\", 30)\
        end \
        return \
    end \
    \
    unitZone.verbose = cfxZones.getBoolFromZoneProperty(theZone, \"verbose\", false)\
    \
    unitZone.ups = cfxZones.getNumberFromZoneProperty(theZone, \"ups\", 1)\
    \
    if unitZone.verbose then \
        trigger.action.outText(\"+++uZne: read config\", 30)\
    end \
end\
\
function unitZone.start()\
    -- lib check\
    if not dcsCommon.libCheck then \
        trigger.action.outText(\"cfx Unit Zone requires dcsCommon\", 30)\
        return false \
    end \
    if not dcsCommon.libCheck(\"cfx Unit Zone\", unitZone.requiredLibs) then\
        return false \
    end\
    \
    -- read config \
    unitZone.readConfigZone()\
    \
    -- process cloner Zones \
    local attrZones = cfxZones.getZonesWithAttributeNamed(\"unitZone\")\
    for k, aZone in pairs(attrZones) do \
        unitZone.createUnitZone(aZone) -- process attributes\
        unitZone.addUnitZone(aZone) -- add to list\
    end\
    \
    -- start update \
    unitZone.update()\
    \
    trigger.action.outText(\"cfx Unit Zone v\" .. unitZone.version .. \" started.\", 30)\
    return true \
end\
\
-- let's go!\
if not unitZone.start() then \
    trigger.action.outText(\"cfx Unit Zone aborted: missing libraries\", 30)\
    unitZone = nil \
end\
\
--ToDo: add 'neutral' support and add 'both' option \
--ToDo: add API ",
                    ["predicate"] = "a_do_script",
                }, -- end of [13]
                [14] = 
                {
                    ["text"] = "cfxSSBClient = {}\
cfxSSBClient.version = \"2.0.2\"\
cfxSSBClient.verbose = false \
cfxSSBClient.singleUse = false -- set to true to block crashed planes\
-- NOTE: singleUse (true) requires SSB to disable immediate respawn after kick\
cfxSSBClient.reUseAfter = -1 -- seconds for re-use delay\
  -- only when singleUse is in effect. -1 means never \
  \
cfxSSBClient.requiredLibs = {\
    \"dcsCommon\", -- always\
    \"cfxGroups\", -- for slot access\
    \"cfxZones\", -- Zones, of course \
}\
\
--[[--\
Version History\
  1.0.0 - initial version\
  1.1.0 - detect airfield by action and location, not group name\
  1.1.1 - performance tuning. only read player groups once \
        - and remove in-air-start groups from scan. this requires\
        - ssb (server) be not modified    \
  1.2.0 - API to close airfields: invoke openAirfieldNamed() \
          and closeAirfieldNamed() with name as string (exact match required)\
          to block an airfield for any player aircraft.\
          Works for FARPS as well \
          API to associate a player group with any airfied's status (nil for unbind):\
          cfxSSBClient.bindGroupToAirfield(group, airfieldName)\
          API shortcut to unbind groups: cfxSSBClient.unbindGroup(group) \
          verbose messages now identify better: \"+++SSB:\"\
          keepInAirGroups option \
  2.0.0 - include single-use ability: crashed airplanes are blocked from further use\
        - single-use can be turned off \
        - getPlayerGroupForGroupNamed()\
        - split setSlotAccess to single accessor \
          and interator\
        - reUseAfter option for single-use  \
        - dcsCommon, cfxZones import\
  2.0.1 - stricter verbosity: moved more comments to verbose only \
  2.0.2 - health check code (initial) \
        - added verbosity\
    \
WHAT IT IS\
SSB Client is a small script that forms the client-side counterpart to\
Ciribob's simple slot block. It will block slots for all client airframes\
that are on an airfield that does not belong to the faction that currently\
owns the airfield. \
\
REQUIRES CIRIBOB's SIMPLE SLOT BLOCK (SSB) TO RUN ON THE SERVER\
\
If run without SSB, your planes will not be blocked.\
\
In order to work, a plane that should be blocked when the airfield or \
FARP doesn't belong to the player's faction, the group's first unit\
must be within 3000 meters of the airfield and on the ground. \
Previous versions of this script relied on group names. No longer.\
\
\
WARNING:\
If you modified ssb's flag values, this script will not work \
\
YOU DO NOT NEED TO ACTIVATE SBB, THIS SCRIPT DOES SO AUTOMAGICALLY\
\
\
--]]--\
\
-- below value for enabled MUST BE THE SAME AS THE VALUE OF THE SAME NAME \
-- IN SSB. DEFAULT IS ZERO, AND THIS WILL WORK\
\
cfxSSBClient.enabledFlagValue = 0 -- DO NOT CHANGE, MUST MATCH SSB \
cfxSSBClient.disabledFlagValue = cfxSSBClient.enabledFlagValue + 100 -- DO NOT CHANGE\
cfxSSBClient.allowNeutralFields = false -- set to FALSE if players can't spawn on neutral airfields \
cfxSSBClient.maxAirfieldRange = 3000 -- meters to airfield before group is no longer associated with airfield \
-- actions to home in on when a player plane is detected and a slot may \
-- be blocked. Currently, homing in on airfield, but not fly over \
cfxSSBClient.slotActions = {\
    \"From Runway\",\
    \"From Parking Area\",\
    \"From Parking Area Hot\",\
    \"From Ground Area\",\
    \"From Ground Area Hot\",\
}\
cfxSSBClient.keepInAirGroups = false -- if false we only look at planes starting on the ground \
-- setting this to true only makes sense if you plan to bind in-air starts to airfields \
\
cfxSSBClient.playerGroups = {}\
cfxSSBClient.closedAirfields = {} -- list that closes airfields for any aircrafts\
cfxSSBClient.playerPlanes = {} -- names of units that a player is flying\
cfxSSBClient.crashedGroups = {} -- names of groups to block after crash of their player-flown plane \
\
\
function cfxSSBClient.closeAirfieldNamed(name)\
    if not name then return end \
    cfxSSBClient.closedAirfields[name] = true \
    cfxSSBClient.setSlotAccessByAirfieldOwner()\
    if cfxSSBClient.verbose then \
        trigger.action.outText(\"+++SSB: Airfield \" .. name .. \" now closed\", 30) \
    end\
end\
\
function cfxSSBClient.openAirFieldNamed(name)\
    cfxSSBClient.closedAirfields[name] = nil \
    cfxSSBClient.setSlotAccessByAirfieldOwner()\
    if cfxSSBClient.verbose then \
        trigger.action.outText(\"+++SSB: Airfield \" .. name .. \" just opened\", 30) \
    end\
end\
\
function cfxSSBClient.unbindGroup(groupName)\
    cfxSSBClient.bindGroupToAirfield(groupName, nil)\
end\
\
function cfxSSBClient.bindGroupToAirfield(groupName, airfieldName)\
    if not groupName then return end \
    local airfield = nil\
    if airfieldName then airfield = Airbase.getByName(airfieldName) end \
    for idx, theGroup in pairs(cfxSSBClient.playerGroups) do\
        if theGroup.name == groupName then \
            if cfxSSBClient.verbose then\
                local newBind = \"NIL\"\
                if airfield then newBind = airfieldName end \
                trigger.action.outText(\"+++SSB: Group \" .. theGroup.name .. \" changed binding to \" .. newBind, 30) \
            end\
            theGroup.airfield = airfield\
            return\
        end\
    end\
    if not airfieldName then airfieldName = \"<NIL>\" end \
    trigger.action.outText(\"+++SSB: Binding Group \" .. groupName .. \" to \" .. airfieldName .. \" failed.\", 30) \
end\
\
\
function cfxSSBClient.getClosestAirbaseTo(thePoint)\
    local delta = math.huge\
    local allYourBase = world.getAirbases() -- get em all\
    local closestBase = nil \
    for idx, aBase in pairs(allYourBase) do\
        -- iterate them all \
        local abPoint = aBase:getPoint()\
        newDelta = dcsCommon.dist(thePoint, {x=abPoint.x, y = 0, z=abPoint.z})\
        if newDelta < delta then \
            delta = newDelta\
            closestBase = aBase\
        end\
    end\
    return closestBase, delta \
end\
\
function cfxSSBClient.setSlotAccessForGroup(theGroup)\
    if not theGroup then return end \
    -- WARNING: theGroup is cfxGroup record  \
    local theName = theGroup.name \
    local theMatchingAirfield = theGroup.airfield \
    -- airfield was attached at startup to group \
    if cfxSSBClient.singleUse and cfxSSBClient.crashedGroups[theName] then \
       -- we don't check, as we know it's blocked after crash \
       -- and leave it as it is. Nothing to do at all now\
           \
    elseif theMatchingAirfield ~= nil then \
        -- we have found a plane that is tied to an airfield \
        -- so this group will receive a block/unblock\
        -- we always set all block/unblock every time\
        -- note: since caching, above guard not needed\
        local airFieldSide = theMatchingAirfield:getCoalition()\
        local groupCoalition = theGroup.coaNum\
        local blockState = cfxSSBClient.enabledFlagValue -- we default to ALLOW the block\
        local comment = \"available\"\
            \
        -- see if airfield is closed \
        local afName = theMatchingAirfield:getName()\
        if cfxSSBClient.closedAirfields[afName] then \
            -- airfield is closed. no take-offs \
            blockState = cfxSSBClient.disabledFlagValue\
            comment = \"!closed airfield!\"\
        end\
            \
        -- on top of that, check coalitions\
        if groupCoalition ~= airFieldSide then \
            -- we have a problem. sides don't match \
            if airFieldSide == 3 \
            or (cfxSSBClient.allowNeutralFields and airFieldSide == 0)\
            then \
                -- all is well, airfield is contested or neutral and \
                -- we allow this plane to spawn here\
            else \
                -- DISALLOWED!!!!\
                blockState = cfxSSBClient.disabledFlagValue\
                comment = \"!!!BLOCKED!!!\"\
            end\
        end \
        -- set the ssb flag for this group so the server can see it\
        trigger.action.setUserFlag(theName, blockState)\
        if cfxSSBClient.verbose then \
            trigger.action.outText(\"+++SSB: group \".. theName .. \": \" .. comment, 30)\
        end \
    else \
        if cfxSSBClient.verbose then \
            trigger.action.outText(\"+++SSB: group \".. theName .. \" no bound airfield: available\", 30)\
        end\
    end\
end\
\
function cfxSSBClient.getPlayerGroupForGroupNamed(aName)\
    local pGroups = cfxSSBClient.playerGroups\
    for idx, theGroup in pairs(pGroups) do\
        if theGroup.name == aName then return theGroup end \
    end\
    return nil \
end\
\
function cfxSSBClient.setSlotAccessByAirfieldOwner()\
    -- get all groups that have a player-controlled aircraft\
    -- now uses cached, reduced set of player planes\
    local pGroups = cfxSSBClient.playerGroups -- cfxGroups.getPlayerGroup() -- we want the group.name attribute\
    for idx, theGroup in pairs(pGroups) do\
        cfxSSBClient.setSlotAccessForGroup(theGroup)\
    end\
\
end\
\
function cfxSSBClient.reOpenSlotForGroupNamed(args)\
    -- this is merely the timer shell for opening the crashed slot\
    gName = args[1]\
    cfxSSBClient.openSlotForCrashedGroupNamed(gName)\
end\
\
function cfxSSBClient.openSlotForCrashedGroupNamed(gName)\
    if not gName then return end\
    local pGroup = cfxSSBClient.getPlayerGroupForGroupNamed(gName)\
    if not pGroup then return end \
    cfxSSBClient.crashedGroups[gName] = nil -- set to nil to forget this happened \
    cfxSSBClient.setSlotAccessForGroup(pGroup) -- set by current occupation status \
    if cfxSSBClient.verbose then \
        trigger.action.outText(\"+++SSBC:SU: re-opened slot for group <\" .. gName .. \">\", 30)\
    end \
end\
\
function cfxSSBClient:onEvent(event) \
    if event.id == 21 then -- S_EVENT_PLAYER_LEAVE_UNIT\
        if cfxSSBClient.verbose then \
            trigger.action.outText(\"+++SSB: Player leave unit\", 30)\
        end\
        local theUnit = event.initiator\
        if not theUnit then\
            if cfxSSBClient.verbose then\
                trigger.action.outText(\"+++SSB: No unit left, abort\", 30)\
            end\
            return \
        end \
        local curH = theUnit:getLife()\
        local maxH = theUnit:getLife0()\
        if cfxSSBClient.verbose then\
            trigger.action.outText(\"+++SSB: Health check: \" .. curH .. \" of \" .. maxH, 30)\
        end\
        return \
    end\
    \
    if event.id == 10 then -- S_EVENT_BASE_CAPTURED\
        if cfxSSBClient.verbose then \
            trigger.action.outText(\"+++SSB: CAPTURE EVENT -- RESETTING SLOTS\", 30)\
        end\
        cfxSSBClient.setSlotAccessByAirfieldOwner()\
    end\
\
-- write down player names and planes\
    if event.id == 15 then\
        --trigger.action.outText(\"+++SSBC:SU: enter event 15\", 30)\
        if not event.initiator then return end \
        local theUnit = event.initiator -- we know this exists\
        local uName = theUnit:getName()\
        if not uName then return end \
        -- player entered unit\
        local playerName = theUnit:getPlayerName()\
        if not playerName then \
            return -- NPC plane\
        end \
        -- remember this unit as player controlled plane\
        -- because player and plane can easily disconnect\
        cfxSSBClient.playerPlanes[uName] = playerName\
        if cfxSSBClient.verbose then \
            trigger.action.outText(\"+++SSBC:SU: noted \" .. playerName .. \" piloting player unit \" .. uName, 30)\
        end \
        return \
    end\
    \
\
    if cfxSSBClient.singleUse and event.id == 5 then -- crash\
        if not event.initiator then return end \
        local theUnit = event.initiator \
        local uName = theUnit:getName()\
        if not uName then return end\
        local theGroup = theUnit:getGroup()\
        if not theGroup then return end \
        -- see if a player plane\
        local thePilot = cfxSSBClient.playerPlanes[uName]\
        if not thePilot then \
            -- ignore. not a player plane\
            if cfxSSBClient.verbose then \
                trigger.action.outText(\"+++SSBC:SU: ignored crash for NPC unit <\" .. uName .. \">\", 30)\
            end \
            return \
        end\
        -- if we get here, a player-owned plane has crashed \
        local gName = theGroup:getName()\
        if not gName then return end \
        \
        -- block this slot. \
        trigger.action.setUserFlag(gName, cfxSSBClient.disabledFlagValue)\
        \
        -- remember this plane to not re-enable if \
        -- airfield changes hands later \
        cfxSSBClient.crashedGroups[gName] = thePilot -- set to crash pilot \
        trigger.action.outText(\"+++SSBC:SU: Blocked slot for group <\" .. gName .. \">\", 30)\
        \
        if cfxSSBClient.reUseAfter > 0 then \
            -- schedule re-opening this slot in <x> seconds\
            timer.scheduleFunction(\
                cfxSSBClient.reOpenSlotForGroupNamed, \
                {gName}, \
                timer.getTime() + cfxSSBClient.reUseAfter\
                )\
        end\
    end\
end\
\
function cfxSSBClient.update()\
    -- first, re-schedule me in one minute \
    timer.scheduleFunction(cfxSSBClient.update, {}, timer.getTime() + 60)\
    \
    -- now establish all slot blocks \
    cfxSSBClient.setSlotAccessByAirfieldOwner()\
end\
\
-- pre-process static player data to minimize \
-- processor load on checks\
function cfxSSBClient.processPlayerData()\
    cfxSSBClient.playerGroups = cfxGroups.getPlayerGroup()\
    local pGroups = cfxSSBClient.playerGroups\
    local filteredPlayers = {}\
    for idx, theGroup in pairs(pGroups) do\
        if theGroup.airfield ~= nil or cfxSSBClient.keepInAirGroups or \
        cfxSSBClient.singleUse then \
            -- only transfer groups that have airfields (or also keepInAirGroups or when single-use)\
            -- attached. Ignore the rest as they are \
            -- always fine\
            table.insert(filteredPlayers, theGroup)\
        end\
    end\
    cfxSSBClient.playerGroups = filteredPlayers\
end\
\
-- add airfield information to each player group\
function cfxSSBClient.processGroupData()\
    local pGroups = cfxGroups.getPlayerGroup() -- we want the group.name attribute\
    for idx, theGroup in pairs(pGroups) do\
        -- we always use the first player's plane as referenced\
        local playerData = theGroup.playerUnits[1]\
        local theAirfield = nil\
        local delta = -1\
        local action = playerData.action \
        if not action then action = \"<NIL>\" end \
        -- see if the data has any of the slot-interesting actions\
        if dcsCommon.arrayContainsString(cfxSSBClient.slotActions, action ) then \
            -- yes, fetch the closest airfield \
            theAirfield, delta = cfxSSBClient.getClosestAirbaseTo(playerData.point)\
            local afName = theAirfield:getName()\
            if cfxSSBClient.verbose then \
                trigger.action.outText(\"+++SSB: group: \" .. theGroup.name .. \" closest to AF \" .. afName .. \": \" .. delta .. \"m\" , 30)\
            end \
            if delta > cfxSSBClient.maxAirfieldRange then \
                -- forget airfield\
                 theAirfield = nil\
                if cfxSSBClient.verbose then \
                    trigger.action.outText(\"+++SSB: group: \" .. theGroup.name .. \" unlinked - too far from airfield\" , 30)\
                end \
            end\
            theGroup.airfield = theAirfield\
        else \
            if cfxSSBClient.verbose then \
                trigger.action.outText(\"+++SSB: group: \" .. theGroup.name .. \" start option \" .. action .. \" does not concern SSB\", 30)\
            end \
        end\
    end\
end\
\
--\
-- read config zone\
--\
function cfxSSBClient.readConfigZone()\
    -- note: must match exactly!!!!\
    local theZone = cfxZones.getZoneByName(\"SSBClientConfig\") \
    if not theZone then \
        trigger.action.outText(\"+++SSBC: no config zone!\", 30) \
        return \
    end \
    \
    trigger.action.outText(\"+++SSBC: found config zone!\", 30) \
    \
    cfxSSBClient.verbose = cfxZones.getBoolFromZoneProperty(theZone, \"verbose\", false)\
    \
    -- single-use\
    cfxSSBClient.singleUse = cfxZones.getBoolFromZoneProperty(theZone, \"singleUse\", false) -- use airframes only once? respawn after kick must be disabled in ssb\
    cfxSSBClient.reUseAfter = cfxZones.getNumberFromZoneProperty(theZone, \"reUseAfter\", -1)\
    \
    -- airfield availability \
    cfxSSBClient.allowNeutralFields = cfxZones.getBoolFromZoneProperty(theZone, \"allowNeutralFields\", false)\
    \
    cfxSSBClient.maxAirfieldRange = cfxZones.getNumberFromZoneProperty(theZone, \"maxAirfieldRange\", 3000) -- meters, to find attached airfield\
\
    -- optimization \
    \
    cfxSSBClient.keepInAirGroups = cfxZones.getBoolFromZoneProperty(theZone, \"keepInAirGroups\", false)\
    \
    -- SSB direct control. \
    -- USE ONLY WHEN YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\
    \
    cfxSSBClient.enabledFlagValue = cfxZones.getNumberFromZoneProperty(theZone, \"enabledFlagValue\", 0)\
    \
    cfxSSBClient.disabledFlagValue = cfxZones.getNumberFromZoneProperty(theZone, \"disabledFlagValue\", cfxSSBClient.enabledFlagValue + 100)\
end\
\
--\
-- start\
--\
function cfxSSBClient.start()\
    -- verify modules loaded \
    if not dcsCommon.libCheck(\"cfx SSB Client\", \
        cfxSSBClient.requiredLibs) then\
        return false \
    end\
    \
    -- read config zone if present \
    cfxSSBClient.readConfigZone()\
    \
    -- install callback for events in DCS\
    world.addEventHandler(cfxSSBClient)\
    \
    -- process group data to attach airfields \
    cfxSSBClient.processGroupData()\
    \
    -- process player data to minimize effort and build cache\
    -- into cfxSSBClient.playerGroups\
    cfxSSBClient.processPlayerData()\
    \
    -- install a timed update just to make sure\
    -- and start NOW\
    timer.scheduleFunction(cfxSSBClient.update, {}, timer.getTime() + 1)\
     \
    -- now turn on ssb \
    trigger.action.setUserFlag(\"SSB\",100)\
    \
    -- say hi!\
    trigger.action.outText(\"cfxSSBClient v\".. cfxSSBClient.version .. \" running, SBB enabled\", 30)\
    \
    --cfxSSBClient.allYourBase()\
    \
    return true \
end\
\
if not cfxSSBClient.start() then \
    trigger.action.outText(\"cfxSSBClient v\".. cfxSSBClient.version .. \" FAILED loading.\", 30)\
    cfxSSBClient = nil\
end\
\
--[[--\
  possible improvements: \
    - use explicitBlockList that with API. planes on that list are always blocked. Use this for special effects, such as allowing a slot only to open from scripts, e.g. when a condition is met like money or goals reached\
   \
-]]--",
                    ["predicate"] = "a_do_script",
                }, -- end of [14]
            }, -- end of ["actions"]
        }, -- end of [1]
        [2] = 
        {
            ["rules"] = 
            {
                [1] = 
                {
                    ["coalitionlist"] = "red",
                    ["unitType"] = "ALL",
                    ["zone"] = 84,
                    ["predicate"] = "c_time_after",
                    ["seconds"] = 1,
                }, -- end of [1]
            }, -- end of ["rules"]
            ["eventlist"] = "",
            ["predicate"] = "triggerOnce",
            ["actions"] = 
            {
                [1] = 
                {
                    ["text"] = "nameStats = {}\
nameStats.version = \"1.1.1\"\
--[[--\
  package that allows generic and global access to data, stored by \
  name and path. Can be used to manage score, cargo, statistics etc.\
  provides its own root by default, but modules can provide their own \
  private roots to be managed the same way.\
  \
  Uses a path metaphor to access fine grained levels\
  \
    version history \
    1.0.0 - initial release \
    1.1.0 - added table to leaf for more general \
          - added ability to use arbitrary roots\
          - setValue \
          - reset\
          - getAllPathes\
    1.1.1 - simplified strings to a single string \
          - left old logic intact for log extensions\
          - setString()\
    \
--]]--\
-- statistics container. everything is in here\
 \
nameStats.stats = {}\
\
--[[--\
    to access data, there are the following principles:\
    - name: uniquely defines a branch where all data for this name \
            is stored. MANDATORY, MUST NEVER BE nil\
            this is usually a unit's name \
    - path: in each branch you can have a path (string) to the data \
            to more precisely define. for example, you can have separate \
            paths 'score' and 'weight' under the same name \
            There currently is no logic attached to a path except that\
            it must be unique inside the same branch\
            OPTIONAL. if omittted, a default data set is returned\
    - rootNode: OPTIONAL storage (table) you can pass to create your own \
            pricate storage space that can't be accessed unless the \
            invoking method also passes the same rootNode \
    \
    Data \
        Data is stored in a \"leaf node\" that has three properties\
        - value: a numerical value that can be set and changed\
        - string: a strings that can be set and added to \
        - table: a table that you can treat as you like and that     \
                 is never looked into nor changed by this module \
                 \
--]]--\
\
function nameStats.getAllNames(theRootNode) -- root node is optional\
    if not theRootNode then theRootNode = nameStats.stats end  \
    local allNames = {}\
    for name, entry in pairs(theRootNode) do \
        table.insert(allNames, name)\
    end\
    return allNames\
end\
\
function nameStats.getAllPathes(name, theRootNode)\
    if not theRootNode then theRootNode = nameStats.stats end \
    local allPathes = {}\
    local theEntry = theRootNode[name]\
    if not theEntry then \
        return allPathes \
    end\
    \
    for pathName, data in pairs(theEntry.data) do \
        table.insert(allPathes, pathName)\
    end\
    \
    return allPathes\
end\
\
-- change the numerical value by delta. use negative numbers to decrease\
function nameStats.changeValue(name, delta, path, rootNode)\
    if not name then return nil end \
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\
    theLeaf.value = theLeaf.value + delta\
    return theLeaf.value \
end\
\
-- set to a specific value \
function nameStats.setValue(name, newVal, path, rootNode)\
    if not name then return nil end \
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\
    theLeaf.value = newVal\
    return theLeaf.value \
end\
\
-- add a string to the log\
function nameStats.addString(name, aString, path, rootNode)\
    if not name then return nil end \
    if not aString then return nil end \
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\
    --table.insert(theLeaf.strings, aString)\
    theLeaf.strings = theLeaf.strings .. aString\
--    return aString\
end\
\
-- reset the log\
function nameStats.removeAllString(name, path, rootNode)\
    if not name then return nil end \
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\
--    theLeaf.strings = {}\
    theLeaf.strings = \"\"\
end\
\
function nameStats.setString(name, aString, path, rootNode)\
    if not name then return nil end \
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\
    theLeaf.strings = aString\
end\
\
-- set the table variable\
function nameStats.setTable(name, path, aTable, rootNode)\
    if not name then return end \
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\
    theLeaf.theTable = aTable\
end\
\
-- get the numerical value associated with name, path \
function nameStats.getValue(name, path, rootNode) -- allocate if not exist\
    if not name then return nil end \
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\
    return theLeaf.value\
end\
\
-- get the log associated with name, path \
function nameStats.getStrings(name, path, rootNode)\
    if not name then return nil end \
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\
    return theLeaf.strings\
end\
\
-- alias for compatibility reasons\
function nameStats.getString(name, path, rootNode)\
    return nameStats.getStrings(name, path, rootNode)\
end\
\
-- get the table stored under name, path.\
function nameStats.getTable(name, path, rootNode)\
    if not name then return nil end \
    local theLeaf = nameStats.getLeaf(name, path, rootNode)\
    return theLeaf.theTable\
end\
\
-- reset whatever is stored under name, path\
-- WARNING: passing nil path will entirely reset the whole name \
function nameStats.reset(name, path, rootNode)\
    if not name then return nil end \
    if not rootNode then rootNode = nameStats.stats end \
    local theEntry = rootNode[name]\
    if not theEntry then \
        -- does not yet exist, create a root entry\
        theEntry = nameStats.createRoot(name)\
        rootNode[name] = theEntry\
        nameStats.getLeaf(name, path, rootNode) -- will alloc an empty leaf\
        return -- done\
    end\
    if not path then -- will delete everything!!!\
        theEntry = nameStats.createRoot(name)\
        rootNode[name] = theEntry\
        return  \
    end \
    -- create new leaf and replace existing\
    theLeaf = nameStats.createLeaf()\
    theEntry.data[path] = theLeaf\
        \
end\
\
--\
--\
-- private function \
--\
--\
function nameStats.getLeaf(name, path, rootNode) \
    if not name then return nil end \
    if not rootNode then rootNode = nameStats.stats end \
    -- will allocate if not existlocal theEntry = nameStats.stats[name]\
    local theEntry = rootNode[name]\
    if not theEntry then \
        -- does not yet exist, create a root entry\
        theEntry = nameStats.createRoot(name)\
        rootNode[name] = theEntry\
    end\
    -- from here on, the entry exists \
    if not path then return theEntry.defaultLeaf end \
    \
    -- access via path \
    local theLeaf = theEntry.data[path]\
    if not theLeaf then \
        theLeaf = nameStats.createLeaf()\
        theEntry.data[path] = theLeaf\
    end\
    return theLeaf\
end\
\
function nameStats.createLeaf()\
    local theLeaf = {}\
    theLeaf.value = 0\
    theLeaf.strings = \"\"\
    theLeaf.log = {} -- was strings\
    theLeaf.theTable = {}\
    return theLeaf\
end\
\
-- for each entry in stats, this is the root container\
function nameStats.createRoot(name)\
    local theRoot = {} -- all nodes are in here\
    theRoot.name = name \
    theRoot.data = {} -- dict by path for leafs\
    theRoot.defaultLeaf = nameStats.createLeaf()\
    return theRoot\
end\
\
-- say hi!\
trigger.action.outText(\"cf/x NameStats v\" .. nameStats.version .. \" loaded\", 30)\
",
                    ["predicate"] = "a_do_script",
                }, -- end of [1]
                [2] = 
                {
                    ["text"] = "cargoSuper = {}\
cargoSuper.version = \"1.1.1\"\
--[[--\
version history\
    1.0.0 - initial version\
    1.1.0 - removeMassObjectFrom supports name directly for mass object \
          - cargoSuper tracks all mass objects \
          - deleteMassObject() \
          - removeMassObjectFrom supports forget option\
          - createMassObject supports auto-gen UUID name \
          - removeAllMassForCargo renamed to removeAllMassForCategory\
          - category default \"cSup!DefCat\"\
          - getAllCategoriesFor alias for getAllCargos \
          - getManifestForCategory alias for getManifestFor\
          - removeAllMassFor()\
    1.1.1 - deleteMassObject corrected index bug \
    \
CargoSuper manages weigth for a logical named unit. Weight can be added \
to arbitrary categories like 'passengers', 'cargo' or \"whatever\". In order \
to add weight to a unit, first create a massObject through createMassObject\
and then add that mass object to the unit via addMassTo, with a category name\
you can get access to massobjects via getMassObjects  \
When done, you can remove the mass object via removeMassObject or \
removeAll\
\
To get a unit's total weight, use getTotalMass() \
\
IMPORTANT:\
This module does ***N*O*T*** call  trigger.action.setUnitInternalCargo\
you must do that yourself\
\
--]]--\
cargoSuper.requiredLibs = {\
    \"dcsCommon\", -- common is of course needed for everything\
                 -- pretty stupid to check for this since we \
                 -- need common to invoke the check, but anyway\
    \"nameStats\", -- generic data module for weight \
}\
\
cargoSuper.cargos = {}\
cargoSuper.massObjects = {}\
\
-- create a massObject. reference object can be used to store \
-- anything that links an associated object:getSampleRate()\
-- massName can be anything but must be unique as it is used to store. pass nil for UUID-created name \
function cargoSuper.createMassObject(massInKg, massName, referenceObject)\
    local theObject = {}\
    theObject.mass = massInKg\
    theObject.name = massName \
    theObject.ref = referenceObject\
    \
    if not massName then \
        massName = dcsCommon.uuid(\"cSup!N\")\
    end\
    \
    local existingMO = cargoSuper.massObjects[massName]\
    if existingMO then \
        trigger.action.outText(\"+++cSuper: WARNING - \" .. massName .. \" exists already, overwritten!\", 30)\
    end\
    cargoSuper.massObjects[massName] = theObject\
    return theObject\
end \
\
function cargoSuper.deleteMassObject(massObject) \
    if not massObject then return end \
    local theName = \"\" \
    if type(massObject) == \"string\" then \
        theName = massObject \
    else \
        theName = massObject.name \
    end \
    cargoSuper.massObjects[theName] = nil -- 1.1.1 corrected to theName from massName \
end\
\
function cargoSuper.addMassObjectTo(name, category, theMassObject)\
    if not theMassObject then return end\
    if not category then category = \"cSup!DefCat\" end \
    -- use nameStats to access private data table\
    local theMassTable = nameStats.getTable(name, category, cargoSuper.cargos)\
    theMassTable[theMassObject.name] = theMassObject\
end\
\
function cargoSuper.removeMassObjectFrom(name, category, theMassObject, forget)\
    if not theMassObject then return end\
    if not category then category = \"cSup!DefCat\" end \
    if not forget then forget = true end \
    -- use nameStats to access private data table\
    -- return the data table stored under category. category *can* be nil \
    -- v1.0.1 can also provide mass object name \
    -- instead of mass object itself. no check!!\
    local moName = \"\"\
    if type(theMassObject) == \"string\" then\
        moName = theMassObject\
    else \
        moName = theMassObject.name \
    end\
    local theMassTable = nameStats.getTable(name, category, cargoSuper.cargos)\
    theMassTable[moName] = nil\
    if forget then \
        cargoSuper.deleteMassObject(theMassObject)\
    end\
end\
\
-- DO NOT PUBLISH. Provided only for backwards compatibility\
function cargoSuper.removeAllMassForCargo(name, catergory)\
    if not category then category = \"cSup!DefCat\" end \
    nameStats.reset(name, category, cargoSuper.cargos)\
end\
\
-- alias for removeAllMassForCargo\
function cargoSuper.removeAllMassForCategory(name, catergory)\
    cargoSuper.removeAllMassForCargo(name, catergory)\
end\
\
function cargoSuper.removeAllMassFor(name)\
    if not name then return end \
    local categories = nameStats.getAllPathes(name, cargoSuper.cargos)\
    for idx, cat in pairs(categories) do\
        cargoSuper.removeAllMassForCategory(name, cat)\
    end\
end\
\
-- returns all cargo categories for name \
-- DO NOT PUBLISH. BAD NAMING\
function cargoSuper.getAllCargosFor(name)\
    local categories = nameStats.getAllPathes(name, cargoSuper.cargos)\
    return categories\
end\
\
-- alias for badly named method above\
function cargoSuper.getAllCategoriesFor(name)\
    cargoSuper.getAllCargosFor(name)\
end\
\
-- return all mass objects that are in name, category as table\
-- that can be accessed as *array*\
-- DO NOT PUBLISH. NAMING IS BAD\
function cargoSuper.getManifestFor(name, category)\
    if not category then category = \"cSup!DefCat\" end \
    local theMassTable = nameStats.getTable(name, category, cargoSuper.cargos)\
    return dcsCommon.enumerateTable(theMassTable)\
end\
\
-- alias for badly named method above\
function cargoSuper.getManifestForCategory(name, category)\
    cargoSuper.getManifestFor(name, category)\
end\
\
function getManifestTextFor(name, category, includeTotal)\
    if not category then category = \"cSup!DefCat\" end \
    local theMassTable = cargoSuper.getManifestFor(name, category)\
    local desc = \"\"\
    local totalMass = 0\
    local isFirst = true\
    for idx, massObject in pairs(theMassTable) do \
        if not isFirst then \
            desc = desc .. \"\\n\"\
        end\
        totalMass = totalMass + massObject.mass\
        desc = desc .. massObject.name .. \" (\" .. massObject.mass .. \"kg)\"\
        isFirst = false\
    end    \
    if includeTotal and (isFirst == false) then \
        -- we only do this if we have at least one (isFirst is false)\
        desc = desc .. \"\\nTotal Weight: \" .. totalMass .. \"kg\"\
    end\
    return desc\
end\
\
function cargoSuper.calculateTotalMassForCategory(name, category)\
    if not category then category = \"cSup!DefCat\" end \
    theMasses = cargoSuper.getManifestFor(name, category)\
    local totalMass = 0\
    for massName, massObject in pairs(theMasses) do\
        totalMass = totalMass + massObject.mass\
    end\
    return totalMass\
end\
\
function cargoSuper.calculateTotalMassFor(name)\
    local allCategories = cargoSuper.getAllCargosFor(name)\
    local totalMass = 0\
    for idx, category in pairs(allCategories) do \
        totalMass = totalMass + cargoSuper.calculateTotalMassForCategory(name, category)\
    end    \
    return totalMass\
end\
\
function cargoSuper.start()\
    -- make sure we have loaded all relevant libraries \
    if not dcsCommon.libCheck(\"cfx CargoSuper\", cargoSuper.requiredLibs) then \
        trigger.action.outText(\"cf/x CargoSuper aborted: missing libraries\", 30)\
        return false \
    end\
    \
    trigger.action.outText(\"cf/x CargoSuper v\" .. cargoSuper.version .. \" loaded\", 30)\
    return true \
    \
end\
\
-- go go go \
if not cargoSuper.start() then \
    cargoSuper = nil\
end",
                    ["predicate"] = "a_do_script",
                }, -- end of [2]
                [3] = 
                {
                    ["text"] = "-- cfxCommander - issue dcs commands to groups etc\
--\
-- supports scheduling\
-- *** EXTENDS ZONES: 'pathing' attribute \
--\
cfxCommander = {}\
cfxCommander.version = \"1.1.2\"\
--[[-- VERSION HISTORY\
 - 1.0.5 - createWPListForGroupToPointViaRoads: detect no road found \
 - 1.0.6 - build in more group checks in assign wp list \
         - added sanity checks for doScheduledTask\
         - assignWPListToGroup now can schedule tasks \
         - makeGroupGoThere supports scheduling\
         - makeGroupGoTherePreferringRoads supports scheduling \
         - scheduleTaskForGroup supports immediate execution\
         - makeGroupHalt\
 - 1.0.7 - warning if road shorter than direct\
         - forceOffRoad option\
         - noRoadsAtAll option \
 - 1.1.0 - load libs \
         - pathing zones. Currently only supports \
         - offroad to override road-usage\
         - pathing zones are overridden by noRoadsAtAll\
         - CommanderConfig zones \
 - 1.1.1 - default pathing for pathing zone is normal, not offroad \
 - 1.1.2 - makeGroupTransmit \
         - makeGroupStopTransmitting\
         - verbose check before path warning\
         - added delay defaulting for most scheduling functions \
--]]--\
\
cfxCommander.requiredLibs = {\
    \"dcsCommon\", -- common is of course needed for everything\
    \"cfxZones\", -- zones management for pathing zones \
}\
\
cfxCommander.verbose = false \
cfxCommander.forceOffRoad = true -- if true, vehicles path follow roads, but may drive offroad (they follow vertex points from path but not the road as they are still commanded 'offroad')\
cfxCommander.noRoadsAtAll = true  -- if true, always go direct, overrides forceOffRoad when true. Always a two-point path. Here, there, bang! \
cfxCommander.pathZones = {} -- zones that can override road settings\
\
--\
-- path zone\
--\
function cfxCommander.processPathingZone(aZone) -- process attribute and add to zone\
    local pathing = cfxZones.getStringFromZoneProperty(aZone, \"pathing\", \"normal\") -- must be \"offroad\" to force offroad\
    pathing = pathing:lower()\
    -- currently no validation of attribute \
    aZone.pathing = pathing\
end \
\
function cfxCommander.addPathingZone(aZone)\
    table.insert(cfxCommander.pathZones, aZone)\
end \
\
function cfxCommander.hasPathZoneFor(here, there)\
    for idx, aZone in pairs(cfxCommander.pathZones) do \
        if cfxZones.pointInZone(here, aZone) then return aZone end \
        if cfxZones.pointInZone(there, aZone) then return aZone end\
    end\
    return nil\
end\
\
--\
-- Config Zone Reading if present \
--\
function cfxCommander.readConfigZone()\
    -- note: must match exactly!!!!\
    local theZone = cfxZones.getZoneByName(\"CommanderConfig\") \
    if not theZone then \
        trigger.action.outText(\"+++cmdr: no config zone!\", 30) \
        return \
    end \
    \
    trigger.action.outText(\"+++cmdr: found config zone!\", 30) \
    \
    cfxCommander.verbose = cfxZones.getBoolFromZoneProperty(theZone, \"verbose\", false)\
    cfxCommander.forceOffRoad = cfxZones.getBoolFromZoneProperty(theZone, \"forceOffRoad\", false) -- if true, vehicles path follow roads, but may drive offroad\
    cfxCommander.noRoadsAtAll = cfxZones.getBoolFromZoneProperty(theZone, \"noRoadsAtAll\", false)\
\
end\
\
--\
-- Options are key, value pairs. Scheduler when you are creating groups\
-- \
\
function cfxCommander.doOption(data) \
    if cfxCommander.verbose then \
        trigger.action.outText(\"Commander: setting option \" .. data.key .. \" --> \" .. data.value, 30)\
    end\
\
    local theController = data.group:getController()\
    theController:setOption(data.key, data.value)\
end\
\
function cfxCommander.scheduleOptionForGroup(group, key, value, delay) \
    local data = {}\
    if not delay then delay = 0.1 end \
    data.group = group\
    data.key = key\
    data.value = value \
    timer.scheduleFunction(cfxCommander.doOption, data, timer.getTime() + delay)\
end\
\
--\
-- performCommand is a special version of issuing a command\
-- that can be easily schduled by pushing the commandData on \
-- the stack with scheduling it \
-- group or name must be filled to get the group,\
-- and the command table is what is going to be passed to the setCommand\
-- commands are given in an array, so you can stack commands \
function cfxCommander.performCommands(commandData)\
    -- see if we have a group\
    if not commandData.group then \
        commandData.group = Group.getByName(commandData.name) -- better be inited!\
    end\
    -- get the AI\
    local theController = commandData.group:getController()\
    for i=1, #commandData.commands do\
        if cfxCommander.verbose then \
            trigger.action.outText(\"Commander: performing \" .. commandData.commands[i].id, 30)\
        end\
        theController:setCommand(commandData.commands[i])\
    end\
    \
    return nil -- a timer called us, so we return no desire to be rescheduled\
end\
\
function cfxCommander.scheduleCommands(data, delay)\
    if not delay then delay = 1 end \
    timer.scheduleFunction(cfxCommander.performCommands, data, timer.getTime() + delay)\
end\
\
function cfxCommander.scheduleSingleCommand(group, command, delay) \
    if not delay then delay = 1 end \
    local data = createCommandDataTableFor(group)\
    cfxCommander.addCommand(data, command)\
    cfxCommander.scheduleCommands(data, delay)\
end\
\
\
function cfxCommander.createCommandDataTableFor(group, name)\
    local cD = {}\
    if not group then \
        cD.name = name\
    else\
        cD.group = group\
    end\
    cD.commands={}\
    return cD\
end\
\
function cfxCommander.addCommand(theCD, theCommand)\
    if not theCD then return end \
    if not theCommand then return end \
    \
    table.insert(theCD.commands, theCommand)\
end\
\
function cfxCommander.createSetFrequencyCommand(freq, modulator)\
    local theCmd = {}\
    if not freq then freq = 100 end \
    if not modulator then modulator = 0 end -- AM = 0, default\
    theCmd.id = 'SetFrequency'\
    theCmd.params = {}\
    theCmd.params.frequency = freq * 10000 -- 88 --> 880000. 124 --> 1.24 MHz\
    theCmd.params.modulation = modulator\
    return theCmd\
end\
\
-- oneShot is optional. if present and anything but false, will cause message to \
-- me sent only once, no loops\
function cfxCommander.createTransmissionCommand(filename, oneShot)\
    local looping = true\
    if not filename then filename = \"dummy\" end \
    if oneShot then looping = false end\
    local theCmd = {}\
    theCmd.id = 'TransmitMessage'\
    theCmd.params = {}\
    theCmd.params.loop = looping\
    theCmd.params.file = \"l10n/DEFAULT/\" .. filename -- need to prepend the resource string\
    return theCmd\
end\
\
function cfxCommander.createStopTransmissionCommand()\
    local theCmd = {}\
    theCmd.id = 'stopTransmission'\
    theCmd.params = {}\
    return theCmd\
end\
\
--\
-- tasks\
-- \
\
function cfxCommander.doScheduledTask(data) \
    if cfxCommander.verbose then \
        trigger.action.outText(\"Commander: setting task \" .. data.task.id .. \" for group \" .. data.group:getName(), 30)\
    end\
    local theGroup = data.group \
    if not theGroup then return end \
    if not theGroup.isExist then return end\
    \
    local theController = theGroup:getController()\
    theController:pushTask(data.task)\
end\
\
function cfxCommander.scheduleTaskForGroup(group, task, delay)\
    if not delay then delay = 0 end \
    local data = {}\
    data.group = group\
    data.task = task\
    if delay < 0.001 then \
        cfxCommander.doScheduledTask(data) -- immediate execution\
        return \
    end\
    timer.scheduleFunction(cfxCommander.doScheduledTask, data, timer.getTime() + delay)\
end\
\
function cfxCommander.createAttackGroupCommand(theGroupToAttack)\
    local task = {}\
    task.id = 'AttackGroup'\
    task.params = {}\
    task.params.groupID = theGroupToAttack:getID()\
    return task\
end\
\
function cfxCommander.createEngageGroupCommand(theGroupToAttack)\
    local task = {}\
    task.id = 'EngageGroup'\
    task.params = {}\
    task.params.groupID = theGroupToAttack:getID()\
    return task\
end\
\
--\
-- waypoints, routes etc \
--\
\
-- basic waypoint is for ground units. point can be xyz or xy \
function cfxCommander.createBasicWaypoint(point, speed, formation)\
    local wp = {}\
    wp.x = point.x\
    -- support xyz and xy format\
    if point.z then \
        wp.y = point.z\
    else\
        wp.y = point.y\
    end\
    \
    if not speed then speed = 6 end -- 6 m/s = 20 kph\
    wp.speed = speed \
    \
    if cfxCommander.forceOffRoad then \
        formation = \"Off Road\"\
    end\
    \
    if not formation then formation = \"Off Road\" end\
    -- legal formations:\
    -- Off road\
    -- On Road -- second letter upper case?\
    -- Cone \
    -- Rank\
    -- Diamond\
    -- Vee\
    -- EchelonR\
    -- EchelonL\
    wp.action = formation -- silly name, but that's how ME does it\
    wp.type = 'Turning Point'\
    return wp\
\
end\
\
function cfxCommander.buildTaskFromWPList(wpList)\
    -- build the task that will make a group follow the WP list\
    -- we do this by creating a \"Mission\" task around the WP List\
    -- WP list is consumed by this action\
    local missionTask = {}\
    missionTask.id = \"Mission\"\
    missionTask.params = {}\
    missionTask.params.route = {}\
    missionTask.params.route.points=wpList\
    return missionTask\
end\
\
function cfxCommander.assignWPListToGroup(group, wpList, delay)\
    if not delay then delay = 0 end \
    if not group then return end \
    if type(group) == 'string' then -- group name, nice mist trick \
        group = Group.getByName(group)\
    end\
    if not group then return end \
    if not group:isExist() then return end \
    \
    local theTask = cfxCommander.buildTaskFromWPList(wpList)\
    local ctrl = group:getController()\
\
--[[--\
    if delay < 0.001 then -- immediate action\
        if ctrl then\
            ctrl:setTask(theTask)\
        end\
    else \
        -- delay execution of this command by the specified amount \
        -- of seconds \
        cfxCommander.scheduleTaskForGroup(group, theTask, delay)\
    end\
--]]--\
    cfxCommander.scheduleTaskForGroup(group, theTask, delay)\
end\
\
function cfxCommander.createWPListForGroupToPoint(group, point, speed, formation)\
    if type(group) == 'string' then -- group name\
        group = Group.getByName(group)\
    end\
\
    local wpList = {}\
    -- here we are, and we want to go there. In DCS, this means that\
    -- we need to create a wp list consisting of here and there\
    local here = dcsCommon.getGroupLocation(group)\
    local wpHere = cfxCommander.createBasicWaypoint(here, speed, formation)\
    local wpThere = cfxCommander.createBasicWaypoint(point, speed, formation)\
    wpList[1] = wpHere\
    wpList[2] = wpThere\
    return wpList\
end\
\
-- make a ground units group head to a waypoint by replacing the entire mission\
-- with a two-waypoint lsit from (here) to there at speed and formation. formation\
-- default is 'off road'\
function cfxCommander.makeGroupGoThere(group, there, speed, formation, delay)\
    if not delay then delay = 0 end \
    if type(group) == 'string' then -- group name\
        group = Group.getByName(group)\
    end\
    local wp = cfxCommander.createWPListForGroupToPoint(group, there, speed, formation)\
    \
    cfxCommander.assignWPListToGroup(group, wp, delay)\
end\
\
function cfxCommander.calculatePathLength(roadPoints)\
    local totalLen = 0\
    if #roadPoints < 2 then return 0 end\
    for i=1, #roadPoints-1 do\
        totalLen = totalLen + dcsCommon.dist(roadPoints[i], roadPoints[i+1])\
    end\
    return totalLen\
end\
\
-- make ground units go from here (group location) to there, using roads if possible\
function cfxCommander.createWPListForGroupToPointViaRoads(group, point, speed)\
    if type(group) == 'string' then -- group name\
        group = Group.getByName(group)\
    end\
\
    local wpList = {}\
    -- here we are, and we want to go there. In DCS, this means that\
    -- we need to create a wp list consisting of here and there\
    -- when going via roads, we add to more wayoints:\
    -- go on-roads and leaveRoads. \
    -- only if we can get these two additional points, we do that, else we \
    -- fall back to direct route \
    \
    local here = dcsCommon.getGroupLocation(group)\
\
    -- now generate a list of all points from here to there that uses roads\
    local rawRoadPoints = land.findPathOnRoads('roads', here.x, here.z, point.x, point.z)\
    -- this is the entire path. calculate the length and make \
    -- sure that path on-road isn't more than twice as long \
    -- that can happen if a bridge is out or we need to go around a hill\
    if not rawRoadPoints or #rawRoadPoints<3 then \
        trigger.action.outText(\"+++ no roads leading there. Taking direct approach\", 30)\
        return cfxCommander.createWPListForGroupToPoint(group, point, speed)\
    end\
    \
    local pathLength = cfxCommander.calculatePathLength(rawRoadPoints)\
    local direct = dcsCommon.dist(here, point)\
    if pathLength < direct and cfxCommander.verbose then \
        trigger.action.outText(\"+++dcsC: WARNING road path (\" .. pathLength .. \") shorter than direct route(\" .. direct .. \"), will not path correctly\", 30)\
    end\
    \
    if pathLength > (2 * direct) then \
        -- road takes too long, take direct approach\
        --trigger.action.outText(\"+++ road path (\" .. pathLength .. \") > twice direct route(\" .. direct .. \"), commencing direct off-road\", 30)\
        return cfxCommander.createWPListForGroupToPoint(group, point, speed)\
    end\
    \
    --trigger.action.outText(\"+++ \".. group:getName() .. \": choosing road path l=\" .. pathLength .. \" over direct route d=\" .. direct, 30)\
    \
    -- if we are here, the road trip is valid \
    for idx, wp in pairs(rawRoadPoints) do \
        -- createBasic... supports w.xy format\
        local theNewWP = cfxCommander.createBasicWaypoint(wp, speed, \"On Road\") -- force off road for better compatibility?\
        table.insert(wpList, theNewWP)\
    end\
    \
    \
    \
    -- now make first and last entry OFF Road\
    local wpc = wpList[1]\
    wpc.action = \"Off Road\"\
    wpc = wpList[#wpList]\
    wpc.action = \"Off Road\"\
\
    return wpList\
end\
\
function cfxCommander.makeGroupGoTherePreferringRoads(group, there, speed, delay)\
    if type(group) == 'string' then -- group name\
        group = Group.getByName(group)\
    end\
    if not delay then delay = 0 end \
\
\
    if cfxCommander.noRoadsAtAll then \
        -- we don't even follow roads, completely forced off\
        cfxCommander.makeGroupGoThere(group, there, speed, \"Off Road\", delay)\
        return \
    end\
\
    -- see if we have an override situation \
    -- for one of the two points where a pathing Zone \
    -- overrides the roads setting \
    if #cfxCommander.pathZones > 0 then  \
        local here = dcsCommon.getGroupLocation(group)\
        local oRide = cfxCommander.hasPathZoneFor(here, there)\
        if oRide and oRide.pathing == \"offroad\" then \
            -- yup, override road preference\
            cfxCommander.makeGroupGoThere(group, there, speed, \"Off Road\", delay)\
            --trigger.action.outText(\"pathing: override offroad\")\
            return \
        end\
    end\
\
    -- viaRoads will only use roads if the road trip isn't more than twice \
    -- as long as the direct route \
    local wp = cfxCommander.createWPListForGroupToPointViaRoads(group, there, speed)\
    cfxCommander.assignWPListToGroup(group, wp, delay)\
end\
\
\
function cfxCommander.makeGroupHalt(group, delay)\
    if not group then return end \
    if not group:isExist() then return end \
    if not delay then delay = 0 end \
    local theTask = {id = 'Hold', params = {}}\
    cfxCommander.scheduleTaskForGroup(group, theTask, delay)\
end\
\
function cfxCommander.makeGroupTransmit(group, tenKHz, filename, oneShot, delay)\
    if not group then return end \
    if not tenKHz then tenKHz = 20 end -- default to 200KHz\
    if not delay then delay = 1.0 end \
    if not filename then return end \
    if not oneShot then oneShot = false end \
    \
    -- now build the transmission command\
    local theCommands = cfxCommander.createCommandDataTableFor(group)\
    local cmd = cfxCommander.createSetFrequencyCommand(tenKHz) -- freq in 10000 Hz\
    cfxCommander.addCommand(theCommands, cmd)\
    cmd = cfxCommander.createTransmissionCommand(filename, oneShot)\
    cfxCommander.addCommand(theCommands, cmd)\
    cfxCommander.scheduleCommands(theCommands, delay)\
end \
\
function cfxCommander.makeGroupStopTransmitting(group, delay)\
    if not delay then delay = 1 end \
    if not group then return end \
    local theCommands = cfxCommander.createCommandDataTableFor(group)\
    local cmd = cfxCommander.createStopTransmissionCommand()\
    cfxCommander.addCommand(theCommands, cmd)\
    cfxCommander.scheduleCommands(theCommands, delay)\
end\
\
\
function cfxCommander.start()\
    -- make sure we have loaded all relevant libraries \
    if not dcsCommon.libCheck(\"cfx Commander\", cfxCommander.requiredLibs) then \
        trigger.action.outText(\"cf/x Commander aborted: missing libraries\", 30)\
        return false \
    end\
    \
    -- identify and process all 'pathing' zones\
    local pathZones = cfxZones.getZonesWithAttributeNamed(\"pathing\")\
    \
    -- now create a spawner for all, add them to the spawner updater, and spawn for all zones that are not\
    -- paused \
    for k, aZone in pairs(pathZones) do \
        cfxCommander.processPathingZone(aZone) -- process attribute and add to zone\
        cfxCommander.addPathingZone(aZone) -- remember it so we can smoke it\
    end\
    \
    -- read config overides \
    cfxCommander.readConfigZone()\
    \
    return true\
end\
\
if cfxCommander.start() then \
    trigger.action.outText(\"cfxCommander v\" .. cfxCommander.version .. \" loaded\", 30)\
else \
    trigger.action.outText(\"+++cfxCommander load FAILED\", 30)\
    cfxCommander = nil\
end\
\
--[[-- known issues\
\
- troops remain motionless until all are repaired or produced after cature\
- long roads / roads not taken in persia \
- all troops red and blue become motionless when one zone is occupied\
- after capture, the troop capturing remains, all others can go on. one will always remain there \
- rethink the factor to add to road, and simply add 100m \
\
 TODO: break long distances into smaller paths, and gravitate towards pathing zones if they have a 'gravitate' or similar attribute \
--]]--\
",
                    ["predicate"] = "a_do_script",
                }, -- end of [3]
                [4] = 
                {
                    ["text"] = "csarManager = {}\
csarManager.version = \"2.0.3\"\
--[[-- VERSION HISTORY\
 - 1.0.0 initial version \
 - 1.0.1 - smoke optional \
         - airframeCrashed method for airframe manager \
         - removed '(downed )' when re-picked up \
         - fixed oclock\
 - 1.0.2 - hover retrieval \
 - 1.0.3 - corrected a bug in oclock during hovering \
 - 1.0.4 - now correctly allocates pilot to coalition via dcscommon.coalition2county\
 - 1.1.0 - pilot adds weight to unit \
         - module check \
 - 2.0.0 - weight managed via cargoSuper\
 - 2.0.1 - getCSARBaseforZone()\
         - check if zone landed in has owner attribute \
           to provide compatibility with owned zones, \
           FARPZones etc that keep zone.owner up to date \
 - 2.0.2 - use parametric csarManager.hoverAlt\
         - use hoverDuration\
 - 2.0.3 - corrected bug in hoverDuration\
 - 2.0.4 - guard in createCSARMission for cfxCommander \
 \
--]]--\
-- modules that need to be loaded BEFORE I run \
csarManager.requiredLibs = {\
    \"dcsCommon\", -- common is of course needed for everything\
    \"cfxZones\", -- zones management foc CSAR and CSAR Mission zones\
    \"cfxPlayer\", -- player monitoring and group monitoring \
    \"nameStats\", -- generic data module for weight \
    \"cargoSuper\",\
--    \"cfxCommander\", -- needed if you want to hand-create CSAR missions\
}\
\
-- *** DOES NOT EXTEND ZONES *** BUT USES OWN STRUCT \
\
--[[--\
    CSAR MANAGER\
    ============\
\
 This module can create and manage CSAR missions, i.e. \
 create a unit on the ground, mark it on the map, handle\
 if the unit is killed, create enemies in the vicinity \
 \
 It will install a menu in any troop helicopter as\
 determined by dcsCommon.isTroopCarrier() with the \
 option to list available csar mission. for each created mission\
 it will give range and frequency for ADF\
 When a helicopter is in range, it will set smoke to better \
 visually identify the location. \
 \
 When the helicopter lands close enough to a downed pilot,\
 the pilot is picket up automatically. Their weight is added\
 to the unit, so it may overload!\
 \
 When the helicopter than lands in a CSARBASE Zone, the mission is \
 a success and a success callback is invoked automatically for \
 all picked up groups. All zones that have the CSARBASE property are\
 CSAR Bases, but their coalition must be either neutral or match the \
 one of the unit that landed\
 \
 On start, it scans all zones for a CSAR property, and creates\
 a CSAR mission with data taken from the properties in the \
 zone so you can easily create CSAR missions in ME\
 \
 WARNING: ASSUMES SINGLE UNIT PLAYER GROUPS\
 ==========================================\
\
 Main Interface\
 - createCSARMission(location, side, numCrew, mark, clearing, timeout)\
   creates a csar mission that can be tracked. \
   location is the position on the map\
   side is the side the unit is on (neutal is for any side)\
   numCrew the number of people (1-4)\
   mark true if marked on map \
   clearing will create a clearing \
   timeout - time in seconds until pilots die. timer stops on pickup\
   RETURNS true, \"ok\" --  false, \"fail reason\" (string)\
\
 - createCSARAdversaries(location, side, numEnemies, radius, maxRadius)\
   creates some random infantery randomized on a circle around the location \
   location - center, usually where the downed pilot is\
   side - side of the enemy red/blue\
   numEnemies - number of infantry \
   radius[, maxRadius] distance of the enemy troops\
\
 - in ME, create at least one zone with a property named \"CSARBASE\" for \
   each side that supports csar missions. This is where the players \
   can drop off pilots that they rescued. If you have no CSARBASE zone \
   defined, you'll receive a warning for that side when you attempt a \
   rescue\
   \
 - in ME you can place zones with a CSAR attribute that will generate \
   a scar mission. Further attributes are \"coalition\" (red/blue), \"name\" (any name you like) and \"freq\" (for elt ADR, leave empty for random)\
   \
   NOTE:\
     CSARBASE is compatible with the FARP Attribute of \
     FARP Zones \
     \
   \
--]]--\
--\
-- OPTIONS\
--\
csarManager.useSmoke = false -- smoke is a performance killer, so you can turn it off \
\
\
-- unitConfigs contain the config data for any helicopter\
-- currently in the game. The Array is indexed by unit name \
csarManager.unitConfigs = {}\
csarManager.myEvents = {3, 4, 5} -- 3 = take off, 4 = land, 5 = crash\
\
--\
-- CASR MISSION\
--\
csarManager.openMissions = {} -- all currently available missions\
csarManager.csarBases = {} -- all bases where we can drop off rescued pilots\
\
csarManager.missionID = 1 -- to create uuid\
csarManager.rescueRadius = 70 -- must land within 50m to rescue\
csarManager.hoverRadius = 30 -- must hover within 10m of unit \
csarManager.hoverAlt = 40 -- must hover below this alt \
csarManager.hoverDuration = 20 -- must hover for this duration\
csarManager.rescueTriggerRange = 2000 -- when the unit pops smoke and radios\
csarManager.beaconSound = \"Radio_beacon_of_distress_on_121,5_MHz.ogg\"\
csarManager.pilotWeight = 120 -- kg for the rescued person. added to the unit's weight\
--\
-- callbacks\
-- \
csarManager.csarCompleteCB = {}\
\
--\
-- CREATING A CSAR \
--\
function csarManager.createDownedPilot(theMission)\
    if not cfxCommander then \
        trigger.action.outText(\"+++CSAR: can't create mission, module cfxCommander is missing.\", 30)\
        return \
    end\
    \
    local aLocation = {}\
    local aHeading = 0 -- in rads\
    local newTargetZone = theMission.zone\
    aLocation, aHeading = dcsCommon.randomPointOnPerimeter(newTargetZone.radius / 2 + 3, newTargetZone.point.x, newTargetZone.point.z) \
\
    local theBoyGroup = dcsCommon.createSingleUnitGroup(theMission.name, \
                            \"Soldier M4 GRG\", -- \"Soldier M4 GRG\",\
                            aLocation.x, \
                            aLocation.z, \
                            -aHeading + 1.5) -- + 1.5 to turn inwards\
    \
    -- WARNING:\
    -- coalition.addGroup takes the COUNTRY of the group, and derives the \
    -- coalition from that. So if mission.sie is 0, we use UN, if it is 1 (red) it\
    -- is joint red, if 2 it is joint blue \
    local theSideCJTF = dcsCommon.coalition2county(theMission.side) -- get the correct county CJTF \
    theMission.group = coalition.addGroup(theSideCJTF, \
                                          Group.Category.GROUND, \
                                          theBoyGroup)\
    \
    if theBoyGroup then \
--        trigger.action.outText(\"+++csar: created csar!\", 30)\
    else \
        trigger.action.outText(\"+++csar: FAILED to create csar!\", 30)\
    end\
    \
    \
    -- we now use commands to send radio transmissions\
    local ADF = 20 + math.random(90)\
    if theMission.freq then ADF = theMission.freq else theMission.freq = ADF end \
    local theCommands = cfxCommander.createCommandDataTableFor(theMission.group)\
    local cmd = cfxCommander.createSetFrequencyCommand(ADF) -- freq in 10000 Hz\
    cfxCommander.addCommand(theCommands, cmd)\
    cmd = cfxCommander.createTransmissionCommand(csarManager.beaconSound)\
    cfxCommander.addCommand(theCommands, cmd)\
    cfxCommander.scheduleCommands(theCommands, 2) -- in 2 seconds, so unit has time to percolate through DCS\
end\
\
function csarManager.createCSARMissionData(point, theSide, freq, name, numCrew, timeLimit, mapMarker)\
    -- create a type \
    if not timeLimit then timeLimit = -1 end\
    if not point then return nil end \
    local newMission = {}\
    newMission.side = theSide\
    if dcsCommon.stringStartsWith(name, \"(downed) \") then \
        -- remove \"downed\" - it will be added again later\
        name = dcsCommon.removePrefix(name, \"(downed) \")\
    end\
    \
    newMission.name = \"(downed) \" .. name .. \"-\" .. csarManager.missionID -- make it uuid-capable\
    newMission.zone = cfxZones.createSimpleZone(newMission.name, point, csarManager.rescueRadius)\
    newMission.marker = mapMarker -- so it can be removed later\
    newMission.isHot = false -- creating adversaries will make it hot, or when units are near. maybe implement a search later?\
    -- detection and load stuff\
    newMission.lastSmokeTime = -1000 -- so it will smoke immediately \
    newMission.messagedUnits = {} -- so we remember whom the unit radioed\
    newMission.hoveringUnits = {} -- used when hovering \
    newMission.freq = freq -- if nil will make random \
            \
    -- allocate units\
    csarManager.createDownedPilot(newMission)\
    \
    -- update counter and return\
    csarManager.missionID = csarManager.missionID + 1\
    return newMission\
end\
\
function csarManager.addMission(theMission)\
    table.insert(csarManager.openMissions, theMission)\
end\
\
function csarManager.removeMission(theMission)\
    if not theMission then return end \
    local newMissions = {}\
    for idx, aMission in pairs (csarManager.openMissions) do\
        if aMission ~= theMission then \
            table.insert(newMissions, aMission)\
        else \
        end\
    end\
    csarManager.openMissions = newMissions -- this is the new batch\
end\
\
function csarManager.removeMissionForGroup(theDownedGroup)\
    if not theDownedGroup then return end \
    local newMissions = {}\
    for idx, aMission in pairs (csarManager.openMissions) do\
        if aMission.group ~= theDownedGroup then \
            table.insert(newMissions, aMission)\
        else \
        end\
    end\
    csarManager.openMissions = newMissions -- this is the new batch\
end\
--\
-- UNIT CONFIG \
--\
function csarManager.resetConfig(conf)\
    -- reset only ovberwrites mission-relevant data\
    conf.troopsOnBoard = {} -- number of rescued missions\
    local myName = conf.name\
    cargoSuper.removeAllMassForCargo(myName, \"Evacuees\") -- will allocate new empty table \
    conf.currentState = -1 -- indetermined, 0 = landed 1 = airborne\
    conf.timeStamp = timer.getTime()\
end\
\
function csarManager.createDefaultConfig(theUnit)\
    local conf = {}\
    conf.theUnit = theUnit \
    conf.name = theUnit:getName()\
    csarManager.resetConfig(conf)\
    --conf.unit = {} -- the unit this is linked to\
    conf.myMainMenu = nil -- this is the main menu for group\
    conf.myCommands = nil -- all commands in sub menu\
    conf.id = theUnit:getID()\
    return conf \
end\
\
\
function csarManager.getUnitConfig(theUnit) -- will create new config if not existing\
    if not theUnit then\
        trigger.action.outText(\"+++csar: nil unit in get config!\", 30)\
        return nil \
    end\
    local uName = theUnit:getName()\
    local c = csarManager.getConfigForUnitNamed(uName)\
    if not c then \
        c = csarManager.createDefaultConfig(theUnit)\
        csarManager.unitConfigs[uName] = c \
    end\
    return c \
end\
\
function csarManager.getConfigForUnitNamed(aName)\
    return csarManager.unitConfigs[aName]\
end\
\
\
function csarManager.removeConfigForUnitNamed(aName) \
    if not aName then return end \
    if csarManager.unitConfigs[aName] then csarManager.unitConfigs[aName] = nil end\
end\
\
--\
-- E V E N T   H A N D L I N G \
-- \
function csarManager.isInteresting(eventID) \
    -- return true if we are interested in this event, false else \
    for key, evType in pairs(csarManager.myEvents) do \
        if evType == eventID then return true end\
    end\
    return false \
end\
\
function csarManager.preProcessor(event)\
    -- make sure it has an initiator\
    if not event.initiator then return false end -- no initiator \
    local theUnit = event.initiator \
    local cat = theUnit:getCategory()\
    if cat ~= Unit.Category.HELICOPTER then \
        return false \
    end\
    \
    --trigger.action.outText(\"+++csar: event \" .. event.id .. \" for cat = \" .. cat .. \" (helicopter?)  unit \" .. theUnit:getName(), 30)\
    \
    if not cfxPlayer.isPlayerUnit(theUnit) then \
        --trigger.action.outText(\"+++csar: rejected event: \" .. theUnit:getName() .. \" not a player helo\", 30)\
        return false \
    end -- not a player unit\
    return csarManager.isInteresting(event.id) \
end\
\
function csarManager.postProcessor(event)\
    -- don't do anything for now\
end\
\
function csarManager.somethingHappened(event)\
    -- when this is invoked, the preprocessor guarantees that\
    -- it's an interesting event\
    -- unit is valid and player \
    -- airframe category is helicopter \
    local theUnit = event.initiator\
    local ID = event.id\
    \
    local myType = theUnit:getTypeName()\
--    trigger.action.outText(\"+++csar: event \" .. ID .. \" for player unit \" .. theUnit:getName() .. \" of type \" .. myType, 30)\
    \
    if ID == 4 then  -- landed\
        csarManager.heloLanded(theUnit)\
    end\
    \
    if ID == 3 then -- take off\
        csarManager.heloDeparted(theUnit)\
    end\
    \
    if ID == 5 then -- crash \
        csarManager.heloCrashed(theUnit)\
    end\
    \
    csarManager.setCommsMenu(theUnit)\
end\
\
--\
--\
-- CSAR LANDED\
--\
--\
\
function csarManager.successMission(who, where, theMission)\
    trigger.action.outTextForCoalition(theMission.side,\
        who .. \" successfully evacuated \" .. theMission.name .. \" to \" .. where .. \"!\", \
        30)\
    \
    -- now call callback for coalition side \
    -- callback has format callback(coalition, success true/false, numberSaved, descriptionText)\
    \
    for idx, callback in pairs(csarManager.csarCompleteCB) do \
        callback(theMission.side, true, 1, \"test\")\
    end\
    trigger.action.outSoundForCoalition(theMission.side, \"Quest Snare 3.wav\")\
end\
\
function csarManager.heloLanded(theUnit)\
    -- when we have landed, \
    if not dcsCommon.isTroopCarrier(theUnit) then return end\
    local conf = csarManager.getUnitConfig(theUnit)\
    conf.unit = theUnit\
    local theGroup = theUnit:getGroup()\
    conf.id = theGroup:getID()\
    --conf.id = theUnit:getID()\
    conf.currentState = 0\
    local thePoint = theUnit:getPoint()\
    local mySide = theUnit:getCoalition()\
    local myName = theUnit:getName()    \
\
    -- first, check if we have landed in a CSAR dropoff zone \
    -- if so, drop off all loaded csar troops and award the \
    -- points or airframes \
    local allEvacuees = cargoSuper.getManifestFor(myName, \"Evacuees\") -- returns unlinked array \
                                            \
    if #allEvacuees > 0 then -- wasif #conf.troopsOnBoard > 0 then\
        for idx, base in pairs(csarManager.csarBases) do\
            -- check if the attached zone has changed hands\
            -- this can happen if zone has its own owner \
            -- attribute and is conquered by another side \
            local currentBaseSide = base.side\
            \
            if base.zone.owner then \
                -- this zone is shared with capturable \
                -- zone extensions like owned zone, FARP etc.\
                -- use current owner\
                currentBaseSide = base.zone.owner \
--                trigger.action.outText(\"+++csar: overriding base.side with zone owner = \" .. currentBaseSide .. \" for csarB \" .. base.name .. \", requiring \" .. mySide .. \" or 0 to land\", 30)\
            else \
--                trigger.action.outText(\"+++csar: base \" .. base.name .. \" has no owner - proceeding with side = \" .. base.side .. \" looking for \" .. mySide, 30)\
            end\
            \
            if currentBaseSide == mySide or \
               currentBaseSide == 0 \
            then  -- can always land in neutral\
                if cfxZones.pointInZone(thePoint, base.zone) then \
                    for idx, msn in pairs(conf.troopsOnBoard) do \
                        -- each troopsOnboard is actually the \
                        -- csar mission that I picked up \
                        csarManager.successMission(myName, base.name, msn)\
                    end\
                    -- now use cargoSuper to retrieve all evacuees \
                    -- and deliver them to safety \
                    \
                    for idx, theMassObject in pairs(allEvacuees) do\
                        cargoSuper.removeMassObjectFrom(\
                                            myName, \
                                            \"Evacuees\", \
                                            theMassObject)\
                        msn = theMassObject.ref \
                        -- csarManager.successMission(myName, base.name, msn)\
                        -- to be done when we remove troopsOnBoard\
                    end                    \
                    -- reset weight \
                    local totalMass = cargoSuper.calculateTotalMassFor(myName)\
                    trigger.action.setUnitInternalCargo(myName, totalMass) -- super recalcs\
--                    trigger.action.outText(\"+++csar: delivered - set internal weight for \" .. myName .. \" to \" .. totalMass, 30)\
    \
--                    trigger.action.setUnitInternalCargo(myName, 10) -- 10 kg as empty \
                    conf.troopsOnBoard = {} -- empty out troops on board \
                    -- we do *not* return so we can pick up troops on \
                    -- a CSARBASE if they were dropped there\
                    \
                end\
            end -- my side?\
        end\
    end -- check only if I'm carrying evacuees\
\
    -- if not in a csar dropoff zone, check if we are \
    -- landed in a csar pickup zone, and start loading \
    \
    local pickups = {}\
    for idx, mission in pairs(csarManager.openMissions) do \
        if mySide == mission.side then \
            -- see if we are inside the mission's rescue range \
            local d = dcsCommon.distFlat(thePoint, mission.zone.point)\
            if d < csarManager.rescueRadius then \
                -- pick up this mission an remove it from the \
                table.insert(pickups, mission)\
            end\
        end\
    end\
    \
    -- now process the missions that I've picked up, transfer them to troopsOnBoard, and remove the dudes\
    local didPickup = false \
    for idx, theMission in pairs(pickups) do\
        trigger.action.outTextForCoalition(mySide,\
        myName .. \" is extracting \" .. theMission.name .. \"!\", \
        30)\
        didPickup = true;\
        \
        csarManager.removeMission(theMission)\
        table.insert(conf.troopsOnBoard, theMission)\
        theMission.group:destroy() -- will shut up radio as well\
        theMission.group = nil\
        -- now adapt for cargoSuper \
        theMassObject = cargoSuper.createMassObject(\
                csarManager.pilotWeight, \
                theMission.name, \
                theMission)\
        cargoSuper.addMassObjectTo(\
                myName, \
                \"Evacuees\", \
                theMassObject)\
    end\
    if didPickup then \
        trigger.action.outSoundForCoalition(mySide, \"Quest Snare 3.wav\")\
    end\
    -- reset unit's weight based on people on board\
    local totalMass = cargoSuper.calculateTotalMassFor(myName)\
    -- WAS: trigger.action.setUnitInternalCargo(myName, 10 + #conf.troopsOnBoard * csarManager.pilotWeight) -- 10 kg as empty + per-unit time people \
    trigger.action.setUnitInternalCargo(myName, totalMass) -- 10 kg as empty + per-unit time people \
--    trigger.action.outText(\"+++csar: set internal weight for \" .. myName .. \" to \" .. totalMass, 30)\
    \
end\
\
--\
--\
-- Helo took off\
--\
--\
function csarManager.heloDeparted(theUnit)\
    if not dcsCommon.isTroopCarrier(theUnit) then return end\
    -- if we have timed extractions (i.e. not instantaneous),\
    -- then we need to check if we take off after the timer runs out \
    \
    \
    -- when we take off, all that needs to be done is to change the state \
    -- to airborne, and then set the status flag \
    local conf = csarManager.getUnitConfig(theUnit)\
    conf.unit = theUnit\
    local theGroup = theUnit:getGroup()\
    conf.id = theGroup:getID()\
    conf.currentState = 1 -- in the air \
    \
    \
end\
\
--\
-- \
-- Helo Crashed \
--\
--\
\
function csarManager.heloCrashed(theUnit)\
    if not dcsCommon.isTroopCarrier(theUnit) then return end\
    -- problem: this isn't called on network games. \
    \
    -- clean up \
    local conf = csarManager.getUnitConfig(theUnit)\
    conf.unit = theUnit \
    local theGroup = theUnit:getGroup()\
    conf.id = theGroup:getID()\
    conf.currentState = -1 -- (we don't know)\
    --[[--\
    if #conf.troopsOnBoard > 0 then \
        -- this is where we can create a new CSAR mission\
        trigger.action.outSoundForCoalition(conf.id, theUnit:getName() .. \" crashed while evacuating \" .. #conf.troopsOnBoard .. \" pilots. Survivors possible.\", 30)\
        trigger.action.outSoundForCoalition(conf.id, \"Quest Snare 3.wav\")\
        for i=1, #conf.troopsOnBoard do \
            local msn = conf.troopsOnBoard[i] -- picked up unit(s)\
            local theRescuedPilot = msn.name \
            -- create x new missions in 50m radius\
            -- except for pilot, that will be called \
            -- from limitedAirframes\
            csarManager.createCSARforUnit(theUnit, theRescuedPilot, 50, true)\
        end\
    end\
    --]]--\
    conf.troopsOnBoard = {}\
    local myName = conf.name\
    cargoSuper.removeAllMassForCargo(myName, \"Evacuees\") -- will allocate new empty table \
    csarManager.removeComms(conf.unit)\
end\
\
function csarManager.airframeCrashed(theUnit)\
    -- called from airframe manager \
    if not dcsCommon.isTroopCarrier(theUnit) then return end\
    local conf = csarManager.getUnitConfig(theUnit)\
    conf.unit = theUnit \
    local theGroup = theUnit:getGroup()\
    conf.id = theGroup:getID()\
    -- may want to do something, for now just nothing\
    \
end\
\
function csarManager.airframeDitched(theUnit)\
    -- called from airframe manager \
    if not dcsCommon.isTroopCarrier(theUnit) then return end\
    \
    local conf = csarManager.getUnitConfig(theUnit)\
    conf.unit = theUnit \
    local theGroup = theUnit:getGroup()\
    conf.id = theGroup:getID()\
    local theSide = theUnit:getCoalition()\
    if #conf.troopsOnBoard > 0 then \
        -- this is where we can create a new CSAR mission\
        trigger.action.outTextForCoalition(theSide, theUnit:getName() .. \" abandoned while evacuating \" .. #conf.troopsOnBoard .. \" pilots. There many be survivors.\", 30)\
--        trigger.action.outSoundForCoalition(conf.id, \"Quest Snare 3.wav\")\
        for i=1, #conf.troopsOnBoard do \
            local msn = conf.troopsOnBoard[i] -- picked up unit(s)\
            local theRescuedPilot = msn.name \
            -- create x new missions in 50m radius\
            -- except for pilot, that will be called \
            -- from limitedAirframes\
            csarManager.createCSARforUnit(theUnit, theRescuedPilot, 50, true)\
        end\
    end\
    -- NYI: re-populate from cargo \
    local myName = conf.name\
    cargoSuper.removeAllMassForCargo(myName, \"Evacuees\") -- will allocate new empty table \
end\
\
--\
--\
-- M E N U   H A N D L I N G   &   R E S P O N S E \
-- \
-- \
function csarManager.clearCommsSubmenus(conf)\
    if conf.myCommands then \
        for i=1, #conf.myCommands do\
            missionCommands.removeItemForGroup(conf.id, conf.myCommands[i])\
        end\
    end\
    conf.myCommands = {}\
end\
\
function csarManager.removeCommsFromConfig(conf)\
    csarManager.clearCommsSubmenus(conf)\
    \
    if conf.myMainMenu then \
        missionCommands.removeItemForGroup(conf.id, conf.myMainMenu) \
        conf.myMainMenu = nil\
    end\
end\
\
function csarManager.removeComms(theUnit)\
    if not theUnit then return end\
    if not theUnit:isExist() then return end \
    \
    local group = theUnit:getGroup() \
    local id = group:getID()\
    local conf = csarManager.getUnitConfig(theUnit)\
    conf.id = id\
    conf.unit = theUnit \
    \
    csarManager.removeCommsFromConfig(conf)\
end\
\
\
function csarManager.setCommsMenu(theUnit)\
    if not theUnit then return end\
    if not theUnit:isExist() then return end \
    \
    -- we only add this menu to helicopter troop carriers\
    -- will also filter out all non-helicopters as nice side effect\
    if not dcsCommon.isTroopCarrier(theUnit) then return end\
    \
    local group = theUnit:getGroup() \
    local id = group:getID()\
    local conf = csarManager.getUnitConfig(theUnit) -- will allocate if new. This is important since a group event can call this as well\
    conf.id = id; -- we do this ALWAYS to it is current even after a crash \
    conf.unit = theUnit -- link back\
    \
    -- reset all coms now\
    csarManager.removeCommsFromConfig(conf)\
    \
    -- ok, first, if we don't have an F-10 menu, create one \
    conf.myMainMenu = missionCommands.addSubMenuForGroup(id, 'CSAR Missions') \
    \
    -- now we have a menu without submenus. \
    -- add our own submenus\
    local commandTxt = \"List active CSAR requests\"\
    local theCommand =  missionCommands.addCommandForGroup(\
                conf.id, \
                commandTxt,\
                conf.myMainMenu,\
                csarManager.redirectListCSARRequests, \
                {conf, \"hi there\"}\
                )\
    table.insert(conf.myCommands, theCommand)\
    commandTxt = \"Status of rescued crew aboard\"\
    theCommand =  missionCommands.addCommandForGroup(\
                conf.id, \
                commandTxt,\
                conf.myMainMenu,\
                csarManager.redirectStatusCarrying, \
                {conf, \"hi there\"}\
                )\
    table.insert(conf.myCommands, theCommand)\
    \
    commandTxt = \"Unload one evacuee here (rescue later)\"\
    theCommand =  missionCommands.addCommandForGroup(\
                conf.id, \
                commandTxt,\
                conf.myMainMenu,\
                csarManager.redirectUnloadOne, \
                {conf, \"unload one\"}\
                )\
    table.insert(conf.myCommands, theCommand)\
end\
\
\
function csarManager.redirectListCSARRequests(args)\
    timer.scheduleFunction(csarManager.doListCSARRequests, args, timer.getTime() + 0.1)\
end\
\
function csarManager.doListCSARRequests(args) \
    local conf = args[1]\
    local param = args[2]\
    local theUnit = conf.unit \
    local point = theUnit:getPoint()\
    \
    --trigger.action.outText(\"+++csar: \".. theUnit:getName() ..\"  issued csar status request\", 30)\
    local report = \"\\nCrews requesting evacuation\\n\"\
    if #csarManager.openMissions < 1 then \
        report = report .. \"\\nNo requests, all crew are safe.\"\
    else \
        -- iterate through all troops onboard to get their status\
        for idx, mission in pairs(csarManager.openMissions) do \
            local d = dcsCommon.distFlat(point, mission.zone.point) * 0.000539957\
            d = math.floor(d * 10) / 10\
            local b = dcsCommon.bearingInDegreesFromAtoB(point, mission.zone.point)\
            local status = \"alive\"\
            report = report .. \"\\n\".. mission.name .. \", bearing \" .. b .. \", \" ..d ..\"nm, \" .. \" ADF \" .. mission.freq .. \"0 kHz - \" .. status \
        end\
    end\
    \
    if #csarManager.csarBases < 1 then \
        report = report .. \"\\n\\nWARNING: NO CSAR BASES TO DELIVER EVACUEES\"\
    end\
    \
    report = report .. \"\\n\"\
    \
    trigger.action.outTextForGroup(conf.id, report, 30)\
    trigger.action.outSoundForGroup(conf.id, \"Quest Snare 3.wav\")\
end\
\
function csarManager.redirectStatusCarrying(args)\
    timer.scheduleFunction(csarManager.doStatusCarrying, args, timer.getTime() + 0.1)\
end\
\
function csarManager.doStatusCarrying(args) \
    local conf = args[1]\
    local param = args[2]\
    local theUnit = conf.unit \
    \
    --trigger.action.outText(\"+++csar: \".. theUnit:getName() ..\"  wants to know how their rescued troops are doing\", 30)\
    \
    -- build status report\
    local report = \"\\nCrew Rescue Status:\\n\"\
    if #conf.troopsOnBoard < 1 then \
        report = report .. \"\\nWe have no evacuees on board\"\
    else \
        -- iterate through all troops onboard to get their status\
        for i=1, #conf.troopsOnBoard do \
            local evacMission = conf.troopsOnBoard[i]\
            report = report .. \"\\n\".. i .. \") \" .. evacMission.name \
            report = report .. \" is stable\" -- or 'beat up, but will live'\
        end\
        \
        report = report .. \"\\n\\nTotal added weigth: \" .. 10 + #conf.troopsOnBoard * csarManager.pilotWeight .. \"kg\" \
    end\
    \
    \
    report = report .. \"\\n\"\
    \
    trigger.action.outTextForGroup(conf.id, report, 30)\
    trigger.action.outSoundForGroup(conf.id, \"Quest Snare 3.wav\")\
end\
\
function csarManager.redirectUnloadOne(args)\
    timer.scheduleFunction(csarManager.unloadOne, args, timer.getTime() + 0.1)\
end\
\
function csarManager.unloadOne(args)\
    local conf = args[1]\
    local param = args[2]\
    local theUnit = conf.unit \
    local myName = theUnit:getName() \
    \
    local report = \"NYI: unload one\"\
    \
    if theUnit:inAir() then \
        report = \"STRONGLY recommend we land first, Sir!\"\
        trigger.action.outTextForGroup(conf.id, report, 30)\
        trigger.action.outSoundForGroup(conf.id, \"Quest Snare 3.wav\")\
        return \
    end\
    \
    if #conf.troopsOnBoard < 1 then\
        report = \"No evacuees on board.\"\
        trigger.action.outTextForGroup(conf.id, report, 30)\
        trigger.action.outSoundForGroup(conf.id, \"Quest Snare 3.wav\")\
        \
    else \
        -- simulate a crash but for one unit \
        local theSide = theUnit:getCoalition()\
        -- this is where we can create a new CSAR mission\
        i= #conf.troopsOnBoard \
        local msn = conf.troopsOnBoard[i] -- picked up unit(s)\
        local theRescuedPilot = msn.name \
        -- create a new missions in 50m radius\
        csarManager.createCSARforUnit(theUnit, theRescuedPilot, 50, true)\
        conf.troopsOnBoard[i] = nil -- remove this mission\
        trigger.action.outTextForCoalition(theSide, myName .. \" has aborted evacuating \" .. msn.name .. \". New CSAR available.\", 30)\
        trigger.action.outSoundForCoalition(theSide, \"Quest Snare 3.wav\")\
        \
        -- recalc weight\
        trigger.action.setUnitInternalCargo(myName, 10 + #conf.troopsOnBoard * csarManager.pilotWeight) -- 10 kg as empty + per-unit time people \
    end\
    \
end\
--\
-- Player event callbacks\
--\
function csarManager.playerChangeEvent(evType, description, player, data)\
    if evType == \"newGroup\" then \
        local theUnit = data.primeUnit\
        if not dcsCommon.isTroopCarrier(theUnit) then return end \
        \
        csarManager.setCommsMenu(theUnit) -- allocates new config\
--        trigger.action.outText(\"+++csar: added \" .. theUnit:getName() .. \" to comms menu\", 30)\
        return \
    end\
    \
    if evType == \"removeGroup\" then \
--        trigger.action.outText(\"+++csar: a group disappeared\", 30)\
        local conf = csarManager.getConfigForUnitNamed(data.primeUnitName)\
        if conf then \
            csarManager.removeCommsFromConfig(conf)\
        end\
        return\
    end\
    \
    if evType == \"leave\" then \
        local conf = csarManager.getConfigForUnitNamed(player.unitName)\
        if conf then \
            csarManager.resetConfig(conf)\
        end\
    end\
    \
    if evType == \"unit\" then \
        -- player changed units. almost never in MP, but possible in solo\
        -- because of 1 seconds timing loop \
        -- will result in a new group appearing and a group disappearing, so we are good,\
        -- except we need to reset the conf so no troops are carried any longer\
        local conf = csarManager.getConfigForUnitNamed(data.oldUnitName) \
        if conf then \
            csarManager.resetConfig(conf)\
        end\
    end\
end\
\
--\
-- CSAR Bases\
--\
-- properties: \
--  - zone : the zone \
--  - side : coalition \
--  - name : name of base, can be overriden with property\
\
function csarManager.addCSARBase(aZone)\
    local csarBase = {}\
    csarBase.zone = aZone \
    local bName = cfxZones.getStringFromZoneProperty(aZone, \"CSARBASE\", \"XXX\")\
    if bName == \"XXX\" then bName = aZone.name end \
    csarBase.name =  cfxZones.getStringFromZoneProperty(aZone, \"name\", bName) \
    \
    -- read further properties like facilities that may \
    -- need to be matched \
    csarBase.side = cfxZones.getCoalitionFromZoneProperty(aZone, \"coalition\", 0) \
    \
    table.insert(csarManager.csarBases, csarBase)\
--    trigger.action.outText(\"+++csar: found base \" .. csarBase.name .. \" for side \" .. csarBase.side, 30)    \
end\
\
function csarManager.getCSARBaseforZone(aZone)\
    for idx, aCsarBase in pairs(csarManager.csarBases) do \
        if aCsarBase.zone == aZone then \
            return aCsarBase \
        end\
    end\
    return nil\
end\
\
--\
--\
-- U P D A T E \
-- ===========\
-- \
-- \
\
\
--\
-- updateCSARMissions: make sure evacuees are still alive \
--\
function csarManager.updateCSARMissions()\
    local newMissions = {}\
    for idx, aMission in pairs (csarManager.openMissions) do\
        local stillAlive = dcsCommon.isGroupAlive(aMission.group)\
        -- now check if a timer was running to rescue this group\
        -- if dead, set stillAlive to false \
        if stillAlive then \
            table.insert(newMissions, aMission)\
        else \
            local msg = aMission.name .. \" confirmed KIA, repeat KIA. Abort CSAR.\"    \
            trigger.action.outTextForCoalition(aMission.side, msg, 30)\
            trigger.action.outSoundForCoalition(aMission.side, \"Quest Snare 3.wav\")\
        end\
    end\
    csarManager.openMissions = newMissions -- this is the new batch\
end\
\
function csarManager.update() -- every second\
    -- schedule next invocation\
    timer.scheduleFunction(csarManager.update, {}, timer.getTime() + 1)\
\
    -- first, check the health of all csar misions and update the table of live units\
    csarManager.updateCSARMissions()\
\
    -- now scan through all helo groups and see if they are close to a \
    -- CSAR zone and initiate the help sequence \
    local allPlayerGroups = cfxPlayerGroups -- cfxPlayerGroups is a global, don't fuck with it! \
    -- contains per group a player record, use prime unit to access player's unit \
    for gname, pgroup in pairs(allPlayerGroups) do \
        local aUnit = pgroup.primeUnit --        get prime unit of that group\
        if aUnit:isExist() and aUnit:inAir() then -- exists and is flying \
            local uPoint = aUnit:getPoint()\
            local uName = aUnit:getName()\
            local uGroup = aUnit:getGroup()\
            local uID = uGroup:getID()\
            local uSide = aUnit:getCoalition()\
            local agl = dcsCommon.getUnitAGL(aUnit)\
            if dcsCommon.isTroopCarrier(aUnit) then \
                -- scan through all available csar missions to see if we are close \
                -- enough to trigger comms \
                for idx, csarMission in pairs (csarManager.openMissions) do\
                    -- check if we are inside trigger range on the same side\
                    local d = dcsCommon.distFlat(uPoint, csarMission.zone.point)\
                    if (uSide == csarMission.side) and (d < csarManager.rescueTriggerRange) then \
                        -- we are in trigger distance. if we did not notify before\
                        -- do it now \
                        if not dcsCommon.arrayContainsString(csarMission.messagedUnits, uName) then \
                            -- radio this unit with oclock and tell it they are in 2k range \
                            -- also note if LZ is hot \
                            local ownHeading = dcsCommon.getUnitHeadingDegrees(aUnit)\
                            local oclock = dcsCommon.clockPositionOfARelativeToB(csarMission.zone.point, uPoint, ownHeading) .. \" o'clock\"\
                            local msg = \"\\n\" .. uName ..\", \" .. csarMission.name .. \". We can hear you, check your \" .. oclock \
                            if csarManager.useSmoke then msg = msg .. \" - popping smoke\" end\
                            msg = msg .. \".\"\
                            if csarMission.isHot then \
                                msg = msg .. \" Be advised: LZ is hot.\"\
                            end\
                            msg = msg .. \"\\n\"\
                            trigger.action.outTextForGroup(uID, msg, 30)\
                            trigger.action.outSoundForGroup(uID, \"Quest Snare 3.wav\")\
                            table.insert(csarMission.messagedUnits, uName) -- remember that we messaged them so we don't do again\
                        end\
                        -- also pop smoke if not popped already, or more than 3 minutes ago\
                        if csarManager.useSmoke and  timer.getTime() - csarMission.lastSmokeTime > 179 then \
                            local smokePoint = cfxZones.createHeightCorrectedPoint(csarMission.zone.point)\
                            trigger.action.smoke(smokePoint, 4 )\
                        end\
                        \
                        -- now check if we are inside hover range and alt \
                        -- in order to simultate winch ops \
                        -- WARNING: WE ALWAYS ONLY CHECK A SINGLE UNIT - the first alive\
                        local evacuee = csarMission.group:getUnit(1)\
                        if evacuee then \
                            ep = evacuee:getPoint()\
                            d = dcsCommon.distFlat(uPoint, ep)\
                            d = math.floor(d * 10) / 10\
                            if d < csarManager.hoverRadius * 2 then\
                                local ownHeading = dcsCommon.getUnitHeadingDegrees(aUnit)\
                                local oclock = dcsCommon.clockPositionOfARelativeToB(ep, uPoint, ownHeading) .. \" o'clock\"\
                                -- log distance \
                                local hoverMsg = \"Closing on \" .. csarMission.name .. \", \" .. d * 3 .. \"ft on your \" .. oclock .. \" o'clock\"\
\
                                if d < csarManager.hoverRadius then \
                                    if (agl <= csarManager.hoverAlt) and (agl > 3) then \
                                        local hoverTime = csarMission.hoveringUnits[uName]\
                                        if not hoverTime then \
                                            -- create new entry\
                                            hoverTime = timer.getTime()\
                                            csarMission.hoveringUnits[uName] = timer.getTime() \
                                        end\
                                        hoverTime = timer.getTime() - hoverTime -- calculate number of seconds \
                                        remainder = math.floor(csarManager.hoverDuration - hoverTime)\
                                        if remainder < 1 then remainder = 1 end \
                                        hoverMsg = \"Steady... \" .. d * 3 .. \"ft to your \" .. oclock .. \" o'clock, winching... (\" .. remainder .. \")\" \
                                        if hoverTime > csarManager.hoverDuration then \
                                            -- we rescued the guy!\
                                            hoverMsg = \"We have \" .. csarMission.name .. \" safely on board!\"\
                                            local conf = csarManager.getUnitConfig(aUnit)\
                                            csarManager.removeMission(csarMission)\
                                            table.insert(conf.troopsOnBoard, csarMission)\
                                            csarMission.group:destroy() -- will shut up radio as well\
                                            csarMission.group = nil\
                                            trigger.action.outTextForGroup(uID, hoverMsg, 30, true)\
                                            trigger.action.outSoundForGroup(uID, \"Quest Snare 3.wav\")\
\
                                            return -- we only ever rescue one \
                                        end -- hovered long enough \
                                        trigger.action.outTextForGroup(uID, hoverMsg, 30, true)\
                                        return -- only ever one winch op\
                                    else -- too high for hover \
                                        hoverMsg = \"Evacuee \" .. d * 3 .. \"ft on your \" .. oclock .. \" o'clock; land or descend to between 10 and 90 AGL for winching\"\
                                        csarMission.hoveringUnits[uName] = nil -- reset timer \
                                    end\
                                else -- not inside hover dist\
                                    -- remove the hover indicator for this \
                                    csarMission.hoveringUnits[uName] = nil \
                                end \
                                trigger.action.outTextForGroup(uID, hoverMsg, 30, true)\
                                return -- only ever one winch op\
                            else \
                                -- remove the hover indicator for this unit\
                                csarMission.hoveringUnits[uName] = nil\
                            end -- inside 2 * hover dist?\
                            \
                        end -- has evacuee \
                    end -- if in range\
                end -- for all missions \
            end -- if troop carrier \
        end -- if exists \
    end -- for all players \
end\
\
--\
-- create a CSAR Mission for a unit \
-- \
function csarManager.createCSARforUnit(theUnit, pilotName, radius, silent)\
    if not silent then silent = false end \
    if not radius then radius = 1000 end \
    if not pilotName then pilotName = \"Eddie\" end \
    \
    local point = theUnit:getPoint()\
    local coal = theUnit:getCoalition() \
    \
    local csarPoint = dcsCommon.randomPointInCircle(radius, radius/2, point.x, point.z) \
    \
    -- check the ground- water will kill the pilot \
    csarPoint.y = csarPoint.z \
    local surf = land.getSurfaceType(csarPoint)\
    \
    if surf == 2 or surf == 3 then \
        if not silent then \
            trigger.action.outTextForCoalition(coal, \"Bad chute! Bad chute! \".. pilotName .. \" did not survive ejection out of their \" .. theUnit:getTypeName(), 30)\
            trigger.action.outSoundForGroup(coal, \"Quest Snare 3.wav\")\
        end\
        return \
    end\
    \
    csarPoint.y = land.getHeight(csarPoint)\
    \
    -- when we get here, the terrain is ok, so let's drop the pilot \
    local theMission = csarManager.createCSARMissionData(\
        csarPoint, \
        coal, \
        nil, \
        pilotName, \
        1, \
        nil, \
        nil)\
    csarManager.addMission(theMission)\
    if not silent then \
        trigger.action.outTextForCoalition(coal, \"MAYDAY MAYDAY MAYDAY! \".. pilotName .. \" in \" .. theUnit:getTypeName() .. \" ejected, report good chute. Prepare CSAR!\", 30)\
        trigger.action.outSoundForGroup(coal, \"Quest Snare 3.wav\")\
    end \
end\
\
\
\
--\
-- Init & Start \
--\
\
function csarManager.processCSARBASE()\
    local csarBases = cfxZones.zonesWithProperty(\"CSARBASE\")\
    \
    -- now add all zones to my zones table, and init additional info\
    -- from properties\
    for k, aZone in pairs(csarBases) do\
        csarManager.addCSARBase(aZone)\
    end\
end\
\
function csarManager.processCASRZones()\
    local csarBases = cfxZones.zonesWithProperty(\"CSAR\")\
    \
    -- now add all zones to my zones table, and init additional info\
    -- from properties\
    for k, aZone in pairs(csarBases) do\
        -- gather data, and then create a mission from this\
        local theSide = cfxZones.getCoalitionFromZoneProperty(aZone, \"coalition\", 0)\
        local name = cfxZones.getZoneProperty(aZone, \"name\")\
        local freq = cfxZones.getNumberFromZoneProperty(aZone, \"freq\", 0)\
        if freq == 0 then freq = nil end \
        local numCrew = 1 \
        local mapMarker = nil \
        local timeLimit = cfxZones.getNumberFromZoneProperty(aZone, \"timeLimit\", 0)\
        if timeLimit == 0 then timeLimit = nil else timeLimit = timeLimit * 60 end \
        \
        local theMission = csarManager.createCSARMissionData(aZone.point, \
            theSide, \
            freq, \
            name, \
            numCrew, \
            timeLimit, \
            mapMarker)\
        csarManager.addMission(theMission)\
    end\
end\
\
\
function csarManager.invokeCallbacks(theCoalition, success, numRescued, notes)\
    -- invoke anyone who wants to know that a group \
    -- of people was rescued.\
    for idx, cb in pairs(csarManager.csarCompleteCB) do \
        cb(theCoalition, success, numRescued, notes)\
    end\
end\
\
function csarManager.installCallback(theCB)\
    table.insert(csarManager.csarCompleteCB, theCB)\
end\
\
\
function csarManager.start()\
    -- make sure we have loaded all relevant libraries \
    if not dcsCommon.libCheck(\"cfx CSAR\", csarManager.requiredLibs) then \
        trigger.action.outText(\"cf/x CSAR aborted: missing libraries\", 30)\
        return false \
    end\
\
    -- install callbacks for helo-relevant events\
    dcsCommon.addEventHandler(csarManager.somethingHappened, csarManager.preProcessor, csarManager.postProcessor)\
\
    -- now iterate through all player groups and install the CSAR Menu\
    \
    local allPlayerGroups = cfxPlayerGroups -- cfxPlayerGroups is a global, don't fuck with it! \
    -- contains per group a player record, use prime unit to access player's unit \
    for gname, pgroup in pairs(allPlayerGroups) do \
        local aUnit = pgroup.primeUnit -- get prime unit of that group\
        csarManager.setCommsMenu(aUnit)\
    end\
    -- now install the new group notifier for new groups so we can remove and add CSAR menus \
    cfxPlayer.addMonitor(csarManager.playerChangeEvent)\
\
    -- now scan all zones that are CSAR drop-off for quick access\
    csarManager.processCSARBASE()\
    \
    -- now scan all zones to create ME-placed CSAR missions\
    -- and populate the available mission.\
    csarManager.processCASRZones()\
    \
    -- now call update so we can monitor progress of all helos, and alert them\
    -- when they are close to a CSAR\
    csarManager.update()\
\
    -- say hi!\
    trigger.action.outText(\"cf/x CSAR v\" .. csarManager.version .. \" started\", 30)\
    return true \
end\
\
-- let's get rolling\
if not csarManager.start() then \
    csarManager = nil\
end\
\
\
--[[--\
    improvements\
    - need to stay on ground for x seconds to load troops \
    - hot lz\
    - hover recover \
    - limit on troops aboard for transport\
    - delay for drop-off \
    \
    - csar when: always, only on eject, \
    \
    - repair o'clock \
    \
    - nearest csarBase\
    - red/blue csarbases \
    - weight \
    \
    - compatibility: side/owner - make sure it is compatible \
      with FARP, and landing on a FARP with opposition ownership \
      will not disembark\
    \
--]]--",
                    ["predicate"] = "a_do_script",
                }, -- end of [4]
                [5] = 
                {
                    ["text"] = "limitedAirframes = {}\
limitedAirframes.version = \"1.3.0\"\
limitedAirframes.enabled = true -- can be turned off\
limitedAirframes.userCanToggle = true -- F-10 menu?\
limitedAirframes.maxRed = -1 -- -1 == infinite\
limitedAirframes.maxBlue = 6 -- -1 = infinite\
limitedAirframes.redWinsFlag = \"999\"\
limitedAirframes.blueWinsFlag = \"998\" \
 \
limitedAirframes.requiredLibs = {\
    \"dcsCommon\", -- common is of course needed for everything\
                 -- pretty stupid to check for this since we \
                 -- need common to invoke the check, but anyway\
    \"cfxZones\", -- Zones, of course for safe landings\
    \"cfxPlayer\", -- callbacks \
--    \"cfxGroundTroops\", -- generic data module for weight \
}\
\
--[[-- VERSION HISTORY\
 - 1.0.0 - initial version \
 - 1.0.1 - out text to coalition for switch\
         - less verbose\
         - win/lose sound by coalition\
 - 1.0.2 - corrected some to to-->for Groups typos\
 - 1.0.3 - renamed to 'pilot' instead of airframe:\
           pilotSafe attribute \
         - fixed MP bug, switched to EventMonII code\
 - 1.0.4 - added CSAR integration: create CSAR and callback\
         - safe ditch only at less than 7 kmh and 10m agl \
 - 1.0.5 - replaced 5 (crash) check for helos only \
 - 1.0.6 - changed alt and speed tests to inAir\
           reduced verbosity \
           made reporting of new units for coalition side only \
 - 1.0.7 - if unlimited pilots it says so when you return one \
           to base\
 - 1.0.8 - now can query remaining pilots \
 - 1.0.9 - better formatted remaining pilots \
 - 1.1.0 - module manager \
         - separated out settings \
         - hand change in pilotsafe zones that can be landed in \
 - 1.2.0 - limitedAirframesConfig zone \
 - 1.3.0 - added network dead override logic via unitFlownByPlayer\
 \
--]]--\
\
-- limitedAirframes manages the number of available player airframes\
-- per scenario and side. Each time a player crashes the plane\
-- outside of safe zones, the number is decreased for that side\
-- when the number reaches -1 or smaller, other side wins\
-- !!!Only affects player planes!!\
\
-- *** EXTENDS ZONES ***\
-- safe zones must have a property \"pilotSafe\"\
--   - pilotSafe - this is a zone to safely change airframes in\
--   - redSafe (optional, defaults to true)\
--   - blueSafe (optional, defaults to true)\
--     set to \"false\" or \"no\" to disallow that side to change \
--       airframes even when safer\
--   if zone can change ownership, player's coalition \
--   is checked against current zone ownership \
--   zone owner. \
\
-- when red wins due to blue frame loss, flag 999 is set to true\
-- when blue wins due to red frame loss, flag 998 is set to true\
-- set a mission trigger to end mission if you want to end mission\
-- or simply keep running, and a CHEATER! message will flash \
-- every time the losing side enters a new aircraft \
\
limitedAirframes.safeZones = {} -- safezones are zones where a crash or change plane does not\
-- these zones are created by adding an 'pilotSafe' attribute\
\
limitedAirframes.myEvents = {5, 9, 30, 6, 20, 21, 15 } -- 5 = crash, 9 - dead, 30 - unit lost, 6 - eject, 20 - enter unit, 21 - leave unit, 15 - birth\
\
-- guarantee a min of 2 seconds between events\
-- for this we save last event per player \
limitedAirframes.lastEvents = {}\
-- each time a plane crashes or is abandoned check \
-- that it's a player unit \
-- inside a crash free zone \
-- update the side's airframe credit \
\
limitedAirframes.currRed = 0\
limitedAirframes.currRed = 0\
\
-- we record all unit names that contain a player \
-- so that we can check against these when we receive\
-- an ejection event. We also keep a list of players\
-- for good measure and their status\
limitedAirframes.playerUnits = {}\
limitedAirframes.players = {}\
limitedAirframes.unitFlownByPlayer = {} -- to detect dead after \
        -- 21 (player left unit) we store on 15 (birth)\
        -- which unit a player occupies. if player \
        -- then levaes and dead has a mismatch, we resolve \
        -- by not calling dead. \
        -- works if eject does not call player left unit \
        -- unit[unitname] = playername. if nil, no longer \
        -- occupied by player.\
        \
limitedAirframes.theCommand = nil \
\
--\
-- READ CONFIG ZONE TO OVERRIDE SETTING\
--\
function limitedAirframes.readConfigZone()\
    -- note: must match exactly!!!!\
    local theZone = cfxZones.getZoneByName(\"limitedAirframesConfig\") \
    if not theZone then \
        trigger.action.outText(\"***LimA: NO config zone!\", 30) \
        return \
    end \
    \
    trigger.action.outText(\"LimA: found config zone!\", 30) \
    \
    -- ok, for each property, load it if it exists\
    if cfxZones.hasProperty(theZone, \"enabled\")  then \
        limitedAirframes.enabled = cfxZones.getBoolFromZoneProperty(theZone, \"enabled\", true)\
    end\
    \
    if cfxZones.hasProperty(theZone, \"userCanToggle\")  then \
        limitedAirframes.userCanToggle = cfxZones.getBoolFromZoneProperty(theZone, \"userCanToggle\", true)\
    end\
    \
    \
    if cfxZones.hasProperty(theZone, \"maxRed\")  then \
        limitedAirframes.maxRed = cfxZones.getNumberFromZoneProperty(theZone, \"maxRed\", -1)\
    end\
    \
    if cfxZones.hasProperty(theZone, \"maxBlue\")  then \
        limitedAirframes.maxBlue = cfxZones.getNumberFromZoneProperty(theZone, \"maxBlue\", -1)\
    end\
    \
    \
    if cfxZones.hasProperty(theZone, \"redWinsFlag\")  then \
        limitedAirframes.redWinsFlag = cfxZones.getStringFromZoneProperty(theZone, \"redWinsFlag\", \"999\")\
    end\
    \
    if cfxZones.hasProperty(theZone, \"blueWinsFlag\")  then \
        limitedAirframes.blueWinsFlag = cfxZones.getStringFromZoneProperty(theZone, \"blueWinsFlag\", \"998\")\
    end\
end\
\
--\
-- UNIT AND PLAYER HANDLING\
--\
function limitedAirframes.isKnownUnitName(uName)\
    if limitedAirframes.playerUnits[uName] then return true end\
    return false \
end\
\
function limitedAirframes.getKnownUnitPilotByUnitName(uName)\
    if limitedAirframes.isKnownUnitName(uName) then \
        return limitedAirframes.playerUnits[uName]\
    end\
    trigger.action.outText(\"+++lim: WARNING: \" .. uName .. \" is unknown!\", 30)\
    return \"***Error\"\
end\
\
function limitedAirframes.getKnownUnitPilotByUnit(theUnit)\
    return limitedAirframes.getKnownUnitPilotByUnitName(theUnit:getName())\
end\
\
-- addPlayerUnit adds a unit as a known player unit \
-- and also adds the player if unknown\
function limitedAirframes.addPlayerUnit(theUnit)\
    local theSide = theUnit:getCoalition()\
    local uName = theUnit:getName()\
    if not uName then uName = \"**XXXX**\" end \
    local pName = theUnit:getPlayerName()\
    if not pName then pName = \"**????**\" end \
    limitedAirframes.updatePlayer(pName, \"alive\")\
    \
    local desc = \"unit <\" .. uName .. \"> controlled by <\" .. pName .. \">\"\
    if not(limitedAirframes.isKnownUnitName(uName)) then \
        --desc = \"+++lim: added \".. desc .. \" to list of known player units\"\
    else \
        if limitedAirframes.playerUnits[uName] == pName then \
            desc = \"player unit <\".. uName .. \"> controlled by <\".. limitedAirframes.playerUnits[uName]..\"> re-seated\"\
        else \
            desc = \"Updated player unit <\".. uName .. \"> from <\".. limitedAirframes.playerUnits[uName]..\"> to <\" .. pName ..\">\"\
        end \
    end \
    limitedAirframes.playerUnits[uName] = pName \
    trigger.action.outTextForCoalition(theSide, desc, 30)\
end\
\
function limitedAirframes.killPlayer(pName)\
    limitedAirframes.updatePlayer(pName, \"dead\")\
    --trigger.action.outText(\"+++lim: PILOT LOST: \" .. pName .. \", NO CSAR\", 30)\
end\
\
function limitedAirframes.killPlayerInUnit(theUnit)\
    limitedAirframes.updatePlayerInUnit(theUnit, \"dead\")\
    --trigger.action.outText(\"+++lim: PILOT LOST, NO CSAR\", 30)\
end\
\
function limitedAirframes.updatePlayerInUnit(theUnit, status)\
    local uName = theUnit:getName()\
    if not limitedAirframes.isKnownUnitName(uName) then \
        trigger.action.outText(\"+++lim: WARNING: updatePlayerInUnit to \" .. status .. \" with unknown pilot for plane\", 30)\
        return \
    end\
    local pName = limitedAirframes.getKnownUnitPilotByUnitName(uName)\
    limitedAirframes.updatePlayer(pName, status)\
end\
\
function limitedAirframes.updatePlayer(pName, status)\
    if not pName then \
        trigger.action.outText(\"+++lim: WARNING - NIL pName in updatePlayer for status \" .. status, 30)\
        return\
    end \
    local desc = \"\"\
    if not limitedAirframes.players[pName] then \
        desc = \"+++lim: NEW player \" .. pName .. \": \" .. status\
    else \
        if limitedAirframes.players[pName] ~= status then \
            desc = \"+++lim: CHANGE player \" .. pName .. \" \" .. limitedAirframes.players[pName] .. \" -> \" .. status\
        else \
            desc = \"+++: player \" .. pName .. \" no change (\" .. status .. \")\"\
        end\
    end\
    \
    limitedAirframes.players[pName] = status \
    -- if desc then trigger.action.outText(desc, 30) end \
end\
\
function limitedAirframes.getStatusOfPlayerInUnit(theUnit)\
    local uName = theUnit:getName()\
    if not limitedAirframes.isKnownUnitName(uName) then \
        trigger.action.outText(\"+++lim: WARNING get player status for unknown pilot in plane \" .. uName, 30)\
        return nil\
    end\
    local pName = limitedAirframes.getKnownUnitPilotByUnitName(uName)\
    return limitedAirframes.getStatusOfPlayerNamed(pName)\
end\
\
function limitedAirframes.getStatusOfPlayerNamed(pName)\
    return limitedAirframes.players[pName]\
end\
\
--\
-- E V E N T   H A N D L I N G \
-- \
function limitedAirframes.XXXisKnownPlayerUnit(theUnit) \
    if not theUnit then return false end \
    local aName = theUnit:getName()\
    if limitedAirframes.playerUnitNames[aName] ~= nil then \
        return true\
    end\
    return false \
end\
\
function limitedAirframes.isInteresting(eventID) \
    -- return true if we are interested in this event, false else \
    for key, evType in pairs(limitedAirframes.myEvents) do \
        if evType == eventID then return true end\
    end\
    return false \
end\
\
function limitedAirframes.preProcessor(event)\
    -- make sure it has an initiator\
    if not event.initiator then return false end -- no initiator \
    local theUnit = event.initiator\
    local uName = theUnit:getName()\
    \
\
    if event.id == 6 then -- Eject, plane already divorced from player\
        if limitedAirframes.isKnownUnitName(uName) then \
            --trigger.action.outText(\"limAir: detected EJECT for player unit \" .. uName .. \" player \" .. limitedAirframes.getKnownUnitPilotByUnitName(uName), 30)\
            return true\
        end\
        return false -- no longer of interest \
    end\
    \
    if event.id == 5 then -- crash, plane no longer attached to player\
        \
        if limitedAirframes.isKnownUnitName(uName) then\
            --trigger.action.outText(\"limAir: detected CRASH for player unit \" .. uName .. \" player \" .. limitedAirframes.getKnownUnitPilotByUnitName(uName), 30)\
            return true\
        end\
        return false -- no longer of interest \
    end\
    \
    \
    if not cfxPlayer.isPlayerUnit(theUnit) then \
        -- not a player unit. Events 5 and 6 have been\
        -- handled before, so we can safely ignore\
        return false \
    end  \
\
    -- exclude all ground units\
    local theGroup = theUnit:getGroup() \
    local cat = theGroup:getCategory()\
    if cat == Group.Category.GROUND then \
        return false \
    end\
\
    -- only return true if defined as interesting \
    return limitedAirframes.isInteresting(event.id) \
end\
\
function limitedAirframes.postProcessor(event)\
    -- don't do anything\
end\
\
function limitedAirframes.somethingHappened(event)\
    -- when this is invoked, the preprocessor guarantees that\
    -- we have:\
    -- * an interesting event\
    -- * unit is valid and was a player's unit\
    \
    -- the events that are relevant for pilot loss are:\
    -- * player entered: set pilot 'alive' state, maybe add new \
    --   unit and pilot to db of players and units \
    -- * pilot died - decrease pilot count, set 'dead' state\
    -- * eject - decrease pilot count, 'MIA' state, csar possible\
    -- * player left - when pilot status 'alive' - check safe zone \
    --               - outside safe zone, csar possible, set 'MIA'\
    --               - when pilot anything but 'alive' - ignore\
    \
    if not event.initiator then \
        trigger.action.outText(\"limAir: ***WARNING: event (\" .. ID .. \"): no initiator, should not have been procced\", 30)\
        return \
    end\
    \
    local theUnit = event.initiator\
    local unitName = theUnit:getName()\
    local ID = event.id\
    local myType = theUnit:getTypeName()\
    \
    -- \"20\" event (player enter): always processed \
--[[--    if ID == 20 or ID == 15 then -- player entered unit\
        limitedAirframes.addPlayerUnit(theUnit) -- will also update player and player status to 'alive'\
        -- now procc a 'cheater' since we entered a new airframe/pilot\
        limitedAirframes.checkPlayerFrameAvailability(event)\
        return \
    end\
--]]--\
    \
    if ID == 20 then -- 20 ENTER UNIT\
        local pName = limitedAirframes.getKnownUnitPilotByUnit(theUnit)\
        if not pName then pName = \"***UNKNOWN***\" end \
        --trigger.action.outText(\"limAir: Received ENTER UNIT (20) for \" .. pName .. \" in \" .. unitName , 30)\
        return \
    end\
    \
    if ID == 15 then -- birth - this one is called in network, 20 is too unreliable\
        -- can set where birthed: runway, parking, air etc.\
        limitedAirframes.addPlayerUnit(theUnit) -- will also update player and player status to 'alive'\
        -- now procc a 'cheater' since we entered a new airframe/pilot\
        limitedAirframes.checkPlayerFrameAvailability(event)\
        local playerName = theUnit:getPlayerName()\
        limitedAirframes.unitFlownByPlayer[unitName] = playerName\
        -- TODO: make sure this is the ONLY plane the player\
        -- is registered under, and mark mismatches\
        trigger.action.outText(\"limAir: 15 -- player \" .. playerName .. \" now in \" .. unitName, 30)\
        return \
    end\
    \
    -- make sure unit's player pilot is known\
    if not limitedAirframes.getKnownUnitPilotByUnitName(unitName) then\
        trigger.action.outText(\"limAir: ***WARNING: Ignored player event (\" .. ID .. \"): unable to retrieve player name for \" .. unitName, 30)\
        return  -- plane no longer of interest cant retrieve pilot -- BUG!!!\
    end\
    \
    \
    -- event 6 - eject - plane divorced but player pilot is known\
    if ID == 6 then -- eject\
        limitedAirframes.pilotEjected(event)            \
        return\
    end\
    \
    -- event 5 - crash - plane divorced but player pilot is known \
    -- if pilot is still alive, this should now cause a pilot lost event if we are a helicopter \
    \
    if ID == 5 then -- crash\
        -- as of new processing, no longer relevant\
        -- limitedAirframes.airFrameCrashed(event) \
        -- helicopters do not call died when helo\
        -- crashes. so check if we are still seated=alive \
        -- and call pilot dead then \
        -- for some reason, pilot died also may not be called \
        -- so if pilot is still alive and not MIA, he's now dead.\
        -- forget the helo check, this now applies to all \
\
        \
        local pStatus = limitedAirframes.getStatusOfPlayerInUnit(theUnit)\
        if pStatus == \"alive\" then \
            -- this frame was carrrying a live player \
            limitedAirframes.pilotDied(theUnit)\
            return \
        else \
            trigger.action.outText(\"limAir: Crash of airframe detected - but player status wasn't alive (\" .. pStatus .. \")\", 30)\
            return \
        end \
    end \
\
-- removed dual 21 detection here \
    \
    if ID == 21 then \
        -- remove pilot name from unit name \
        limitedAirframes.unitFlownByPlayer[unitName] = nil\
        --trigger.action.outText(\"limAir: 21 -- unit \" .. unitName .. \" unoccupied\", 30)\
        \
        trigger.action.outText(\"limAir: 21 (player left) for unit \" .. unitName , 30)\
        -- player left unit. Happens twice\
        -- check if player alive, else we have a ditch.\
        limitedAirframes.handlePlayerLeftUnit(event)\
        return \
    end\
    \
    \
    if ID == 9 then -- died \
        --trigger.action.outText(\"limAir: 9 (PILOT DEAD) for unit \" .. unitName , 30)\
        local thePilot = limitedAirframes.unitFlownByPlayer[unitName]\
        if not thePilot then \
            trigger.action.outText(\"+++limAir: 9 O'RIDE -- unit \" .. unitName .. \" was legally vacated before!\", 30)\
            return \
        end\
        limitedAirframes.pilotDied(theUnit)\
        return \
    end\
    \
    if ID == 30 then -- unit lost\
        return \
    end\
    \
\
    \
    trigger.action.outText(\"limAir: WARNING unhandled: \" .. ID .. \" for player unit \" .. theUnit:getName() .. \" of type \" .. myType, 30)\
end\
\
--\
-- HANDLE VARIOUS SITUATIONS\
--\
\
function limitedAirframes.handlePlayerLeftUnit(event)\
    local theUnit = event.initiator\
    -- make sure the pilot is alive\
    if limitedAirframes.getStatusOfPlayerInUnit(theUnit) ~= \"alive\" then \
        -- was already handled. simply exit\
        local pName = limitedAirframes.getKnownUnitPilotByUnitName(theUnit:getName())\
        local pStatus = limitedAirframes.getStatusOfPlayerInUnit(theUnit)\
        -- player was already dead and has been accounted for \
        --trigger.action.outText(\"limAir: Change Plane for player <\" .. pName .. \"> with status <\" .. pStatus .. \"> procced.\", 30)\
        return \
    end\
    \
    -- check if the unit was inside a safe zone\
    -- if so, graceful exit \
    local uPos = theUnit:getPoint() \
    local meInside = cfxZones.getZonesContainingPoint(uPos, limitedAirframes.safeZones)\
    local mySide = theUnit:getCoalition()\
    --local speed = dcsCommon.getUnitSpeed(theUnit) -- this can cause problems with carriers, so check if below \
    --local agl = dcsCommon.getUnitAGL(theUnit) -- this will cause problems with FARP and carriers. \
    -- we now check the inAir \
    local isInAir = theUnit:inAir()\
    --trigger.action.outTextForCoalition(mySide, \"limAir: safe check for Pilot \" .. theUnit:getPlayerName() .. \": agl=\" .. agl .. \", speed = \" .. speed .. \", air status = \" .. dcsCommon.bool2YesNo(isInAir), 30)\
\
    for i=1, #meInside do \
        -- I'm inside all these zones. We look for the first\
        -- that saves me \
        local theSafeZone = meInside[i]\
        local isSafe = false\
        if mySide == 1 then \
            isSafe = theSafeZone.redSafe \
        elseif mySide == 2 then \
            isSafe = theSafeZone.blueSafe\
        else \
            isSafe = true \
        end\
        \
        if theSafeZone.owner then\
            -- owned zone. olny allow in neutral or owned by same side \
            isSafe = isSafe and (mySide == theSafeZone.owner or theSafeZone.owner == 0)\
            trigger.action.outText(\"+++: Lim - \" .. theSafeZone.name .. \" ownership: myside = \" .. mySide .. \" zone owner is \" .. theSafeZone.owner, 30)\
        else \
            -- trigger.action.outText(\"+++: Zone \" .. theSafeZone.name .. \" has no ownership, skipping check\", 30)\
        end\
        \
        -- check we are at rest below 10m height. agl may give \
        -- misreadings on carriers and FARPs, while speed may read\
        -- wrongly on carriers (tbd). we now use isInAir to determine if\
        -- we ditched while in flight \
        --if speed > 2 or agl > 10 then isSafe = false end \
        --if not isInAir then return false end -- why *not* isInAir??? \
        \
        -- for matter of fact, why did we return ANYTHING???\
        -- there may be a bug here \
        -- maybe it should be \"if isInAir then isSafe = false\"??\
        if isInAir then isSafe = false end \
        \
        if isSafe then \
            trigger.action.outTextForCoalition(mySide, \"limAir: Pilot \" .. theUnit:getPlayerName() .. \" left unit \" .. theUnit:getName() .. \" legally in zone \" .. theSafeZone.name, 30)\
            -- remove from known player planes\
            -- no more limitedAirframes.removePlayerUnit(theUnit)\
            return;\
        end\
    end\
    \
    -- ditched outside safe harbour\
    trigger.action.outTextForCoalition(mySide, \"Pilot \" .. theUnit:getPlayerName() .. \" DITCHED unit \" .. theUnit:getName() .. \" -- PILOT LOSS (MIA)\", 30)\
    limitedAirframes.pilotLost(theUnit)\
    if csarManager and csarManager.airframeDitched then \
        csarManager.airframeDitched(theUnit)\
    end\
    \
    limitedAirframes.updatePlayerInUnit(theUnit, \"MIA\") -- cosmetic only\
    limitedAirframes.createCSAR(theUnit)\
end\
\
\
\
function limitedAirframes.pilotEjected(event)\
    local theUnit = event.initiator\
    -- do we want to check location?\
    -- no. if the user ejects, plane is done for\
    local theSide = theUnit:getCoalition()\
    local pilot = limitedAirframes.getKnownUnitPilotByUnit(theUnit)\
    local uName = theUnit:getName()\
    trigger.action.outTextForCoalition(theSide, \"Pilot <\" .. pilot .. \"> ejected from \" .. uName .. \", now MIA\", 30)\
    \
    local hasLostTheWar = limitedAirframes.pilotLost(theUnit)\
    \
    limitedAirframes.updatePlayerInUnit(theUnit, \"MIA\") -- cosmetic only\
    -- create CSAR if applicable\
    if not hasLostTheWar then \
        limitedAirframes.createCSAR(theUnit)\
    end \
end\
\
function limitedAirframes.pilotDied(theUnit)\
    --limitedAirframes.killPlayerInUnit(theUnit)\
    local theSide = theUnit:getCoalition()\
    local pilot = limitedAirframes.getKnownUnitPilotByUnit(theUnit)\
    local uName = theUnit:getName()\
    trigger.action.outTextForCoalition(theSide, \"Pilot <\" .. pilot .. \"> is confirmed KIA while controlling \" .. uName, 30)\
    limitedAirframes.pilotLost(theUnit)\
end\
\
function limitedAirframes.pilotLost(theUnit)\
    -- returns true if lost the war \
    -- MUST NOT MESSAGE PILOT STATUS AS MIA CAN ALSO BE SET\
    -- first DELETE THE UNIT FROM player-owned unit table\
    -- so an empty crash after eject/death will not be counted as two losses\
    limitedAirframes.killPlayerInUnit(theUnit)\
\
    -- now see if we are enabled to limit airframes \
    if not limitedAirframes.enabled then return false end \
    \
    -- find out which side lost the airframe and message side\
    local theSide = theUnit:getCoalition()\
    local pilot = limitedAirframes.getKnownUnitPilotByUnit(theUnit)\
    local uName = theUnit:getName()\
    --trigger.action.outTextForCoalition(theSide, \"Pilot <\" .. pilot .. \"> is confirmed KIA while controlling \" .. uName, 30)\
    \
    if theSide == 1 then -- red \
        theOtherSide = 2 \
        if     limitedAirframes.maxRed < 0 then return false end -- disabled/infinite\
        \
        limitedAirframes.currRed = limitedAirframes.currRed - 1\
        \
        if limitedAirframes.currRed == 0 then\
            trigger.action.outTextForCoalition(theSide, \"\\nYou have lost almost all of your pilots.\\n\\nWARNING: Losing any more pilots WILL FAIL THE MISSION\\n\", 30)\
            trigger.action.outSoundForCoalition(theSide, \"Quest Snare 3.wav\")\
            return false  \
        end\
        \
        if limitedAirframes.currRed < 0 then \
            -- red have lost all airframes \
            trigger.action.outText(\"\\nREDFORCE has lost all of their pilots.\\n\\nBLUEFORCE WINS!\\n\", 30)\
            trigger.action.outSoundForCoalition(theSide, \"Death PIANO.wav\")\
            trigger.action.outSoundForCoalition(theOtherSide, \"Triumphant Victory.wav\")\
            trigger.action.setUserFlag(limitedAirframes.blueWinsFlag, 1 )\
            return true \
        end\
        \
        \
    elseif theSide == 2 then -- blue \
        theOtherSide = 1\
        if     limitedAirframes.maxBlue < 0 then return false end -- disabled/infinite\
        limitedAirframes.currBlue = limitedAirframes.currBlue - 1\
        if limitedAirframes.currBlue == 0 then\
            trigger.action.outTextForCoalition(theSide, \"\\nYou have lost almost all of your pilots.\\n\\nWARNING: Losing any more pilots WILL FAIL THE MISSION\\n\", 30)\
            trigger.action.outSoundForCoalition(theSide, \"Quest Snare 3.wav\")\
            return false \
        end\
        if limitedAirframes.currBlue < 0 then \
            -- red have lost all airframes \
            trigger.action.outText(\"\\nBLUEFORCE has lost all of their pilots.\\n\\nREDFORCE WINS!\\n\", 30)\
            trigger.action.setUserFlag(limitedAirframes.redWinsFlag, 1 )\
            trigger.action.outSoundForCoalition(theSide, \"Death PIANO.wav\")\
            trigger.action.outSoundForCoalition(theOtherSide, \"Triumphant Victory.wav\")\
            return true \
        end\
        trigger.action.outSoundForCoalition(theSide, \"Quest Snare 3.wav\")\
        trigger.action.outTextForCoalition(theSide, \"You have lost a pilot! Remaining: \" .. limitedAirframes.currBlue, 30)\
    end\
    return false \
end\
\
function limitedAirframes.checkPlayerFrameAvailability(event)\
    local theUnit = event.initiator\
    local theSide = theUnit:getCoalition()\
    if theSide == 1 then -- red \
        if     limitedAirframes.maxRed < 0 then return end -- disabled/infinite\
        if limitedAirframes.currRed < 0 then \
            -- red have lost all airframes \
            trigger.action.outText(\"\\nREDFORCE is a CHEATER!\\n\", 30)\
            return \
        end\
    elseif theSide == 2 then -- blue \
        if     limitedAirframes.maxBlue < 0 then return end -- disabled/infinite\
        if limitedAirframes.currBlue < 0 then \
            -- red have lost all airframes \
            trigger.action.outText(\"\\nBLUEFORCE is a CHEATER!\\n\", 30)\
            return \
        end\
    end\
end\
\
\
function limitedAirframes.createCSAR(theUnit)\
    -- only do this if we have installed CSAR Manager\
    if csarManager and csarManager.createCSARforUnit then \
        csarManager.createCSARforUnit(theUnit, \
            limitedAirframes.getKnownUnitPilotByUnit(theUnit),\
            100)\
    end\
end\
\
-- start up\
\
function limitedAirframes.addSafeZone(aZone)\
    if not aZone then \
        trigger.action.outText(\"WARNING: NIL Zone in addSafeZone\", 30)\
        return \
    end\
\
    -- transfer properties if they exist \
    -- blueSafe, redSafe: what side this is safe for, default = yes \
    \
    -- add zone to my list\
    limitedAirframes.safeZones[aZone] = aZone \
    aZone.redSafe = true\
    aZone.redSafe = cfxZones.getBoolFromZoneProperty(aZone, \"redSafe\", true)\
    aZone.blueSafe = true \
    aZone.blueSafe = cfxZones.getBoolFromZoneProperty(aZone, \"blueSafe\", true)\
\
    trigger.action.outText(\"limAir: added safeZone \" .. aZone.name, 30)\
end\
\
\
\
--\
-- COMMAND & CONFIGURATION\
--\
function limitedAirframes.setCommsMenu()\
    local desc = \"Pilot Count (Currently ON)\"\
    local desc2 = \"Turn OFF Pilot Count (Cheat)?\"\
    if not limitedAirframes.enabled then \
        desc = \"Pilot Count (Currently OFF)\"\
        desc2 = \"ENABLE Pilot Count\"\
    end\
    -- remove previous version\
    if limitedAirframes.rootMenu then \
        missionCommands.removeItem(limitedAirframes.theScore)\
        missionCommands.removeItem(limitedAirframes.theCommand)\
        missionCommands.removeItem(limitedAirframes.rootMenu)\
    end\
    limitedAirframes.theCommand = nil\
    limitedAirframes.rootMenu = nil \
    \
    -- add current version menu and command\
    limitedAirframes.rootMenu = missionCommands.addSubMenu(desc, nil)\
    \
    limitedAirframes.theScore = missionCommands.addCommand(\"How many airframes left?\" , limitedAirframes.rootMenu, limitedAirframes.redirectAirframeScore, {\"none\"})\
    \
    limitedAirframes.theCommand = missionCommands.addCommand(desc2 , limitedAirframes.rootMenu, limitedAirframes.redirectToggleAirFrames, {\"none\"})\
    \
end\
\
function limitedAirframes.redirectAirframeScore(args)\
    timer.scheduleFunction(limitedAirframes.doAirframeScore, args, timer.getTime() + 0.1)\
end\
\
function limitedAirframes.doAirframeScore(args)\
    local redRemaining = \"unlimited\"\
    if limitedAirframes.maxRed >= 0 then \
        redRemaining = limitedAirframes.currRed .. \" of \" .. limitedAirframes.maxRed\
        if limitedAirframes.currRed < 1 then \
            redRemaining = \"no\"\
        end\
    end\
    \
    local blueRemaining = \"unlimited\"\
    if limitedAirframes.maxBlue >= 0 then \
        blueRemaining = limitedAirframes.currBlue .. \" of \" .. limitedAirframes.maxBlue\
        if limitedAirframes.currBlue < 1 then \
            blueRemaining = \"no\"\
        end\
    end\
    \
    local msg = \"\\nRED has \" .. redRemaining .. \" pilots left,\\nBLUE has \" .. blueRemaining .. \" pilots left\\n\"\
    trigger.action.outText(msg, 30, true)\
    trigger.action.outSound(\"Quest Snare 3.wav\")\
end\
\
function limitedAirframes.redirectToggleAirFrames(args)\
    timer.scheduleFunction(limitedAirframes.doToggleAirFrames, args, timer.getTime() + 0.1)\
end\
\
function limitedAirframes.doToggleAirFrames(args)\
    limitedAirframes.enabled = not limitedAirframes.enabled\
    limitedAirframes.setCommsMenu()\
    local desc = \"\\n\\nPilot Count rule NOW IN EFFECT\\n\\n\"\
    \
    if limitedAirframes.enabled then \
        trigger.action.outSound(\"Quest Snare 3.wav\")\
    else\
        desc = \"\\n\\nYou cowardly disabled Pilot Count\\n\\n\"\
        trigger.action.outSound(\"Death PIANO.wav\")\
    end\
    trigger.action.outText(desc, 30)\
    limitedAirframes.setCommsMenu()\
end\
\
--\
-- CSAR CALLBACK\
--\
\
function limitedAirframes.pilotsRescued(theCoalition, success, numRescued, notes)\
    local availablePilots = 0\
    if theCoalition == 1 then -- red \
        limitedAirframes.currRed = limitedAirframes.currRed + numRescued\
        if limitedAirframes.currRed > limitedAirframes.maxRed then \
            limitedAirframes.currRed = limitedAirframes.maxRed \
        end\
        availablePilots = limitedAirframes.currRed\
        if limitedAirframes.maxRed < 0 then \
            availablePilots = \"unlimited\"\
        end \
    end\
    \
    if theCoalition == 2 then -- blue \
        limitedAirframes.currBlue = limitedAirframes.currBlue + numRescued\
        if limitedAirframes.currBlue > limitedAirframes.maxBlue then \
            limitedAirframes.currBlue = limitedAirframes.maxBlue \
        end\
        availablePilots = limitedAirframes.currBlue\
        if limitedAirframes.maxBlue < 0 then \
            availablePilots = \"unlimited\"\
        end \
    end\
    trigger.action.outTextForCoalition(theCoalition, \"\\nPilots returned to flight line, you now have \" .. availablePilots..\".\\n\", 30)\
    trigger.action.outSoundForCoalition(theCoalition, \"Quest Snare 3.wav\")\
end\
\
--\
-- START \
--\
\
function limitedAirframes.start()\
    if not dcsCommon.libCheck(\"cfx Limited Airframes\", \
        limitedAirframes.requiredLibs) then\
        return false \
    end\
    \
    -- override config settings if defined as zone\
    limitedAirframes.readConfigZone()\
    \
    -- collect all zones that are airframe safe \
    local afsZones = cfxZones.zonesWithProperty(\"pilotSafe\")\
    \
    -- now add all zones to my zones table, and init additional info\
    -- from properties\
    for k, aZone in pairs(afsZones) do\
        limitedAirframes.addSafeZone(aZone)\
    end\
    \
    -- connect player callback \
    -- install callbacks for airframe-related events\
    dcsCommon.addEventHandler(limitedAirframes.somethingHappened, limitedAirframes.preProcessor, limitedAirframes.postProcessor)\
    \
    \
    -- set current values\
    limitedAirframes.currRed = limitedAirframes.maxRed\
    limitedAirframes.currBlue = limitedAirframes.maxBlue\
    \
    -- collect active player unit names \
    local allPlayerUnits = cfxPlayer.getAllExistingPlayerUnitsRaw()\
    for i=1, #allPlayerUnits do \
        local aUnit = allPlayerUnits[i]\
        limitedAirframes.addPlayerUnit(aUnit)\
--        trigger.action.outText(\"limAir: detected active player unit \" .. aUnit:getName(), 30)\
    end\
    \
    \
    -- allow configuration menu \
    if limitedAirframes.userCanToggle then     \
        limitedAirframes.setCommsMenu()\
    end\
    \
    -- connect to csarManager if present \
    if csarManager and csarManager.installCallback then \
        csarManager.installCallback(limitedAirframes.pilotsRescued)\
        trigger.action.outText(\"+++lim: connected to csar manager\", 30)\
    else \
        trigger.action.outText(\"+++lim: NO CSAR integration\", 30)\
    end\
    \
    -- say hi\
    trigger.action.outText(\"limitedAirframes v\" .. limitedAirframes.version .. \" started: R:\".. limitedAirframes.maxRed .. \"/B:\" .. limitedAirframes.maxBlue, 30)\
    return true \
end\
\
if not limitedAirframes.start() then \
    limitedAirframes = nil\
    trigger.action.outText(\"cf/x Limited Airframes aborted: missing libraries\", 30)\
end\
\
\
\
--[[--\
   safe ditch: check airspeed and altitude. ditch only counts if less than 10m and 2 kts \
   report number of airframes left via second instance in switch off menu\
--]]--",
                    ["predicate"] = "a_do_script",
                }, -- end of [5]
                [6] = 
                {
                    ["text"] = "cfxPlayerScore = {}\
cfxPlayerScore.version = \"1.3.0\"\
cfxPlayerScore.badSound = \"Death BRASS.wav\"\
cfxPlayerScore.scoreSound = \"Quest Snare 3.wav\"\
cfxPlayerScore.announcer = true \
--[[-- VERSION HISTORY\
    1.0.1 - bug fixes to killDetected \
    1.0.2 - messaging clean-up, less verbose \
    1.1.0 - integrated score base system\
          - accepts configZones \
          - module validation \
          - isNamedUnit(theUnit)\
          - notify if named unit killed \
          - kill weapon reported \
    1.2.0 - score table \
          - announcer attribute \
          - badSound name \
          - scoreSound name \
    1.3.0 - object2score \
          - static objects also can score \
          - can now also score members of group by adding group name \
          - scenery objects are now supported. use the \
            number that is given under OBJECT ID when \
            using assign as...\
    \
          \
--]]--\
cfxPlayerScore.requiredLibs = {\
    \"dcsCommon\", -- this is doing score keeping\
    \"cfxPlayer\", -- player events, comms \
    \"cfxZones\", -- zones for config \
}\
cfxPlayerScore.playerScore = {} -- init to empty\
\
-- typeScore: dictionary sorted by typeString for score \
-- extend to add more types. It is used by unitType2score to \
-- determine the base unit score  \
cfxPlayerScore.typeScore = {}\
 \
--\
-- we subscribe to the kill event. each time a unit \
-- is killed, we check if it was killed by a player\
-- and if so, that player record is updated and the side\
-- whom the player belongs to is informed\
--\
cfxPlayerScore.aircraft = 50 \
cfxPlayerScore.helo = 40 \
cfxPlayer.ground = 10\
cfxPlayerScore.ship = 80 \
cfxPlayerScore.train = 5 \
\
function cfxPlayerScore.cat2BaseScore(inCat)\
    if inCat == 0 then return cfxPlayerScore.aircraft end -- airplane\
    if inCat == 1 then return cfxPlayerScore.helo end -- helo \
    if inCat == 2 then return cfxPlayer.ground end -- ground \
    if inCat == 3 then return cfxPlayerScore.ship end -- ship \
    if inCat == 4 then return cfxPlayerScore.train end -- train \
    \
    trigger.action.outText(\"+++scr c2bs: unknown category for lookup: <\" .. inCat .. \">, returning 1\", 30)\
    \
    return 1 \
end\
\
function cfxPlayerScore.object2score(inVictim) -- does not have group\
    if not inVictim then return end \
    local inName = inVictim:getName()\
    if not inName then return 0 end \
    if type(inName) == \"number\" then \
        inName = tostring(inName)\
    end\
        \
    local objectScore = cfxPlayerScore.typeScore[inName]\
    if not objectScore then \
        -- try the type desc \
        local theType = inVictim:getTypeName()\
        objectScore = cfxPlayerScore.typeScore[theType]\
    end\
    \
    if type(objectScore) == \"string\" then \
        objectScore = tonumber(objectScore)\
    end\
    if not objectScore then return 0 end \
    return objectScore \
end\
\
function cfxPlayerScore.unit2score(inUnit)\
    local vicGroup = inUnit:getGroup()\
    local vicCat = vicGroup:getCategory()\
    local vicType = inUnit:getTypeName()\
    local vicName = inUnit:getName() \
    if type(vicName) == \"number\" then vicName = tostring(vicName) end \
    \
    -- simply extend by adding items to the typescore table.concat\
    -- we first try by unit name. This allows individual\
    -- named hi-value targets to have individual scores \
    local uScore = cfxPlayerScore.typeScore[vicName]\
\
    -- see if all members of group score \
    if not uScore then \
        local grpName = vicGroup:getName()\
        uScore = cfxPlayerScore.typeScore[grpName]\
    end\
    \
    if uScore == nil then \
        -- WE NOW TRY TO ACCESS BY VICTIM'S TYPE STRING        \
        uScore = cfxPlayerScore.typeScore[vicType]\
    else \
\
    end \
    if type(uScore) == \"string\" then \
        -- convert string to number \
        uScore = tonumber(uScore)\
    end\
\
    if uScore == nil then uScore = 0 end \
    if uScore > 0 then return uScore end \
    \
    -- only apply base scores when the lookup did not give a result\
    uScore = cfxPlayerScore.cat2BaseScore(vicCat)\
    return uScore \
end\
\
function cfxPlayerScore.getPlayerScore(playerName)\
    local thePlayerScore = cfxPlayerScore.playerScore[playerName]\
    if thePlayerScore == nil then \
        thePlayerScore = {}\
        thePlayerScore.name = playerName\
        thePlayerScore.score = 0 -- score\
        thePlayerScore.killTypes = {} -- the type strings killed\
        thePlayerScore.totalKills = 0 -- number of kills total \
    end\
    return thePlayerScore\
end\
\
function cfxPlayerScore.setPlayerScore(playerName, thePlayerScore)\
    cfxPlayerScore.playerScore[playerName] = thePlayerScore\
end\
\
function cfxPlayerScore.updateScoreForPlayer(playerName, score)\
    local thePlayerScore = cfxPlayerScore.getPlayerScore(playerName)\
    \
    thePlayerScore.score = thePlayerScore.score + score\
    cfxPlayerScore.setPlayerScore(playerName, thePlayerScore)\
    return thePlayerScore.score \
end\
\
function cfxPlayerScore.logKillForPlayer(playerName, theUnit)\
    if not theUnit then return end\
    if not playerName then return end \
    \
    local thePlayerScore = cfxPlayerScore.getPlayerScore(playerName)\
    \
    local theType = theUnit:getTypeName()\
    local killCount = thePlayerScore.killTypes[theType]\
    if killCount == nil then \
        killCount = 0\
    end\
    killCount = killCount + 1\
    thePlayerScore.totalKills = thePlayerScore.totalKills + 1\
    thePlayerScore.killTypes[theType] = killCount\
    \
    cfxPlayerScore.setPlayerScore(playerName, thePlayerScore)\
end\
\
function cfxPlayerScore.playerScore2text(thePlayerScore)\
    local desc = thePlayerScore.name .. \" - score: \".. thePlayerScore.score .. \" - kills: \" .. thePlayerScore.totalKills .. \"\\n\"\
    -- now go through all killSide\
    for theType, quantity in pairs(thePlayerScore.killTypes) do \
        desc = desc .. \"  - \" .. theType .. \": \" .. quantity .. \"\\n\"\
    end\
    return desc\
end\
\
function cfxPlayerScore.scoreTextForPlayerNamed(playerName)\
    local thePlayerScore = cfxPlayerScore.getPlayerScore(playerName)\
    return cfxPlayerScore.playerScore2text(thePlayerScore)\
end\
\
function cfxPlayerScore.isNamedUnit(theUnit) \
    if not theUnit then return false end \
    local theName = \"(cfx_none)\"\
    if type(theUnit) == \"string\" then \
        theName = theUnit -- direct name assignment\
        -- WARNING: NO EXIST CHECK DONE!\
    else \
        -- after kill, unit is dead, so will no longer exist!\
        theName = theUnit:getName() \
        if not theName then return false end \
    end\
    if cfxPlayerScore.typeScore[theName] then \
        return true\
    end\
    return false \
end\
\
function cfxPlayerScore.awardScoreTo(killSide, theScore, killerName)\
    local playerScore = cfxPlayerScore.updateScoreForPlayer(killerName, theScore)\
    \
    if cfxPlayerScore.announcer then \
        trigger.action.outTextForCoalition(killSide, \"Killscore:  \" .. theScore .. \" for a total of \" .. playerScore .. \" for \" .. killerName, 30)\
    end \
end\
--\
-- EVENT HANDLING\
--\
function cfxPlayerScore.preProcessor(theEvent)\
    -- return true if the event should be processed\
    -- by us\
    \
    if theEvent.id == 28 then\
        -- we only are interested in kill events where \
        -- there is an initiator, and the initiator is \
        -- a player \
        if theEvent.initiator  == nil then \
            return false \
        end \
        \
        local killer = theEvent.initiator \
        if theEvent.target == nil then \
            if cfxPlayerScore.verbose then \
                trigger.action.outText(\"+++scr pre: nil TARGET\", 30) \
            end \
            return false \
        end \
        \
        local wasPlayer = cfxPlayer.isPlayerUnit(killer)\
        return wasPlayer\
    end\
    return false \
end\
\
function cfxPlayerScore.postProcessor(theEvent)\
    -- don't do anything\
end\
\
function cfxPlayerScore.killDetected(theEvent)\
    -- we are only getting called when and if \
    -- a kill occured and killer was a player \
    -- and target exists\
    \
    local killer = theEvent.initiator\
    local killerName = killer:getPlayerName()\
    if not killerName then killerName = \"<nil>\" end\
    local killSide = killer:getCoalition()\
    local killVehicle = killer:getTypeName()\
    if not killVehicle then killVehicle = \"<nil>\" end \
    local victim = theEvent.target\
\
    -- was it a player kill?\
    local pk = cfxPlayer.isPlayerUnit(victim)\
\
    -- was it a scenery object? \
    local wasBuilding = dcsCommon.isSceneryObject(victim)\
    if wasBuilding then \
        -- these objects have no coalition; we simply award the score if \
        -- it exists in look-up table. \
        local staticScore = cfxPlayerScore.object2score(victim)\
        if staticScore > 0 then \
            trigger.action.outSoundForCoalition(killSide, cfxPlayerScore.scoreSound)\
            cfxPlayerScore.awardScoreTo(killSide, staticScore, killerName)\
        end\
        return \
    end\
\
    -- was it fraternicide?\
    local vicSide = victim:getCoalition()\
    local fraternicide = killSide == vicSide\
    local vicDesc = victim:getTypeName()\
    local scoreMod = 1 -- start at one \
\
    -- see what kind of unit (category) we killed\
    -- and look up base score \
    if not victim.getGroup then\
        -- static objects have no group \
\
        local staticName = victim:getName() -- on statics, this returns \
                                            -- name as entered in TOP LINE\
        local staticScore = cfxPlayerScore.object2score(victim)\
        if staticScore > 0 then \
            -- this was a named static, return the score - unless our own\
            if fraternicide then \
                scoreMod = -2 * scoreMod \
                trigger.action.outSoundForCoalition(killSide, cfxPlayerScore.badSound)\
            else \
                trigger.action.outSoundForCoalition(killSide, cfxPlayerScore.scoreSound)\
            end\
            staticScore = scoreMod * staticScore\
            cfxPlayerScore.awardScoreTo(killSide, staticScore, killerName)\
        else \
            -- no score, no mentions\
        end\
        \
        return \
    end \
    \
    local vicGroup = victim:getGroup()\
    local vicCat = vicGroup:getCategory()\
    local unitScore = cfxPlayerScore.unit2score(victim)\
\
    -- see which weapon was used. gun kills score 2x \
    local killMeth = \"\"\
    local killWeap = theEvent.weapon\
    if killWeap then \
        local killWeapType = killWeap:getCategory()\
        if killWeapType == 0 then \
            killMeth = \" with GUNS\" \
            scoreMod = scoreMod * 2\
        else \
            local kWeapon = killWeap:getTypeName()\
            killMeth = \" with \" .. kWeapon\
        end\
    else \
        \
    end\
    \
    if pk then \
        vicDesc = victim:getPlayerName() .. \" in \" .. vicDesc \
        scoreMod = scoreMod * 10\
    end \
    \
    if fraternicide then\
        scoreMod = scoreMod * -2\
        if cfxPlayerScore.announcer then \
            trigger.action.outTextForCoalition(killSide, killerName .. \" in \" .. killVehicle .. \" killed FRIENDLY \" .. vicDesc .. killMeth .. \"!\", 30)\
            trigger.action.outSoundForCoalition(killSide, cfxPlayerScore.badSound)\
        end \
    else \
        if cfxPlayerScore.announcer then \
            trigger.action.outText(killerName .. \" in \" .. killVehicle ..\" killed \" .. vicDesc .. killMeth ..\"!\", 30)\
            trigger.action.outSoundForCoalition(vicSide, cfxPlayerScore.badSound)\
            trigger.action.outSoundForCoalition(killSide, cfxPlayerScore.scoreSound)\
         end \
         -- since not fraticide, log this kill\
         -- logging kills does not impct score\
         cfxPlayerScore.logKillForPlayer(killerName, victim)\
    end\
    \
    -- see if it was a named target \
    if cfxPlayerScore.isNamedUnit(victim) then \
        if cfxPlayerScore.announcer then \
            trigger.action.outTextForCoalition(killSide, killerName .. \" reports killing strategic unit '\" .. victim:getName() .. \"'\", 30)\
        end \
    end\
    \
    local totalScore = unitScore * scoreMod\
    cfxPlayerScore.awardScoreTo(killSide, totalScore, killerName)\
\
end\
\
function cfxPlayerScore.readConfigZone(theZone)\
    cfxPlayerScore.verbose = cfxZones.getBoolFromZoneProperty(theZone, \"verbose\", false)\
    -- default scores \
    cfxPlayerScore.aircraft = cfxZones.getNumberFromZoneProperty(theZone, \"aircraft\", 50) \
    cfxPlayerScore.helo = cfxZones.getNumberFromZoneProperty(theZone, \"helo\", 40)  \
    cfxPlayer.ground = cfxZones.getNumberFromZoneProperty(theZone, \"ground\", 10)  \
    cfxPlayerScore.ship = cfxZones.getNumberFromZoneProperty(theZone, \"ship\", 80)   \
    cfxPlayerScore.train = cfxZones.getNumberFromZoneProperty(theZone, \"train\", 5)\
    \
    cfxPlayerScore.announcer = cfxZones.getBoolFromZoneProperty(theZone, \"announcer\", true)\
    \
    if cfxZones.hasProperty(theZone, \"badSound\") then \
        cfxReconMode.badSound = cfxZones.getStringFromZoneProperty(theZone, \"badSound\", \"<nosound>\")\
    end\
    if cfxZones.hasProperty(theZone, \"scoreSound\") then \
        cfxReconMode.scoreSound = cfxZones.getStringFromZoneProperty(theZone, \"scoreSound\", \"<nosound>\")\
    end\
end\
\
function cfxPlayerScore.start()\
    if not dcsCommon.libCheck(\"cfx Player Score\", \
                              cfxPlayerScore.requiredLibs) \
    then \
        return false \
    end\
    \
    -- read my score table \
    -- identify and process a score table zones\
    local theZone = cfxZones.getZoneByName(\"playerScoreTable\") \
    if not theZone then \
        trigger.action.outText(\"+++scr: no score table!\", 30) \
    else \
        -- read all into my types registry, replacing whatever is there\
        cfxPlayerScore.typeScore = cfxZones.getAllZoneProperties(theZone)\
        trigger.action.outText(\"+++scr: read score table\", 30) \
    end \
    \
    -- now read my config zone \
    local theZone = cfxZones.getZoneByName(\"playerScoreConfig\") \
    if not theZone then \
        trigger.action.outText(\"+++scr: no config!\", 30) \
    else \
        cfxPlayerScore.readConfigZone(theZone)\
        trigger.action.outText(\"+++scr: read config\", 30) \
    end \
    \
    -- subscribe to events and use dcsCommon's handler structure\
    dcsCommon.addEventHandler(cfxPlayerScore.killDetected,\
                              cfxPlayerScore.preProcessor,\
                              cfxPlayerScore.postProcessor)\
    trigger.action.outText(\"cfxPlayerScore v\" .. cfxPlayerScore.version .. \" started\", 30)\
    return true \
end\
\
\
if not cfxPlayerScore.start() then \
    trigger.action.outText(\"+++ aborted cfxPlayerScore v\" .. cfxPlayerScore.version .. \"  -- libcheck failed\", 30)\
    cfxPlayerScore = nil \
end\
\
-- TODO: score mod for weapons type \
-- TODO: player kill score \
 ",
                    ["predicate"] = "a_do_script",
                }, -- end of [6]
                [7] = 
                {
                    ["text"] = "cfxReconMode = {}\
cfxReconMode.version = \"1.4.1\"\
cfxReconMode.verbose = false -- set to true for debug info  \
cfxReconMode.reconSound = \"UI_SCI-FI_Tone_Bright_Dry_20_stereo.wav\" -- to be played when somethiong discovered\
\
cfxReconMode.prioList = {} -- group names that are high prio and generate special event\
cfxReconMode.blackList = {} -- group names that are NEVER detected. Comma separated strings, e.g. {\"Always Hidden\", \"Invisible Group\"}\
\
cfxReconMode.requiredLibs = {\
    \"dcsCommon\", -- always\
    \"cfxZones\", -- Zones, of course \
}\
\
--[[--\
VERSION HISTORY\
 1.0.0 - initial version \
 1.0.1 - removeScoutByName()\
 1.0.2 - garbage collection \
 1.1.0 - autoRecon - any aircraft taking off immediately\
         signs up, no message when signing up or closing down\
         standalone - copied common procs lerp, agl, dist, distflat\
         from dcsCommon\
         report numbers \
         verbose flag \
 1.2.0 - queued recons. One scout per second for more even\
         performance\
         removed gc since it's now integrated into \
         update queue\
         removeScout optimization when directly passing name\
         playerOnlyRecon for autoRecon \
         red, blue, grey side filtering on auto scout\
 1.2.1 - parametrized report sound \
 1.3.0 - added black list, prio list functionality \
 1.3.1 - callbacks now also push name, as group can be dead\
       - removed bug when removing dead groups from map\
 1.4.0 - import dcsCommon, cfxZones etc \
       - added lib check \
       - config zone \
       - prio+\
       - detect+\
 1.4.1 - invocation no longer happen twice for prio. \
       - recon sound \
       - read all flight groups at start to get rid of the \
       - late activation work-around \
 \
 \
 cfxReconMode is a script that allows units to perform reconnaissance\
 missions and, after detecting units, marks them on the map with \
 markers for their coalition and some text \
 Also, a callback is initiated for scouts as follows\
   signature: (reason, theSide, theSout, theGroup) with  \
   reason a string \
     'detected' a group was detected\
     'removed' a mark for a group timed out\
     'priority' a member of prio group was detected \
     'start' a scout started scouting\
     'end' a scout stopped scouting\
     'dead' a scout has died and was removed from pool \
   theSide - side of the SCOUT that detected units\
   theScout - the scout that detected the group \
   theGroup - the group that is detected  \
   theName - the group's name    \
--]]--\
\
cfxReconMode.detectionMinRange = 3000 -- meters at ground level\
cfxReconMode.detectionMaxRange = 12000 -- meters at max alt (10'000m)\
cfxReconMode.maxAlt = 9000 -- alt for maxrange (9km = 27k feet)\
\
cfxReconMode.autoRecon = true -- add all airborne units, unless \
cfxReconMode.redScouts = false -- set to false to prevent red scouts in auto mode\
cfxReconMode.blueScouts = true -- set to false to prevent blue scouts in auto-mode\
cfxReconMode.greyScouts = false -- set to false to prevent neutral scouts in auto mode\
cfxReconMode.playerOnlyRecon = false -- only players can do recon \
cfxReconMode.reportNumbers = true -- also add unit count in report \
cfxReconMode.prioFlag = nil \
cfxReconMode.detectFlag = nil \
cfxReconMode.applyMarks = true \
\
cfxReconMode.ups = 1 -- updates per second.\
cfxReconMode.scouts = {} -- units that are performing scouting.\
cfxReconMode.processedScouts = {} -- for managing performance: queue\
cfxReconMode.detectedGroups = {} -- so we know which have been detected\
cfxReconMode.marksFadeAfter = 30*60 -- after detection, marks disappear after\
                     -- this amount of seconds. -1 means no fade\
                     -- 60 is one minute\
\
cfxReconMode.callbacks = {} -- sig: cb(reason, side, scout, group)\
cfxReconMode.uuidCount = 0 -- for unique marks \
\
\
-- end standalone dcsCommon extract \
\
function cfxReconMode.uuid()\
    cfxReconMode.uuidCount = cfxReconMode.uuidCount + 1\
    return cfxReconMode.uuidCount\
end\
\
function cfxReconMode.addCallback(theCB)\
    table.insert(cfxReconMode.callbacks, theCB)\
end\
\
function cfxReconMode.invokeCallbacks(reason, theSide, theScout, theGroup, theName)\
    for idx, theCB in pairs(cfxReconMode.callbacks) do \
        theCB(reason, theSide, theScout, theGroup, theName)\
    end\
end\
\
-- add a priority/blackList group name to prio list \
function cfxReconMode.addToPrioList(aGroup)\
    if not aGroup then return end \
    if type(aGroup) == \"table\" and aGroup.getName then \
        aGroup = aGroup:getName()\
    end\
    if type(aGroup) == \"string\" then \
        table.insert(cfxReconMode.prioList, aGroup)\
    end\
end\
\
function cfxReconMode.addToBlackList(aGroup)\
    if not aGroup then return end \
    if type(aGroup) == \"table\" and aGroup.getName then \
        aGroup = aGroup:getName()\
    end\
    if type(aGroup) == \"string\" then \
        table.insert(cfxReconMode.blackList, aGroup)\
    end\
end\
\
\
function cfxReconMode.isStringInList(theString, theList)\
    if not theString then return false end \
    if not theList then return false end \
    if type(theString) == \"string\" then \
        for idx,anItem in pairs(theList) do \
            if anItem == theString then return true end\
        end\
    end\
    return false\
end\
\
-- addScout directly adds a scout unit. Use from external \
-- to manually add a unit (e.g. via GUI when autoscout isExist\
-- off, or to force a scout unit (e.g. when scouts for a side\
-- are not allowed but you still want a unit from that side \
-- to scout\
-- since we use a queue for scouts, also always check the \
-- processed queue before adding to make sure a scout isn't \
-- entered multiple times \
\
function cfxReconMode.addScout(theUnit)\
    if not theUnit then \
        trigger.action.outText(\"+++cfxRecon: WARNING - nil Unit on add\", 30)\
        return\
    end\
    \
    if type(theUnit) == \"string\" then \
        local u = Unit.getByName(theUnit) \
        theUnit = u\
    end \
    \
    if not theUnit then \
        trigger.action.outText(\"+++cfxRecon: WARNING - did not find unit on add\", 30)\
        return \
    end    \
    if not theUnit:isExist() then return end \
    -- find out if this an update or a new scout \
    local thisID = tonumber(theUnit:getID())\
    local theName = theUnit:getName() \
    local lastUnit = cfxReconMode.scouts[theName]\
    local isProcced = false -- may also be in procced line \
    if not lastUnit then \
        lastUnit = cfxReconMode.processedScouts[theName]\
        if lastUnit then isProcced = true end \
    end\
\
    if lastUnit then \
        -- this is merely an overwrite \
        if cfxReconMode.verbose then trigger.action.outText(\"+++rcn: UPDATE scout \" .. theName .. \" -- no CB invoke\", 30) end \
    else \
        if cfxReconMode.verbose then trigger.action.outText(\"+++rcn: new scout \" .. theName .. \" with ID \" .. thisID, 30) end \
        -- a new scout! Invoke callbacks\
        local scoutGroup = theUnit:getGroup()\
        local theSide = scoutGroup:getCoalition()\
        cfxReconMode.invokeCallbacks(\"start\", theSide, theUnit, nil, \"<none>\")\
    end \
    \
    if isProcced then \
        -- overwrite exiting entry in procced queue\
        cfxReconMode.processedScouts[theName] = theUnit\
    else \
        -- add / overwrite into normal queue \
        cfxReconMode.scouts[theName] = theUnit\
    end \
    \
    if cfxReconMode.verbose then\
        trigger.action.outText(\"+++rcn: addded scout \" .. theUnit:getName(), 30)\
    end\
end\
\
\
function cfxReconMode.removeScout(theUnit)\
    if not theUnit then \
        trigger.action.outText(\"+++cfxRecon: WARNING - nil Unit on remove\", 30)\
        return \
    end\
    \
    if type(theUnit) == \"string\" then \
        cfxReconMode.removeScoutByName(theUnit)\
        return \
    end \
    \
    if not theUnit then return end    \
    if not theUnit:isExist() then return end \
    cfxReconMode.removeScoutByName(theUnit:getName())\
    local scoutGroup = theUnit:getGroup()\
    local theSide = scoutGroup:getCoalition()\
    cfxReconMode.invokeCallbacks(\"end\", theSide, theUnit, nil, \"<none>\")\
end\
\
-- warning: removeScoutByName does NOT invoke callbacks, always\
-- use removeScout instead!\
function cfxReconMode.removeScoutByName(aName)\
    cfxReconMode.scouts[aName] = nil\
    cfxReconMode.processedScouts[aName] = nil -- also remove from processed stack \
    if cfxReconMode.verbose then\
        trigger.action.outText(\"+++rcn: removed scout \" .. aName, 30)\
    end\
end\
\
\
function cfxReconMode.canDetect(scoutPos, theGroup, visRange)\
    -- determine if a member of theGroup can be seen from \
    -- scoutPos at visRange \
    -- returns true and pos when detected\
    local allUnits = theGroup:getUnits()\
    for idx, aUnit in pairs(allUnits) do\
        if aUnit:isExist() and aUnit:getLife() >= 1 then \
            local uPos = aUnit:getPoint()\
            uPos.y = uPos.y + 3 -- raise my 3 meters\
            local d = dcsCommon.distFlat(scoutPos, uPos) \
            if d < visRange then \
                -- is in visual range. do we have LOS?\
                if land.isVisible(scoutPos, uPos) then \
                    -- group is visible, stop here, return true\
                    return true, uPos\
                end\
            else \
                -- OPTIMIZATION: if a unit is outside \
                -- detect range, we assume that entire group \
                -- is, since they are bunched together\
                -- edge cases may get lucky tests\
                return false, nil \
            end\
        end        \
    end\
    return false, nil -- nothing visible\
end\
\
function cfxReconMode.placeMarkForUnit(location, theSide, theGroup) \
    local theID = cfxReconMode.uuid()\
    local theDesc = \"Contact: \"..theGroup:getName()\
    if cfxReconMode.reportNumbers then \
        theDesc = theDesc .. \" (\" .. theGroup:getSize() .. \" units)\"\
    end\
    trigger.action.markToCoalition(\
                    theID, \
                    theDesc, \
                    location, \
                    theSide, \
                    false, \
                    nil)\
    return theID\
end\
\
function cfxReconMode.removeMarkForArgs(args)\
    local theSide = args[1]\
    local theScout = args[2]\
    local theGroup = args[3]\
    local theID = args[4]\
    local theName = args[5]\
    \
--    if not theGroup then return end \
--    if not theGroup:isExist then return end \
    \
    trigger.action.removeMark(theID)\
    cfxReconMode.detectedGroups[theName] = nil \
    \
    -- invoke callbacks\
    cfxReconMode.invokeCallbacks(\"removed\", theSide, theScout, theGroup, theName)\
end \
\
\
function cfxReconMode.detectedGroup(mySide, theScout, theGroup, theLoc)\
    -- put a mark on the map \
    if cfxReconMode.applyMarks then \
        local theID = cfxReconMode.placeMarkForUnit(theLoc, mySide, theGroup)\
    \
        -- schedule removal if desired \
        if cfxReconMode.marksFadeAfter > 0 then \
            args = {mySide, theScout, theGroup, theID, theGroup:getName()}\
            timer.scheduleFunction(cfxReconMode.removeMarkForArgs, args, timer.getTime() + cfxReconMode.marksFadeAfter)\
        end\
    end \
    -- say something\
    if cfxReconMode.announcer then \
        trigger.action.outTextForCoalition(mySide, theScout:getName() .. \" reports new ground contact \" .. theGroup:getName(), 30)\
        -- play a sound \
        trigger.action.outSoundForCoalition(mySide, cfxReconMode.reconSound)\
    end \
    \
    -- see if it was a prio target \
    if cfxReconMode.isStringInList(theGroup:getName(), cfxReconMode.prioList) then \
        if cfxReconMode.announcer then \
            trigger.action.outTextForCoalition(mySide, \"Priority target confirmed\",    30)\
        end \
        -- invoke callbacks\
        cfxReconMode.invokeCallbacks(\"priotity\", mySide, theScout, theGroup, theGroup:getName())\
        \
        -- increase prio flag \
        if cfxReconMode.prioFlag then \
            local currVal = trigger.misc.getUserFlag(cfxReconMode.prioFlag)\
            trigger.action.setUserFlag(cfxReconMode.prioFlag, currVal + 1)\
        end\
    else \
        -- invoke callbacks\
        cfxReconMode.invokeCallbacks(\"detected\", mySide, theScout, theGroup, theGroup:getName())\
    \
        -- increase normal flag \
        if cfxReconMode.detectFlag then \
            local currVal = trigger.misc.getUserFlag(cfxReconMode.detectFlag)\
            trigger.action.setUserFlag(cfxReconMode.detectFlag, currVal + 1)\
        end\
    end\
end\
\
function cfxReconMode.performReconForUnit(theScout)\
    if not theScout then return end \
    if not theScout:isExist() then return end -- will be gc'd soon\
    -- get altitude above ground to calculate visual range \
    local alt = dcsCommon.getUnitAGL(theScout)\
    local visRange = dcsCommon.lerp(cfxReconMode.detectionMinRange, cfxReconMode.detectionMaxRange, alt/cfxReconMode.maxAlt)\
    local scoutPos = theScout:getPoint()\
    -- figure out which groups we are looking for\
    local myCoal = theScout:getCoalition()\
    local enemyCoal = 1 \
    if myCoal == 1 then enemyCoal = 2 end \
    \
    -- iterate all enemy units until we find one \
    -- and then stop this iteration (can only detect one \
    -- group per pass)\
    local enemyGroups = coalition.getGroups(enemyCoal)\
    for idx, theGroup in pairs (enemyGroups) do \
        -- make sure it's a ground unit \
        local isGround = theGroup:getCategory() == 2\
        if theGroup:isExist() and isGround then \
            local visible, location = cfxReconMode.canDetect(scoutPos, theGroup, visRange)\
            if visible then \
                -- see if we already detected this one \
                local groupName = theGroup:getName()\
                if cfxReconMode.detectedGroups[groupName] == nil then \
                    -- only now check against blackList\
                    if not cfxReconMode.isStringInList(groupName, cfxReconMode.blackList) then \
                        -- visible and not yet seen \
                        -- perhaps add some percent chance now \
                        -- remember that we know this group \
                        cfxReconMode.detectedGroups[groupName] = theGroup\
                        cfxReconMode.detectedGroup(myCoal, theScout, theGroup, location)\
                        return -- stop, as we only detect one group per pass\
                    end \
                end\
            end\
        end\
    end\
end\
\
\
\
function cfxReconMode.updateQueues()\
    -- schedule next call \
    timer.scheduleFunction(cfxReconMode.updateQueues, {}, timer.getTime() + 1/cfxReconMode.ups)\
    \
    -- we only process the first aircraft in \
    -- the scouts array, move it to processed and then shrink\
    -- scouts table until it's empty. When empty, transfer all \
    -- back and start cycle anew\
\
    local theFocusScoutName = nil \
    local procCount = 0 -- no iterations done yet\
    for name, scout in pairs(cfxReconMode.scouts) do \
        theFocusScoutName = name -- remember so we can delete\
        if not scout:isExist() then \
            -- we ignore the scout, and it's \
            -- forgotten since no longer transferred\
            -- i.e. built-in GC\
            if cfxReconMode.verbose then\
                trigger.action.outText(\"+++rcn: GC - removing scout \" .. name .. \" because it no longer exists\", 30)\
            end\
            -- invoke 'end' for this scout  \
            cfxReconMode.invokeCallbacks(\"dead\", -1, nil, nil, name)\
        else\
            -- scan for this scout\
            cfxReconMode.performReconForUnit(scout)\
            -- move it to processed table\
            cfxReconMode.processedScouts[name] = scout\
        end\
        procCount = 1 -- remember we went through one iteration\
        break -- always end after first iteration\
    end\
\
    -- remove processed scouts from scouts array\
    if procCount > 0 then \
        -- we processed one scout (even if scout itself did not exist)\
        -- remove that scout from active scouts table\
        cfxReconMode.scouts[theFocusScoutName] = nil\
    else \
        -- scouts is empty. copy processed table back to scouts\
        -- restart scouts array, contains GC already \
        cfxReconMode.scouts = cfxReconMode.processedScouts\
        cfxReconMode.processedScouts = {} -- start new empty processed queue\
    end \
end\
\
-- event handler \
function cfxReconMode:onEvent(event) \
    if not event then return end \
    if not event.initiator then return end \
    local theUnit = event.initiator \
    \
    -- we simply add scouts as they are garbage-collected \
    -- every so often when they do not exist \
    if event.id == 15 or -- birth\
       event.id == 3 -- take-off. should already have been taken \
                     -- care of by birth, but you never know \
    then\
        -- check if a side must not have scouts.\
        -- this will prevent player units to auto-\
        -- scout when they are on that side. in that case\
        -- you must add manually\
        local theSide = theUnit:getCoalition()\
        if theSide == 0 and not cfxReconMode.greyScouts then \
            return -- grey scouts are not allowed\
        end\
        if theSide == 1 and not cfxReconMode.redScouts then \
            return -- grey scouts are not allowed\
        end\
        if theSide == 2 and not cfxReconMode.blueScouts then \
            return -- grey scouts are not allowed\
        end\
        \
        if cfxReconMode.playerOnlyRecon then \
            if not theUnit:getPlayerName() then \
                return -- only players can do recon. this unit is AI\
            end\
        end\
        if cfxReconMode.verbose then \
            trigger.action.outText(\"+++rcn: event \" .. event.id .. \" for unit \" .. theUnit:getName(), 30)\
        end \
        cfxReconMode.addScout(theUnit)\
    end\
end\
\
--\
-- read all existing planes \
-- \
function cfxReconMode.processScoutGroups(theGroups)\
    for idx, aGroup in pairs(theGroups) do \
        -- process all planes in that group \
        -- we are very early in the mission, only few groups really \
        -- exist now, the rest of the units come in with 15 event\
        if aGroup:isExist() then \
            local allUnits = Group.getUnits(aGroup)\
            for idy, aUnit in pairs (allUnits) do \
                if aUnit:isExist() then \
                    cfxReconMode.addScout(aUnit)\
                    if cfxReconMode.verbose then\
                        trigger.action.outText(\"+++rcn: added unit \" ..aUnit:getName() .. \" to pool at startup\", 30)\
                    end \
                end\
            end\
        end\
    end\
end\
\
function cfxReconMode.initScouts()\
    -- get all groups of aircraft. Unrolled loop 0..2 \
    local theAirGroups = {}  \
    if cfxReconMode.greyScouts then\
        theAirGroups = coalition.getGroups(0, 0) -- 0 = aircraft\
        cfxReconMode.processScoutGroups(theAirGroups) \
    end\
    if cfxReconMode.redScouts then\
        theAirGroups = coalition.getGroups(1, 0) -- 1 = red, 0 = aircraft\
        cfxReconMode.processScoutGroups(theAirGroups) \
    end\
    \
    if cfxReconMode.blueScouts then\
        theAirGroups = coalition.getGroups(2, 0) -- 2 = blue, 0 = aircraft\
        cfxReconMode.processScoutGroups(theAirGroups) \
    end\
end\
\
--\
-- read config \
--\
function cfxReconMode.readConfigZone()\
    -- note: must match exactly!!!!\
    local theZone = cfxZones.getZoneByName(\"reconModeConfig\") \
    if not theZone then \
        if cfxReconMode.verbose then\
            trigger.action.outText(\"+++rcn: no config zone!\", 30) \
        end \
        return \
    end \
    if cfxReconMode.verbose then \
        trigger.action.outText(\"+++rcn: found config zone!\", 30) \
    end \
    \
    cfxReconMode.verbose = cfxZones.getBoolFromZoneProperty(theZone, \"verbose\", false)\
\
    cfxReconMode.autoRecon = cfxZones.getBoolFromZoneProperty(theZone, \"autoRecon\", true)\
    cfxReconMode.redScouts = cfxZones.getBoolFromZoneProperty(theZone, \"redScouts\", false)\
    cfxReconMode.blueScouts = cfxZones.getBoolFromZoneProperty(theZone, \"blueScouts\", true)    \
    cfxReconMode.greyScouts = cfxZones.getBoolFromZoneProperty(theZone, \"greyScouts\", false)\
    cfxReconMode.playerOnlyRecon = cfxZones.getBoolFromZoneProperty(theZone, \"playerOnlyRecon\", false)\
    cfxReconMode.reportNumbers = cfxZones.getBoolFromZoneProperty(theZone, \"reportNumbers\", true)\
        \
    cfxReconMode.detectionMinRange = cfxZones.getNumberFromZoneProperty(theZone, \"detectionMinRange\", 3000)\
    cfxReconMode.detectionMaxRange = cfxZones.getNumberFromZoneProperty(theZone, \"detectionMaxRange\", 12000)\
    cfxReconMode.maxAlt = cfxZones.getNumberFromZoneProperty(theZone, \"maxAlt\", 9000)\
    \
    if cfxZones.hasProperty(theZone, \"prio+\") then \
        cfxReconMode.prioFlag = cfxZones.getStringFromZoneProperty(theZone, \"prio+\", \"none\")\
    end\
    \
    if cfxZones.hasProperty(theZone, \"detect+\") then \
        cfxReconMode.detectFlag = cfxZones.getStringFromZoneProperty(theZone, \"detect+\", \"none\")\
    end\
    \
    \
    cfxReconMode.applyMarks = cfxZones.getBoolFromZoneProperty(theZone, \"applyMarks\", true)\
    cfxReconMode.announcer = cfxZones.getBoolFromZoneProperty(theZone, \"announcer\", true)\
    \
    if cfxZones.hasProperty(theZone, \"reconSound\") then \
        cfxReconMode.reconSound = cfxZones.getStringFromZoneProperty(theZone, \"reconSound\", \"<nosound>\")\
    end\
end\
\
--\
-- start \
--\
function cfxReconMode.start()\
    -- lib check \
    if not dcsCommon.libCheck(\"cfx Recon Mode\", \
        cfxReconMode.requiredLibs) then\
        return false \
    end\
    \
    -- read config \
    cfxReconMode.readConfigZone()\
    \
    -- gather exiting planes \
    cfxReconMode.initScouts()\
    \
    -- start update cycle\
    cfxReconMode.updateQueues()\
        \
    if cfxReconMode.autoRecon then \
        -- install own event handler to detect \
        -- when a unit takes off and add it to scout\
        -- roster \
        world.addEventHandler(cfxReconMode)\
    end\
    \
    trigger.action.outText(\"cfx Recon version \" .. cfxReconMode.version .. \" started.\", 30)\
    return true\
end\
\
--\
-- test callback \
--\
function cfxReconMode.demoReconCB(reason, theSide, theScout, theGroup, theName)\
    trigger.action.outText(\"recon CB: \" .. reason .. \" -- \" .. theScout:getName() .. \" spotted \" .. theName, 30)\
end\
\
if not cfxReconMode.start() then \
    cfxReconMode = nil\
end\
\
-- debug: wire up my own callback\
-- cfxReconMode.addCallback(cfxReconMode.demoReconCB)\
\
\
--[[--\
\
ideas:\
 \
- renew lease. when already sighted, simply renew lease, maybe update location.\
- update marks and renew lease \
TODO: red+ and blue+ - flags to increase when a plane of the other side is detected\
\
 \
--]]--\
\
\
 \
 ",
                    ["predicate"] = "a_do_script",
                }, -- end of [7]
                [8] = 
                {
                    ["seconds"] = 10,
                    ["start_delay"] = 0,
                    ["KeyDict_text"] = "DictKey_ActionText_11",
                    ["text"] = "DictKey_ActionText_11",
                    ["predicate"] = "a_out_text_delay",
                    ["clearview"] = true,
                }, -- end of [8]
            }, -- end of ["actions"]
            ["comment"] = "Extensions",
        }, -- end of [2]
        [3] = 
        {
            ["rules"] = 
            {
                [1] = 
                {
                    ["coalitionlist"] = "red",
                    ["unitType"] = "ALL",
                    ["zone"] = 84,
                    ["predicate"] = "c_time_after",
                    ["seconds"] = 999999,
                }, -- end of [1]
            }, -- end of ["rules"]
            ["eventlist"] = "",
            ["predicate"] = "triggerOnce",
            ["actions"] = 
            {
                [1] = 
                {
                    ["file"] = "ResKey_Action_6",
                    ["predicate"] = "a_out_sound",
                    ["start_delay"] = 0,
                }, -- end of [1]
                [2] = 
                {
                    ["file"] = "ResKey_Action_7",
                    ["predicate"] = "a_out_sound",
                    ["start_delay"] = 0,
                }, -- end of [2]
                [3] = 
                {
                    ["file"] = "ResKey_Action_8",
                    ["predicate"] = "a_out_sound",
                    ["start_delay"] = 0,
                }, -- end of [3]
                [4] = 
                {
                    ["file"] = "ResKey_Action_9",
                    ["predicate"] = "a_out_sound",
                    ["start_delay"] = 0,
                }, -- end of [4]
                [5] = 
                {
                    ["file"] = "ResKey_Action_10",
                    ["predicate"] = "a_out_sound",
                    ["start_delay"] = 0,
                }, -- end of [5]
                [6] = 
                {
                    ["file"] = "ResKey_Action_12",
                    ["predicate"] = "a_out_sound",
                    ["start_delay"] = 0,
                }, -- end of [6]
            }, -- end of ["actions"]
            ["comment"] = "Load Audio",
        }, -- end of [3]
    }, -- end of ["trigrules"]
    ["currentKey"] = 46232,
    ["start_time"] = 28800,
    ["forcedOptions"] = 
    {
        ["padlock"] = false,
        ["easyRadar"] = false,
        ["miniHUD"] = false,
        ["accidental_failures"] = false,
        ["optionsView"] = "optview_allies",
        ["permitCrash"] = true,
        ["immortal"] = false,
        ["easyCommunication"] = true,
        ["cockpitVisualRM"] = false,
        ["easyFlight"] = false,
        ["radio"] = false,
        ["geffect"] = "realistic",
        ["birds"] = 0,
        ["wakeTurbulence"] = false,
        ["unrestrictedSATNAV"] = false,
        ["userMarks"] = true,
        ["RBDAI"] = true,
        ["externalViews"] = true,
        ["fuel"] = false,
        ["civTraffic"] = "",
        ["weapons"] = false,
        ["cockpitStatusBarAllowed"] = false,
        ["labels"] = 3,
    }, -- end of ["forcedOptions"]
    ["failures"] = 
    {
        ["ELEVONINNERRIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONINNERRIGHT",
            ["mm"] = 0,
        }, -- end of ["ELEVONINNERRIGHT"]
        ["BATTERY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BATTERY",
            ["mm"] = 0,
        }, -- end of ["BATTERY"]
        ["AUTOPILOT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AUTOPILOT",
            ["mm"] = 0,
        }, -- end of ["AUTOPILOT"]
        ["RADARASS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RADARASS",
            ["mm"] = 0,
        }, -- end of ["RADARASS"]
        ["FUELTANK5L"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK5L",
            ["mm"] = 0,
        }, -- end of ["FUELTANK5L"]
        ["FR22RADIO"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FR22RADIO",
            ["mm"] = 0,
        }, -- end of ["FR22RADIO"]
        ["HUDDISPLAY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HUDDISPLAY",
            ["mm"] = 0,
        }, -- end of ["HUDDISPLAY"]
        ["CANARDSERVOLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CANARDSERVOLEFT",
            ["mm"] = 0,
        }, -- end of ["CANARDSERVOLEFT"]
        ["AIRBRAKE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AIRBRAKE",
            ["mm"] = 0,
        }, -- end of ["AIRBRAKE"]
        ["ADI_UNIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ADI_UNIT",
            ["mm"] = 0,
        }, -- end of ["ADI_UNIT"]
        ["MAINPITOT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MAINPITOT",
            ["mm"] = 0,
        }, -- end of ["MAINPITOT"]
        ["TILS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TILS",
            ["mm"] = 0,
        }, -- end of ["TILS"]
        ["JAMMER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "JAMMER",
            ["mm"] = 0,
        }, -- end of ["JAMMER"]
        ["COMPRESSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "COMPRESSOR",
            ["mm"] = 0,
        }, -- end of ["COMPRESSOR"]
        ["FR24RADIO"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FR24RADIO",
            ["mm"] = 0,
        }, -- end of ["FR24RADIO"]
        ["RWRANTLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWRANTLEFT",
            ["mm"] = 0,
        }, -- end of ["RWRANTLEFT"]
        ["ELEVONSERVOUTERRIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONSERVOUTERRIGHT",
            ["mm"] = 0,
        }, -- end of ["ELEVONSERVOUTERRIGHT"]
        ["RPMSENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RPMSENSOR",
            ["mm"] = 0,
        }, -- end of ["RPMSENSOR"]
        ["OXYGEN"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "OXYGEN",
            ["mm"] = 0,
        }, -- end of ["OXYGEN"]
        ["EPRSENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EPRSENSOR",
            ["mm"] = 0,
        }, -- end of ["EPRSENSOR"]
        ["BACKUPGENERATOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BACKUPGENERATOR",
            ["mm"] = 0,
        }, -- end of ["BACKUPGENERATOR"]
        ["AIRBRAKESERVO"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AIRBRAKESERVO",
            ["mm"] = 0,
        }, -- end of ["AIRBRAKESERVO"]
        ["CANARDFLAPLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CANARDFLAPLEFT",
            ["mm"] = 0,
        }, -- end of ["CANARDFLAPLEFT"]
        ["RWRUNIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWRUNIT",
            ["mm"] = 0,
        }, -- end of ["RWRUNIT"]
        ["DATACARTRIDGE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DATACARTRIDGE",
            ["mm"] = 0,
        }, -- end of ["DATACARTRIDGE"]
        ["CMDISP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CMDISP",
            ["mm"] = 0,
        }, -- end of ["CMDISP"]
        ["ACCSENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ACCSENSOR",
            ["mm"] = 0,
        }, -- end of ["ACCSENSOR"]
        ["MAINPOWER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MAINPOWER",
            ["mm"] = 0,
        }, -- end of ["MAINPOWER"]
        ["FUELTANK4R"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK4R",
            ["mm"] = 0,
        }, -- end of ["FUELTANK4R"]
        ["HAW"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HAW",
            ["mm"] = 0,
        }, -- end of ["HAW"]
        ["ELEVONSERVOUTERLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONSERVOUTERLEFT",
            ["mm"] = 0,
        }, -- end of ["ELEVONSERVOUTERLEFT"]
        ["FUELTANK3R"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK3R",
            ["mm"] = 0,
        }, -- end of ["FUELTANK3R"]
        ["HYDRRESERVPUMP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDRRESERVPUMP",
            ["mm"] = 0,
        }, -- end of ["HYDRRESERVPUMP"]
        ["FUELTANK4L"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK4L",
            ["mm"] = 0,
        }, -- end of ["FUELTANK4L"]
        ["HYDR1PUMP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR1PUMP",
            ["mm"] = 0,
        }, -- end of ["HYDR1PUMP"]
        ["ELEVONOUTERLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONOUTERLEFT",
            ["mm"] = 0,
        }, -- end of ["ELEVONOUTERLEFT"]
        ["RUDDER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RUDDER",
            ["mm"] = 0,
        }, -- end of ["RUDDER"]
        ["IFF"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "IFF",
            ["mm"] = 0,
        }, -- end of ["IFF"]
        ["FDU"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FDU",
            ["mm"] = 0,
        }, -- end of ["FDU"]
        ["TEMPSENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TEMPSENSOR",
            ["mm"] = 0,
        }, -- end of ["TEMPSENSOR"]
        ["FUELTANK2"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK2",
            ["mm"] = 0,
        }, -- end of ["FUELTANK2"]
        ["RWRANTRIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWRANTRIGHT",
            ["mm"] = 0,
        }, -- end of ["RWRANTRIGHT"]
        ["RUDDERSERV"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RUDDERSERV",
            ["mm"] = 0,
        }, -- end of ["RUDDERSERV"]
        ["ELEVONINNERLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONINNERLEFT",
            ["mm"] = 0,
        }, -- end of ["ELEVONINNERLEFT"]
        ["HYDR2PUMP"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR2PUMP",
            ["mm"] = 0,
        }, -- end of ["HYDR2PUMP"]
        ["TURBINE"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TURBINE",
            ["mm"] = 0,
        }, -- end of ["TURBINE"]
        ["RADARALTANT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RADARALTANT",
            ["mm"] = 0,
        }, -- end of ["RADARALTANT"]
        ["FUELTANK3L"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK3L",
            ["mm"] = 0,
        }, -- end of ["FUELTANK3L"]
        ["FR24ANTENNA"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FR24ANTENNA",
            ["mm"] = 0,
        }, -- end of ["FR24ANTENNA"]
        ["GTS"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "GTS",
            ["mm"] = 0,
        }, -- end of ["GTS"]
        ["BCKGYRO"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BCKGYRO",
            ["mm"] = 0,
        }, -- end of ["BCKGYRO"]
        ["RWRANTREAR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RWRANTREAR",
            ["mm"] = 0,
        }, -- end of ["RWRANTREAR"]
        ["CANARDSERVORIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CANARDSERVORIGHT",
            ["mm"] = 0,
        }, -- end of ["CANARDSERVORIGHT"]
        ["CANARDFLAPRIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CANARDFLAPRIGHT",
            ["mm"] = 0,
        }, -- end of ["CANARDFLAPRIGHT"]
        ["BCKPITOT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BCKPITOT",
            ["mm"] = 0,
        }, -- end of ["BCKPITOT"]
        ["TAPEREC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TAPEREC",
            ["mm"] = 0,
        }, -- end of ["TAPEREC"]
        ["FUELTANK1"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK1",
            ["mm"] = 0,
        }, -- end of ["FUELTANK1"]
        ["AOASENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AOASENSOR",
            ["mm"] = 0,
        }, -- end of ["AOASENSOR"]
        ["ELEVONOUTERRIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONOUTERRIGHT",
            ["mm"] = 0,
        }, -- end of ["ELEVONOUTERRIGHT"]
        ["AFK"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "AFK",
            ["mm"] = 0,
        }, -- end of ["AFK"]
        ["HYDR2ACC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR2ACC",
            ["mm"] = 0,
        }, -- end of ["HYDR2ACC"]
        ["MAINGENERATOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "MAINGENERATOR",
            ["mm"] = 0,
        }, -- end of ["MAINGENERATOR"]
        ["DOPPLER_UNIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "DOPPLER_UNIT",
            ["mm"] = 0,
        }, -- end of ["DOPPLER_UNIT"]
        ["FR22ANTENNA"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FR22ANTENNA",
            ["mm"] = 0,
        }, -- end of ["FR22ANTENNA"]
        ["ELEVONSERVINNERLEFT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONSERVINNERLEFT",
            ["mm"] = 0,
        }, -- end of ["ELEVONSERVINNERLEFT"]
        ["RADARALTUNIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RADARALTUNIT",
            ["mm"] = 0,
        }, -- end of ["RADARALTUNIT"]
        ["REVERSER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "REVERSER",
            ["mm"] = 0,
        }, -- end of ["REVERSER"]
        ["TVDISPLAY"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "TVDISPLAY",
            ["mm"] = 0,
        }, -- end of ["TVDISPLAY"]
        ["EGTSENSOR"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "EGTSENSOR",
            ["mm"] = 0,
        }, -- end of ["EGTSENSOR"]
        ["FUELTANK5R"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "FUELTANK5R",
            ["mm"] = 0,
        }, -- end of ["FUELTANK5R"]
        ["ELEVONSERVINNERRIGHT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "ELEVONSERVINNERRIGHT",
            ["mm"] = 0,
        }, -- end of ["ELEVONSERVINNERRIGHT"]
        ["RADARDISPL"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RADARDISPL",
            ["mm"] = 0,
        }, -- end of ["RADARDISPL"]
        ["BURNER"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "BURNER",
            ["mm"] = 0,
        }, -- end of ["BURNER"]
        ["CK_UNIT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "CK_UNIT",
            ["mm"] = 0,
        }, -- end of ["CK_UNIT"]
        ["HYDR1ACC"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "HYDR1ACC",
            ["mm"] = 0,
        }, -- end of ["HYDR1ACC"]
        ["RB05ANT"] = 
        {
            ["hh"] = 0,
            ["prob"] = 100,
            ["enable"] = false,
            ["mmint"] = 1,
            ["id"] = "RB05ANT",
            ["mm"] = 0,
        }, -- end of ["RB05ANT"]
    }, -- end of ["failures"]
} -- end of mission
