summaryrefslogtreecommitdiff
path: root/ADSBDecoder
diff options
context:
space:
mode:
Diffstat (limited to 'ADSBDecoder')
-rw-r--r--ADSBDecoder/ADSBRegEx.swift87
-rw-r--r--ADSBDecoder/Configs.swift10
-rw-r--r--ADSBDecoder/Decoder.swift249
-rw-r--r--ADSBDecoder/PositionDecoder.swift221
-rw-r--r--ADSBDecoder/Query.swift126
-rw-r--r--ADSBDecoder/Utils.swift23
-rw-r--r--ADSBDecoder/main.swift1
7 files changed, 0 insertions, 717 deletions
diff --git a/ADSBDecoder/ADSBRegEx.swift b/ADSBDecoder/ADSBRegEx.swift
deleted file mode 100644
index 2841467..0000000
--- a/ADSBDecoder/ADSBRegEx.swift
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// ADSBRegEx.swift
-// ADSBDecoder
-//
-// Created by Jacky Jack on 30/06/2024.
-//
-
-import Foundation
-import RegexBuilder
-/*
-let matchADSBLong = Regex {
- Anchor.startOfLine
- "*"
-
- Repeat(
- CharacterClass(
- ("a"..."f"),
- ("0"..."9")
- )
- ,count:28)
-
- ";"
-}*/
-class MatchADSBLong {
- let matchADSBLong = Regex {
- Anchor.startOfLine
- "*"
-
- Repeat(
- CharacterClass(
- ("a"..."f"),
- ("0"..."9")
- )
- ,count:28)
-
- ";"
- }
-
- func prefixMatch(_ line: String) -> Regex<Regex<Substring>.RegexOutput>.Match? {
- do {
- if let match = try matchADSBLong.prefixMatch(in: line) {
- return match
- }
- } catch {
- return nil
- }
- return nil
- }
-}
-
-/*
-let matchADSBShort = Regex {
- Anchor.startOfLine
- "*"
- Repeat(
- CharacterClass(
- ("a"..."f"),
- ("0"..."9")
- )
- ,count:14)
- ";"
-}*/
-
-class MatchADSBShort {
- let matchADSBShort = Regex {
- Anchor.startOfLine
- "*"
- Repeat(
- CharacterClass(
- ("a"..."f"),
- ("0"..."9")
- )
- ,count:14)
- ";"
- }
-
- func prefixMatch(_ line: String) -> Regex<Regex<Substring>.RegexOutput>.Match? {
- do {
- if let match = try matchADSBShort.prefixMatch(in: line) {
- return match
- }
- } catch {
- return nil
- }
- return nil
- }
-}
diff --git a/ADSBDecoder/Configs.swift b/ADSBDecoder/Configs.swift
deleted file mode 100644
index a42e745..0000000
--- a/ADSBDecoder/Configs.swift
+++ /dev/null
@@ -1,10 +0,0 @@
-//
-// Configs.swift
-// ADSBDecoder
-//
-// Created by Jacky Jack on 09/07/2024.
-//
-
-import Foundation
-
-let decoder_debug_mode = false
diff --git a/ADSBDecoder/Decoder.swift b/ADSBDecoder/Decoder.swift
deleted file mode 100644
index a9724b6..0000000
--- a/ADSBDecoder/Decoder.swift
+++ /dev/null
@@ -1,249 +0,0 @@
-//
-// Decoder.swift
-// ADSBDecoder
-//
-// Created by Jacky Jack on 28/05/2024.
-//
-
-import Foundation
-
-func BarometricAltitudeFeat(_ altitude: UInt16) -> Int {
- let QBit = (altitude>>4)&0x1
- if QBit == 1 {
- //remove qbit
- let part1:UInt16 = altitude&0xf
- let part2:UInt16 = (altitude>>1)&0x7ff0
- let altitude25 = part1 + part2
- //print("altitude2 \(altitude25) ")
- return Int(altitude25)*25-1000
- }
- return Int(altitude)*100-1000
-}
-
-class Decoder {
- var adsb_data: String = ""
- var DataFormat: UInt32 = 0;
-
- init (_ adsb_data: String) {
- //print(adsb_data)
- self.adsb_data = adsb_data
- //get the first 8 bits as integer
- let startI = adsb_data.startIndex
- let endI = adsb_data.index(startI, offsetBy: 1)
- let firstByteString = adsb_data[startI...endI]
- //print("\(firstByteString)")
- if let ControlMsg = UInt32(firstByteString, radix: 16) {
- //print("ControlMsg = \(ControlMsg)")
- let CM_DataFormat = (ControlMsg&0xF8)>>3
- DataFormat = CM_DataFormat
- //let CM_TranspoderCapability = ControlMsg&(0x7)
- }
- //print("Data Format \(DataFormat)")
- }
-
- func getDataFormat17() -> DataFormat17? {
-
- if (DataFormat != 17) {
- return nil
- }
- //let startI = adsb_data.index(adsb_data.startIndex, offsetBy: 1)
- //let endI = adsb_data.index(adsb_data.endIndex, offsetBy: -1)
- //let adsbData = adsb_data[startI...endI]
- let ret:DataFormat17 = DataFormat17(adsb_data)
-
-
-
- return ret;
- }
-
- func getDataFormat18() {
- print("Not implemented")
- }
-
-}
-
-func ICAOAlphabet(_ code: UInt8) -> String {
- if ((code>=1) && (code<=26)) {
- return String(UnicodeScalar(code+64))
- } else if ((code >= 48)&&(code<=57)) {
- return String(UnicodeScalar(code))
- } else if (code==32) {
- return " "
- }
- return "#"
-}
-
-func ICAO2String(_ b1: UInt8, _ b2: UInt8, _ b3: UInt8, _ b4: UInt8, _ b5: UInt8, _ b6: UInt8, _ b7: UInt8, _ b8: UInt8) -> String {
- return ICAOAlphabet(b1)+ICAOAlphabet(b2)+ICAOAlphabet(b3)+ICAOAlphabet(b4)+ICAOAlphabet(b5)+ICAOAlphabet(b6)+ICAOAlphabet(b7)+ICAOAlphabet(b8)
-}
-
-class DataFormat17 {
-
- let DataFormat=17 //0:5
- var Capability=0 //5:7
- var AddressAnnounced=0 //8:31
- var TypeCode=0 //32:36
- var MovementField=0//37:43
- var HeadingBit=0//44
- var HeadingField=0//45:51
- //var CPROddEven=0//53
- //var CPRlat=0//54:70
- //var CPRlon=0//71:87
- var ParityIntegrity=0//88-111
-
- //all avaliable message types
- var messageIdentification:ADSBTypeCodeIndentification? = nil
- var messageAirbornPositon:ADSBTypeCodeAirbonePositon? = nil
-
- init(_ adsb_data: String) {
- //print("Dataformat: 17!")
- //print(adsb_data)
-
- var bindata:[UInt8] = []
-
- var startN = adsb_data.startIndex
- var endN = adsb_data.index(startN, offsetBy: 1)
- var count=0//start index value
- while (count<adsb_data.count) {
- let u8 = UInt8(adsb_data[startN...endN], radix: 16)!
- //print(adsb_data[startN...endN])
- bindata.append(u8)
- count += 2
- if (count<adsb_data.count) {
- startN = adsb_data.index(startN, offsetBy: 2)
- endN = adsb_data.index(startN, offsetBy: 1)
- }
- }
- //print(bindata)
-
- //Decode Capability
- let cap = (bindata[0]>>1)&0x7
- //print(String(format: "cap %02x", cap))
- Capability = Int(cap)
-
- //Decode Address Announcement
- let address_ann = UInt32(bindata[1])<<16 + UInt32(bindata[2])<<8 + UInt32(bindata[3])
- //print(String(format: "address %06x", address_ann))
-
- AddressAnnounced = Int(address_ann)
-
- //Decode Type Code
- let tc_byte = bindata[4] >> 3
- //print(String(format: "tc %02d", tc_byte))
-
- TypeCode = Int(tc_byte)
-
- //aircraft indentification and category
- if (tc_byte == 4) {
- let msg = ADSBTypeCodeIndentification(bindata[4...10])
- if decoder_debug_mode {
- print("=====ADSB MESSSGE 04 =======")
- print(msg)
- print("============================")
- }
-
- messageIdentification = msg
- //airborn position
- } else if ((tc_byte >= 8) && (tc_byte <= 18)) {
- let msg = ADSBTypeCodeAirbonePositon(bindata[4...10])
- if decoder_debug_mode {
- print(String(format:"=====ADSB MESSSGE %02d ======= AA:%04d", tc_byte, AddressAnnounced))
- print(msg)
- print("============================")
- }
-
- messageAirbornPositon = msg
- //airborn velocity
- } else if (tc_byte == 19) {
- if decoder_debug_mode {
- print("=====ADSB MESSSGE 19 =======")
- print("=====VELOCITY =======")
- }
- } else {
- if decoder_debug_mode {
- print("=====ADSB MESSSGE UNKNOWN =======")
- }
- }
- }
-}
-
-class ADSBTypeCodeIndentification: CustomStringConvertible {
- var TypeCode:Int = 4
- var Category:Int = 0
- var ICAOName:String
-
- init(_ bindata:ArraySlice<UInt8>) {
- let cat = bindata[4]&0x7
- Category = Int(cat)
- let char_0 = bindata[5]>>2
- let char_1 = (bindata[5]&0x3)<<4 + bindata[6]>>4
- let char_2 = (bindata[6]&0xf)<<2 + (bindata[7]>>6)&0x3
- let char_3 = (bindata[7])&0x3f
- let char_4 = bindata[8]>>2
- let char_5 = (bindata[8]&0x3)<<4 + bindata[9]>>4
- let char_6 = (bindata[9]&0xf)<<2 + (bindata[10]>>6)
- let char_7 = bindata[10]&0x3f
-
- //print(char_0, char_1, char_2,char_3,char_4,char_5,char_6,char_7)
- ICAOName = ICAO2String(char_0, char_1, char_2, char_3, char_4, char_5, char_6, char_7)
- //print("ICAO name \(ICAOName)")
- }
-
- var description: String {
- let description = "TypeCode \(TypeCode) Cat \(Category) Flight name \(ICAOName)"
- return description
- }
-}
-
-//DF17 message types codes 8 to 18
-class ADSBTypeCodeAirbonePositon:CustomStringConvertible {
- var TypeCode:Int = 11
- var SurveillanceStatus: Int = 0
- var SingleAntennaFlag: Int = 0
- var Altitude: Int = 0
- var Time: Int = 0
- var CPRFormat: Int = 0
- var Latitude: Int = 0
- var Longitude: Int = 0
-
- init(_ bindata:ArraySlice<UInt8>) {
- let ss = (bindata[4]>>1)&(0x3)
- SurveillanceStatus = Int(ss)
- let saf = bindata[5]&0x1
- SingleAntennaFlag = Int(saf)
- let altitude = UInt16(bindata[5])<<4 + (UInt16(bindata[6])>>4)&0xf
- //print(altitude)
- Altitude = BarometricAltitudeFeat(altitude)
- let time = (bindata[6]>>3)&0x1
- Time = Int(time)
- let cpr = (bindata[6]>>2)&0x1
- CPRFormat = Int(cpr)
- let lat:UInt32 = UInt32(bindata[6]&0x3)<<15 + UInt32(bindata[7])<<7 + UInt32(bindata[8]>>1)
- Latitude = Int(lat)
- let lon:UInt32 = UInt32(bindata[8]&0x1)<<16 + UInt32(bindata[9])<<8 + UInt32(bindata[10])
- Longitude = Int(lon)
- }
-
- var description: String {
- var description = "SS \(SurveillanceStatus) SAF \(SingleAntennaFlag) Altitude \(Altitude)ft \n"
- description += "Time \(Time) CPR \(CPRFormat)"
- if (CPRFormat == 0) {
- description += "even"
- } else {
- description += "odd"
- }
- description += "\n"
- description += "Lat \(Latitude) Long \(Longitude)"
- return description
- }
-}
-
-class DataFormat19:CustomStringConvertible {
- init(_ bindata:ArraySlice<UInt8>) {
- print("Dataformat: 19")
- }
-
- var description: String {
- return ""
- }
-}
diff --git a/ADSBDecoder/PositionDecoder.swift b/ADSBDecoder/PositionDecoder.swift
deleted file mode 100644
index 85b9d49..0000000
--- a/ADSBDecoder/PositionDecoder.swift
+++ /dev/null
@@ -1,221 +0,0 @@
-//
-// PositionDecoder.swift
-// ADSBDecoder
-//
-// Created by Jacky Jack on 14/06/2024.
-//
-
-import Foundation
-import Collections
-
-struct PositionData {
- var cpr_lat: UInt32
- var cpr_long: UInt32
- var even: Bool
- var cprtime: Int64
-}
-
-func cpr_mod(_ a: Int, _ b: Int) -> Int {
- var res:Int = a % b;
- if (res < 0) {
- res += b
- }
- return res;
-}
-
-/* The NL function uses the precomputed table from 1090-WP-9-14 */
-func cpr_NLFunction(_ _lat: Double) -> Int {
- var lat:Double = _lat
- if (lat < 0) {
- lat = -lat
- } /* Table is simmetric about the equator. */
- if (lat < 10.47047130) {return 59}
- if (lat < 14.82817437) {return 58}
- if (lat < 18.18626357) {return 57}
- if (lat < 21.02939493) {return 56}
- if (lat < 23.54504487) {return 55}
- if (lat < 25.82924707) {return 54}
- if (lat < 27.93898710) {return 53}
- if (lat < 29.91135686) {return 52}
- if (lat < 31.77209708) {return 51}
- if (lat < 33.53993436) {return 50}
- if (lat < 35.22899598) {return 49}
- if (lat < 36.85025108) {return 48}
- if (lat < 38.41241892) {return 47}
- if (lat < 39.92256684) {return 46}
- if (lat < 41.38651832) {return 45}
- if (lat < 42.80914012) {return 44}
- if (lat < 44.19454951) {return 43}
- if (lat < 45.54626723) {return 42}
- if (lat < 46.86733252) {return 41}
- if (lat < 48.16039128) {return 40}
- if (lat < 49.42776439) {return 39}
- if (lat < 50.67150166) {return 38}
- if (lat < 51.89342469) {return 37}
- if (lat < 53.09516153) {return 36}
- if (lat < 54.27817472) {return 35}
- if (lat < 55.44378444) {return 34}
- if (lat < 56.59318756) {return 33}
- if (lat < 57.72747354) {return 32}
- if (lat < 58.84763776) {return 31}
- if (lat < 59.95459277) {return 30}
- if (lat < 61.04917774) {return 29}
- if (lat < 62.13216659) {return 28}
- if (lat < 63.20427479) {return 27}
- if (lat < 64.26616523) {return 26}
- if (lat < 65.31845310) {return 25}
- if (lat < 66.36171008) {return 24}
- if (lat < 67.39646774) {return 23}
- if (lat < 68.42322022) {return 22}
- if (lat < 69.44242631) {return 21}
- if (lat < 70.45451075) {return 20}
- if (lat < 71.45986473) {return 19}
- if (lat < 72.45884545) {return 18}
- if (lat < 73.45177442) {return 17}
- if (lat < 74.43893416) {return 16}
- if (lat < 75.42056257) {return 15}
- if (lat < 76.39684391) {return 14}
- if (lat < 77.36789461) {return 13}
- if (lat < 78.33374083) {return 12}
- if (lat < 79.29428225) {return 11}
- if (lat < 80.24923213) {return 10}
- if (lat < 81.19801349) {return 9}
- if (lat < 82.13956981) {return 8}
- if (lat < 83.07199445) {return 7}
- if (lat < 83.99173563) {return 6}
- if (lat < 84.89166191) {return 5}
- if (lat < 85.75541621) {return 4}
- if (lat < 86.53536998) {return 3}
- if (lat < 87.00000000) {return 2}
- else {return 1}
-}
-
-func cpr_NFunction(_ lat: Double, _ isodd: Int) -> Int {
- var nl:Int = cpr_NLFunction(lat) - isodd;
- if (nl < 1) {
- nl = 1
- }
- return nl;
-}
-
-func cpr_DlonFunction(_ lat: Double, _ isodd: Int) -> Double {
- return 360.0 / Double(cpr_NFunction(lat, isodd));
-}
-
-func mstime() -> Int64 {
- var tv:timeval = timeval(tv_sec: 0, tv_usec: 0)
- var mst:Int64=0;
-
- gettimeofday(&tv, nil);
- mst = Int64(tv.tv_sec)*1000;
- mst += Int64(tv.tv_usec)/1000;
- return mst;
-}
-
-class PositionDecoder {
-
- var long: Double = 0.0
- var lat: Double = 0.0
- var ready: Bool = false
- var newposition: Bool = false
-
- //initialise first values so this values is nonsence
- var queue: Deque<PositionData> = []
-
- init() {
-
- }
-
- func addEvenPosition(_ cpr_lat: UInt32,_ cpr_long: UInt32, _ cprtime: Int64) {
- queue.append(PositionData(cpr_lat:cpr_lat, cpr_long:cpr_long, even:true, cprtime: cprtime))
- }
-
- func addOddPosition(_ cpr_lat: UInt32,_ cpr_long: UInt32, _ cprtime: Int64) {
- queue.append(PositionData(cpr_lat:cpr_lat,cpr_long:cpr_long,even:false, cprtime: cprtime))
- }
-
- func getPosition() -> (Double, Double)? {
- if (ready) {
- return (lat, long)
- }
- return nil
- }
-
- //TODO: allways adds to queue newer frees the queue
- func calcPosition() -> Bool {
- if (queue.count > 2) {
- let el1 = queue[queue.count-1]
- let el2 = queue[queue.count-2]
- if (el1.even == el2.even) {
- //ready = false
- return false
- }
- } else {
- ready = false
- print("Position queue to short to calculate values")
- return false
- }
-
- //last to elements are evan and odd
- let el1 = queue[queue.count-1]
- let el2 = queue[queue.count-2]
- let cpr_even = el1.even ? el1 : el2
- let cpr_odd = (!el1.even) ? el1 : el2
-
- //print("Position queue is ready to calculate location \(cpr_even) \(cpr_odd)")
- // from here https://github.com/antirez/dump1090/blob/master/dump1090.c#L1718
- let AirDlat0:Double = 360.0/60.0
- let AirDlat1:Double = 360.0/59.0
-
- let lat0 = Int(cpr_even.cpr_lat)
- let lat1 = Int(cpr_odd.cpr_lat)
- let lon0 = Int(cpr_even.cpr_long)
- let lon1 = Int(cpr_odd.cpr_long)
-
- //latitude index
- let j:Int = Int(floor(((59.0*Double(lat0) - 60.0*Double(lat1)) / 131072.0) + 0.5))
-
- var rlat0:Double = AirDlat0 * (Double(cpr_mod(j,60)) + Double(lat0) / 131072.0)
- var rlat1:Double = AirDlat1 * (Double(cpr_mod(j,59)) + Double(lat1) / 131072.0)
-
- if (rlat0 >= 270.0) {
- rlat0 -= 360.0
- }
- if (rlat1 >= 270.0) {
- rlat1 -= 360.0
- }
-
- /* Check that both are in the same latitude zone, or abort. */
- if (cpr_NLFunction(rlat0) != cpr_NLFunction(rlat1)) {
- print("Not same lat?!")
- return false
- }
-
- /* Compute ni and the longitude index m */
- if (cpr_even.cprtime > cpr_odd.cprtime) {
- /* Use even packet. */
- let ni:Int = cpr_NFunction(rlat0,0);
- let m:Int = Int(
- floor((((Double(lon0) * (Double(cpr_NLFunction(rlat0))-1.0)) -
- (Double(lon1) * Double(cpr_NLFunction(rlat0)))) / 131072.0) + 0.5)
- );
- self.long = Double(cpr_DlonFunction(rlat0,0)) * (Double(cpr_mod(m,ni))+Double(lon0)/131072.0);
- self.lat = rlat0;
- } else {
- /* Use odd packet. */
- let ni:Int = cpr_NFunction(rlat1,1);
- let m:Int = Int(floor((((Double(lon0) * (Double(cpr_NLFunction(rlat1))-1.0)) -
- (Double(lon1) * Double(cpr_NLFunction(rlat1)))) / 131072.0) + 0.5));
- self.long = cpr_DlonFunction(rlat1,1) * (Double(cpr_mod(m,ni))+Double(lon1)/131072.0);
- self.lat = rlat1;
- }
- if (self.long > 180) {
- self.long -= 360
- }
-
- ready = true
- return true
- }
-
-
-}
diff --git a/ADSBDecoder/Query.swift b/ADSBDecoder/Query.swift
deleted file mode 100644
index a92d919..0000000
--- a/ADSBDecoder/Query.swift
+++ /dev/null
@@ -1,126 +0,0 @@
-//
-// Query.swift
-// ADSBDecoder
-//
-// Created by Jacky Jack on 31/05/2024.
-//
-
-import Foundation
-
-class QueryDF: CustomStringConvertible {
-
- //max I see is 24
- var DFlist:[Int] = Array(repeating: 0, count: 30)
-
- init() {
-
- }
-
- func addDF(_ dataformat: UInt32) {
- DFlist[Int(dataformat)] += 1
- }
-
- func showStat() {
- print("DataFormat Count")
- for i in 0...(DFlist.count)-1 {
- if DFlist[i] != 0 {
- print(String(format:" %02d: %05d", i, DFlist[i]))
- }
- }
- }
-
- var description: String {
- var description = "DataFormat Count\n"
- for i in 0...(DFlist.count)-1 {
- if DFlist[i] != 0 {
- description += String(format:" %02d: %04d\n", i, DFlist[i])
- }
- }
- return description
- }
-}
-
-class QueryDF17TC: CustomStringConvertible {
- var TClist:[Int] = Array(repeating: 0, count: 32)
-
- init() {
-
- }
-
- func addTC(_ typecode: Int) {
- TClist[typecode] += 1
- }
-
- var description: String {
- var description = "DF17 TypeCode Count\n"
- for i in 0...(TClist.count-1) {
- if TClist[i] != 0 {
- description += String(format: " %02d: %04d\n", i, TClist[i])
- }
- }
- return description
- }
-}
-
-class QueryDecodedMessages: CustomStringConvertible {
-
- var decoded:Int = 0
- var total:Int = 0
-
- init() {
-
- }
-
- func addDecoded() {
- decoded += 1
- total += 1
- }
-
- func addUndecoded() {
- total = total + 1
- }
-
- var description: String {
- var description = "Total messages:\n"
- description += "Decoded:\(decoded)\n"
- description += "Total :\(total) \(String(format:"%02.01f",Float(Float(decoded)/Float(total)*100.0)))%\n"
- return description
- }
-
-}
-
-
-class QueryDF17TC_decoded: CustomStringConvertible {
- var TClist_decoded:[Int] = Array(repeating: 0, count: 32)
- var TClist_total:[Int] = Array(repeating: 0, count: 32)
-
- init() {
-
- }
-
- func addDecoded(_ typecode: Int) {
- TClist_decoded[typecode] += 1
- TClist_total[typecode] += 1
- }
-
- func addUndecode(_ typecode: Int) {
- TClist_total[typecode] += 1
- }
-
- var description: String {
- var description = ""
- var decoded:Int = 0
- var total:Int = 0
- for i in 0...(TClist_decoded.count-1) {
- total += TClist_total[i]
- decoded += TClist_decoded[i]
- if TClist_total[i] != 0 {
- description += String(format: " %02d: %04d\n", i, TClist_decoded[i])
- }
- }
- description += String(format:"Total %d/%d %.1f",decoded,total,Double(Double(decoded)/Double(total))*100)
- description += "%\n"
- return description
- }
-}
-
diff --git a/ADSBDecoder/Utils.swift b/ADSBDecoder/Utils.swift
deleted file mode 100644
index 7a7f177..0000000
--- a/ADSBDecoder/Utils.swift
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Utils.swift
-// ADSBDecoder
-//
-// Created by Jacky Jack on 30/06/2024.
-//
-
-import Foundation
-
-//return true if file excists
-func checkIfFileExists(_ fname: String) -> Bool {
- let fm = FileManager.default
- if fm.fileExists(atPath: fname) {
- return true
- }
- return false
-}
-
-//get current run directory
-func getCurrentDirPath() -> String {
- return Process().currentDirectoryPath
-}
-
diff --git a/ADSBDecoder/main.swift b/ADSBDecoder/main.swift
index 91ba97b..ace377f 100644
--- a/ADSBDecoder/main.swift
+++ b/ADSBDecoder/main.swift
@@ -11,7 +11,6 @@ import RegexBuilder
import SQLite3
-
struct CommandLineArgs: ParsableCommand {
@Option(name: .shortAndLong) var inputfile: String
@Flag(name: .shortAndLong) var debug:Bool = false