package adif import "strings" // This file embeds the complete ADIF 3.1.7 QSO-field dictionary. It is the // single source of truth for: // - the generic "ADIF fields" editor in the UI (any field becomes editable), // - the "standard ADIF" export mode (only spec fields are emitted), // - import diagnostics (a tag absent here is non-standard / vendor-specific). // // Promoted fields (those with dedicated QSO columns) are flagged Promoted=true // so the UI can hide them from the generic editor — they already have proper // inputs in the main tabs. // FieldKind is a coarse input type used by the generic editor to pick a widget. type FieldKind string const ( KindText FieldKind = "text" // String / IntlString / MultilineString KindNumber FieldKind = "number" // Number / PositiveInteger KindDate FieldKind = "date" // ADIF Date (YYYYMMDD) KindTime FieldKind = "time" // ADIF Time (HHMMSS / HHMM) KindBool FieldKind = "boolean" // Boolean (Y/N) KindEnum FieldKind = "enum" // Enumeration KindLoc FieldKind = "location" // Location (e.g. "N048 09.000") ) // FieldDef describes one ADIF QSO field. type FieldDef struct { Name string `json:"name"` // canonical uppercase ADIF tag Kind FieldKind `json:"kind"` // editor widget hint Category string `json:"category"` // grouping for the UI Promoted bool `json:"promoted"` // has a dedicated QSO column Deprecated bool `json:"deprecated"` // import-only per the spec Intl bool `json:"intl"` // *_INTL UTF-8 variant } // adifVersion is the ADIF spec version OpsLog targets for import/export. const adifVersion = "3.1.7" // ADIFVersion returns the ADIF spec version OpsLog conforms to. func ADIFVersion() string { return adifVersion } // Fields is the full ADIF 3.1.7 QSO-field set. Order is alphabetical within // each category; categories order is roughly "most-used first" for the UI. var Fields = []FieldDef{ // ── Core / contact ────────────────────────────────────────────── {Name: "CALL", Kind: KindText, Category: "Core", Promoted: true}, {Name: "QSO_DATE", Kind: KindDate, Category: "Core", Promoted: true}, {Name: "TIME_ON", Kind: KindTime, Category: "Core", Promoted: true}, {Name: "QSO_DATE_OFF", Kind: KindDate, Category: "Core", Promoted: true}, {Name: "TIME_OFF", Kind: KindTime, Category: "Core", Promoted: true}, {Name: "BAND", Kind: KindEnum, Category: "Core", Promoted: true}, {Name: "BAND_RX", Kind: KindEnum, Category: "Core", Promoted: true}, {Name: "MODE", Kind: KindEnum, Category: "Core", Promoted: true}, {Name: "SUBMODE", Kind: KindEnum, Category: "Core", Promoted: true}, {Name: "FREQ", Kind: KindNumber, Category: "Core", Promoted: true}, {Name: "FREQ_RX", Kind: KindNumber, Category: "Core", Promoted: true}, {Name: "RST_SENT", Kind: KindText, Category: "Core", Promoted: true}, {Name: "RST_RCVD", Kind: KindText, Category: "Core", Promoted: true}, {Name: "QSO_COMPLETE", Kind: KindEnum, Category: "Core", Promoted: true}, {Name: "QSO_RANDOM", Kind: KindBool, Category: "Core", Promoted: true}, {Name: "SWL", Kind: KindBool, Category: "Core", Promoted: true}, // ── Contacted station ─────────────────────────────────────────── {Name: "NAME", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "NAME_INTL", Kind: KindText, Category: "Contacted", Intl: true}, {Name: "QTH", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "QTH_INTL", Kind: KindText, Category: "Contacted", Intl: true}, {Name: "ADDRESS", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "ADDRESS_INTL", Kind: KindText, Category: "Contacted", Intl: true}, {Name: "EMAIL", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "WEB", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "GRIDSQUARE", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "GRIDSQUARE_EXT", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "VUCC_GRIDS", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "COUNTRY", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "COUNTRY_INTL", Kind: KindText, Category: "Contacted", Intl: true}, {Name: "STATE", Kind: KindEnum, Category: "Contacted", Promoted: true}, {Name: "CNTY", Kind: KindEnum, Category: "Contacted", Promoted: true}, {Name: "CNTY_ALT", Kind: KindEnum, Category: "Contacted"}, {Name: "DXCC", Kind: KindEnum, Category: "Contacted", Promoted: true}, {Name: "CONT", Kind: KindEnum, Category: "Contacted", Promoted: true}, {Name: "CQZ", Kind: KindNumber, Category: "Contacted", Promoted: true}, {Name: "ITUZ", Kind: KindNumber, Category: "Contacted", Promoted: true}, {Name: "IOTA", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "IOTA_ISLAND_ID", Kind: KindText, Category: "Contacted"}, {Name: "REGION", Kind: KindEnum, Category: "Contacted", Promoted: true}, {Name: "PFX", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "AGE", Kind: KindNumber, Category: "Contacted", Promoted: true}, {Name: "LAT", Kind: KindLoc, Category: "Contacted", Promoted: true}, {Name: "LON", Kind: KindLoc, Category: "Contacted", Promoted: true}, {Name: "ALTITUDE", Kind: KindNumber, Category: "Contacted"}, {Name: "DISTANCE", Kind: KindNumber, Category: "Contacted", Promoted: true}, {Name: "RIG", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "RIG_INTL", Kind: KindText, Category: "Contacted", Intl: true}, {Name: "ANT", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "CONTACTED_OP", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "EQ_CALL", Kind: KindText, Category: "Contacted", Promoted: true}, {Name: "GUEST_OP", Kind: KindText, Category: "Contacted", Deprecated: true}, {Name: "OWNER_CALLSIGN", Kind: KindText, Category: "Contacted"}, {Name: "SILENT_KEY", Kind: KindBool, Category: "Contacted", Promoted: true}, {Name: "USACA_COUNTIES", Kind: KindText, Category: "Contacted"}, // ── Special activity (POTA/SOTA/WWFF/SIG) ─────────────────────── {Name: "SIG", Kind: KindText, Category: "Activity", Promoted: true}, {Name: "SIG_INFO", Kind: KindText, Category: "Activity", Promoted: true}, {Name: "SIG_INTL", Kind: KindText, Category: "Activity", Intl: true}, {Name: "SIG_INFO_INTL", Kind: KindText, Category: "Activity", Intl: true}, {Name: "POTA_REF", Kind: KindText, Category: "Activity", Promoted: true}, {Name: "SOTA_REF", Kind: KindText, Category: "Activity", Promoted: true}, {Name: "WWFF_REF", Kind: KindText, Category: "Activity", Promoted: true}, // ── Power / propagation / space wx ────────────────────────────── {Name: "TX_PWR", Kind: KindNumber, Category: "Propagation", Promoted: true}, {Name: "RX_PWR", Kind: KindNumber, Category: "Propagation", Promoted: true}, {Name: "A_INDEX", Kind: KindNumber, Category: "Propagation", Promoted: true}, {Name: "K_INDEX", Kind: KindNumber, Category: "Propagation", Promoted: true}, {Name: "SFI", Kind: KindNumber, Category: "Propagation", Promoted: true}, {Name: "PROP_MODE", Kind: KindEnum, Category: "Propagation", Promoted: true}, {Name: "SAT_NAME", Kind: KindText, Category: "Propagation", Promoted: true}, {Name: "SAT_MODE", Kind: KindText, Category: "Propagation", Promoted: true}, {Name: "ANT_AZ", Kind: KindNumber, Category: "Propagation", Promoted: true}, {Name: "ANT_EL", Kind: KindNumber, Category: "Propagation", Promoted: true}, {Name: "ANT_PATH", Kind: KindEnum, Category: "Propagation", Promoted: true}, {Name: "FORCE_INIT", Kind: KindBool, Category: "Propagation"}, {Name: "MAX_BURSTS", Kind: KindNumber, Category: "Propagation"}, {Name: "MS_SHOWER", Kind: KindText, Category: "Propagation"}, {Name: "NR_BURSTS", Kind: KindNumber, Category: "Propagation"}, {Name: "NR_PINGS", Kind: KindNumber, Category: "Propagation"}, // ── QSL / confirmations ───────────────────────────────────────── {Name: "QSL_SENT", Kind: KindEnum, Category: "QSL", Promoted: true}, {Name: "QSL_RCVD", Kind: KindEnum, Category: "QSL", Promoted: true}, {Name: "QSLSDATE", Kind: KindDate, Category: "QSL", Promoted: true}, {Name: "QSLRDATE", Kind: KindDate, Category: "QSL", Promoted: true}, {Name: "QSL_VIA", Kind: KindText, Category: "QSL", Promoted: true}, {Name: "QSL_SENT_VIA", Kind: KindEnum, Category: "QSL"}, {Name: "QSL_RCVD_VIA", Kind: KindEnum, Category: "QSL"}, {Name: "QSLMSG", Kind: KindText, Category: "QSL", Promoted: true}, {Name: "QSLMSG_INTL", Kind: KindText, Category: "QSL", Intl: true}, {Name: "QSLMSG_RCVD", Kind: KindText, Category: "QSL", Promoted: true}, {Name: "LOTW_QSL_SENT", Kind: KindEnum, Category: "QSL", Promoted: true}, {Name: "LOTW_QSL_RCVD", Kind: KindEnum, Category: "QSL", Promoted: true}, {Name: "LOTW_QSLSDATE", Kind: KindDate, Category: "QSL", Promoted: true}, {Name: "LOTW_QSLRDATE", Kind: KindDate, Category: "QSL", Promoted: true}, {Name: "EQSL_QSL_SENT", Kind: KindEnum, Category: "QSL", Promoted: true}, {Name: "EQSL_QSL_RCVD", Kind: KindEnum, Category: "QSL", Promoted: true}, {Name: "EQSL_QSLSDATE", Kind: KindDate, Category: "QSL", Promoted: true}, {Name: "EQSL_QSLRDATE", Kind: KindDate, Category: "QSL", Promoted: true}, {Name: "EQSL_AG", Kind: KindBool, Category: "QSL"}, {Name: "DCL_QSL_SENT", Kind: KindEnum, Category: "QSL"}, {Name: "DCL_QSL_RCVD", Kind: KindEnum, Category: "QSL"}, {Name: "DCL_QSLSDATE", Kind: KindDate, Category: "QSL"}, {Name: "DCL_QSLRDATE", Kind: KindDate, Category: "QSL"}, {Name: "CLUBLOG_QSO_UPLOAD_DATE", Kind: KindDate, Category: "QSL", Promoted: true}, {Name: "CLUBLOG_QSO_UPLOAD_STATUS", Kind: KindEnum, Category: "QSL", Promoted: true}, {Name: "HRDLOG_QSO_UPLOAD_DATE", Kind: KindDate, Category: "QSL", Promoted: true}, {Name: "HRDLOG_QSO_UPLOAD_STATUS", Kind: KindEnum, Category: "QSL", Promoted: true}, {Name: "QRZCOM_QSO_UPLOAD_DATE", Kind: KindDate, Category: "QSL", Promoted: true}, {Name: "QRZCOM_QSO_UPLOAD_STATUS", Kind: KindEnum, Category: "QSL", Promoted: true}, {Name: "QRZCOM_QSO_DOWNLOAD_DATE", Kind: KindDate, Category: "QSL", Promoted: true}, {Name: "QRZCOM_QSO_DOWNLOAD_STATUS", Kind: KindEnum, Category: "QSL", Promoted: true}, {Name: "HAMLOGEU_QSO_UPLOAD_DATE", Kind: KindDate, Category: "QSL"}, {Name: "HAMLOGEU_QSO_UPLOAD_STATUS", Kind: KindEnum, Category: "QSL"}, {Name: "HAMQTH_QSO_UPLOAD_DATE", Kind: KindDate, Category: "QSL"}, {Name: "HAMQTH_QSO_UPLOAD_STATUS", Kind: KindEnum, Category: "QSL"}, // ── Awards / credits ──────────────────────────────────────────── {Name: "CREDIT_SUBMITTED", Kind: KindText, Category: "Awards", Promoted: true}, {Name: "CREDIT_GRANTED", Kind: KindText, Category: "Awards", Promoted: true}, {Name: "AWARD_SUBMITTED", Kind: KindText, Category: "Awards"}, {Name: "AWARD_GRANTED", Kind: KindText, Category: "Awards"}, // ── Contest ───────────────────────────────────────────────────── {Name: "CONTEST_ID", Kind: KindText, Category: "Contest", Promoted: true}, {Name: "SRX", Kind: KindNumber, Category: "Contest", Promoted: true}, {Name: "STX", Kind: KindNumber, Category: "Contest", Promoted: true}, {Name: "SRX_STRING", Kind: KindText, Category: "Contest", Promoted: true}, {Name: "STX_STRING", Kind: KindText, Category: "Contest", Promoted: true}, {Name: "CHECK", Kind: KindText, Category: "Contest", Promoted: true}, {Name: "CLASS", Kind: KindText, Category: "Contest", Promoted: true}, {Name: "PRECEDENCE", Kind: KindText, Category: "Contest", Promoted: true}, {Name: "ARRL_SECT", Kind: KindEnum, Category: "Contest", Promoted: true}, // ── Club memberships ──────────────────────────────────────────── {Name: "SKCC", Kind: KindText, Category: "Clubs", Promoted: true}, {Name: "FISTS", Kind: KindNumber, Category: "Clubs", Promoted: true}, {Name: "FISTS_CC", Kind: KindNumber, Category: "Clubs"}, {Name: "TEN_TEN", Kind: KindNumber, Category: "Clubs", Promoted: true}, {Name: "UKSMG", Kind: KindNumber, Category: "Clubs"}, {Name: "DARC_DOK", Kind: KindText, Category: "Clubs", Promoted: true}, // ── Morse key (3.1.5+) ────────────────────────────────────────── {Name: "MORSE_KEY_TYPE", Kind: KindEnum, Category: "Morse key"}, {Name: "MORSE_KEY_INFO", Kind: KindText, Category: "Morse key"}, // ── Misc / crypto ─────────────────────────────────────────────── {Name: "COMMENT", Kind: KindText, Category: "Misc", Promoted: true}, {Name: "COMMENT_INTL", Kind: KindText, Category: "Misc", Intl: true}, {Name: "NOTES", Kind: KindText, Category: "Misc", Promoted: true}, {Name: "NOTES_INTL", Kind: KindText, Category: "Misc", Intl: true}, {Name: "PUBLIC_KEY", Kind: KindText, Category: "Misc"}, {Name: "VE_PROV", Kind: KindText, Category: "Misc", Deprecated: true}, // ── My station / operator ─────────────────────────────────────── {Name: "STATION_CALLSIGN", Kind: KindText, Category: "My station", Promoted: true}, {Name: "OPERATOR", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_NAME", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_NAME_INTL", Kind: KindText, Category: "My station", Intl: true}, {Name: "MY_GRIDSQUARE", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_GRIDSQUARE_EXT", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_VUCC_GRIDS", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_COUNTRY", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_COUNTRY_INTL", Kind: KindText, Category: "My station", Intl: true}, {Name: "MY_STATE", Kind: KindEnum, Category: "My station", Promoted: true}, {Name: "MY_CNTY", Kind: KindEnum, Category: "My station", Promoted: true}, {Name: "MY_CNTY_ALT", Kind: KindEnum, Category: "My station"}, {Name: "MY_DXCC", Kind: KindEnum, Category: "My station", Promoted: true}, {Name: "MY_CQ_ZONE", Kind: KindNumber, Category: "My station", Promoted: true}, {Name: "MY_ITU_ZONE", Kind: KindNumber, Category: "My station", Promoted: true}, {Name: "MY_IOTA", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_IOTA_ISLAND_ID", Kind: KindText, Category: "My station"}, {Name: "MY_SOTA_REF", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_POTA_REF", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_WWFF_REF", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_SIG", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_SIG_INFO", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_SIG_INTL", Kind: KindText, Category: "My station", Intl: true}, {Name: "MY_SIG_INFO_INTL", Kind: KindText, Category: "My station", Intl: true}, {Name: "MY_LAT", Kind: KindLoc, Category: "My station", Promoted: true}, {Name: "MY_LON", Kind: KindLoc, Category: "My station", Promoted: true}, {Name: "MY_ALTITUDE", Kind: KindNumber, Category: "My station"}, {Name: "MY_STREET", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_STREET_INTL", Kind: KindText, Category: "My station", Intl: true}, {Name: "MY_CITY", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_CITY_INTL", Kind: KindText, Category: "My station", Intl: true}, {Name: "MY_POSTAL_CODE", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_POSTAL_CODE_INTL", Kind: KindText, Category: "My station", Intl: true}, {Name: "MY_RIG", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_RIG_INTL", Kind: KindText, Category: "My station", Intl: true}, {Name: "MY_ANTENNA", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_ANTENNA_INTL", Kind: KindText, Category: "My station", Intl: true}, {Name: "MY_ARRL_SECT", Kind: KindEnum, Category: "My station", Promoted: true}, {Name: "MY_USACA_COUNTIES", Kind: KindText, Category: "My station"}, {Name: "MY_DARC_DOK", Kind: KindText, Category: "My station", Promoted: true}, {Name: "MY_FISTS", Kind: KindNumber, Category: "My station"}, {Name: "MY_MORSE_KEY_TYPE", Kind: KindEnum, Category: "My station"}, {Name: "MY_MORSE_KEY_INFO", Kind: KindText, Category: "My station"}, } // fieldIndex maps an uppercase ADIF tag to its definition for O(1) lookup. var fieldIndex = func() map[string]FieldDef { m := make(map[string]FieldDef, len(Fields)) for _, f := range Fields { m[f.Name] = f } return m }() // IsStandardField reports whether tag (any case) is a defined ADIF 3.1.7 // field. APP_* and USERDEF tags are non-standard and return false. func IsStandardField(tag string) bool { _, ok := fieldIndex[strings.ToUpper(strings.TrimSpace(tag))] return ok } // LookupField returns the definition for a tag (any case), ok=false if unknown. func LookupField(tag string) (FieldDef, bool) { f, ok := fieldIndex[strings.ToUpper(strings.TrimSpace(tag))] return f, ok }