File size: 6,542 Bytes
20f83d9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/**
 * Single source of truth for the 13 canonical chokepoints.
 *
 * All other chokepoint references in the codebase should derive from or
 * validate against this registry.  Key relationships:
 *   - `id`              β†’ canonical ID used everywhere in this repo
 *   - `geoId`           β†’ same as `id`; matches STRATEGIC_WATERWAYS.id in geo.ts
 *   - `relayName`       β†’ display name used by the AIS relay
 *   - `portwatchName`   β†’ name in PortWatch transit data
 *   - `corridorRiskName`β†’ name in CorridorRisk feed (null = not covered)
 *   - `baselineId`      β†’ EIA/IEA energy baseline ID (null = no energy model)
 *   - `shockModelSupported` β†’ true for the 4 chokepoints with an energy shock model
 *   - `routeIds`        β†’ TRADE_ROUTES.id values that include this chokepoint
 */
export interface ChokepointRegistryEntry {
  id: string;
  displayName: string;
  /** Same as id β€” matches STRATEGIC_WATERWAYS.id in geo.ts */
  geoId: string;
  relayName: string;
  portwatchName: string;
  corridorRiskName: string | null;
  /** EIA chokepoint baseline ID.  Null = no EIA baseline. */
  baselineId: string | null;
  /**
   * True for the 4 chokepoints that have an energy shock model
   * (suez, malacca_strait, hormuz_strait, bab_el_mandeb).
   */
  shockModelSupported: boolean;
  /** IDs of TRADE_ROUTES entries whose waypoints include this chokepoint. */
  routeIds: string[];
  lat: number;
  lon: number;
}

export const CHOKEPOINT_REGISTRY: readonly ChokepointRegistryEntry[] = [
  {
    id: 'suez',
    displayName: 'Suez Canal',
    geoId: 'suez',
    relayName: 'Suez Canal',
    portwatchName: 'Suez Canal',
    corridorRiskName: 'Suez',
    baselineId: 'suez',
    shockModelSupported: true,
    routeIds: ['china-europe-suez', 'china-us-east-suez', 'gulf-europe-oil', 'qatar-europe-lng', 'singapore-med', 'india-europe'],
    lat: 30.5,
    lon: 32.3,
  },
  {
    id: 'malacca_strait',
    displayName: 'Strait of Malacca',
    geoId: 'malacca_strait',
    relayName: 'Malacca Strait',
    portwatchName: 'Malacca Strait',
    corridorRiskName: 'Malacca',
    baselineId: 'malacca',
    shockModelSupported: true,
    routeIds: ['china-europe-suez', 'china-us-east-suez', 'gulf-asia-oil', 'qatar-asia-lng', 'india-se-asia', 'china-africa', 'cpec-route'],
    lat: 2.5,
    lon: 101.5,
  },
  {
    id: 'hormuz_strait',
    displayName: 'Strait of Hormuz',
    geoId: 'hormuz_strait',
    relayName: 'Strait of Hormuz',
    portwatchName: 'Strait of Hormuz',
    corridorRiskName: 'Hormuz',
    baselineId: 'hormuz',
    shockModelSupported: true,
    routeIds: ['gulf-europe-oil', 'gulf-asia-oil', 'qatar-europe-lng', 'qatar-asia-lng', 'gulf-americas-cape'],
    lat: 26.5,
    lon: 56.5,
  },
  {
    id: 'bab_el_mandeb',
    displayName: 'Bab el-Mandeb',
    geoId: 'bab_el_mandeb',
    relayName: 'Bab el-Mandeb Strait',
    portwatchName: 'Bab el-Mandeb Strait',
    corridorRiskName: 'Bab el-Mandeb',
    baselineId: 'babelm',
    shockModelSupported: true,
    routeIds: ['china-europe-suez', 'china-us-east-suez', 'gulf-europe-oil', 'qatar-europe-lng', 'singapore-med', 'india-europe'],
    lat: 12.5,
    lon: 43.3,
  },
  {
    id: 'panama',
    displayName: 'Panama Canal',
    geoId: 'panama',
    relayName: 'Panama Canal',
    portwatchName: 'Panama Canal',
    corridorRiskName: 'Panama',
    baselineId: 'panama',
    shockModelSupported: false,
    routeIds: ['china-us-east-panama', 'panama-transit'],
    lat: 9.1,
    lon: -79.7,
  },
  {
    id: 'taiwan_strait',
    displayName: 'Taiwan Strait',
    geoId: 'taiwan_strait',
    relayName: 'Taiwan Strait',
    portwatchName: 'Taiwan Strait',
    corridorRiskName: 'Taiwan',
    baselineId: null,
    shockModelSupported: false,
    routeIds: ['china-us-west', 'intra-asia-container'],
    lat: 24.0,
    lon: 119.5,
  },
  {
    id: 'cape_of_good_hope',
    displayName: 'Cape of Good Hope',
    geoId: 'cape_of_good_hope',
    relayName: 'Cape of Good Hope',
    portwatchName: 'Cape of Good Hope',
    corridorRiskName: 'Cape of Good Hope',
    baselineId: null,
    shockModelSupported: false,
    routeIds: ['brazil-china-bulk', 'gulf-americas-cape', 'asia-europe-cape'],
    lat: -34.36,
    lon: 18.49,
  },
  {
    id: 'gibraltar',
    displayName: 'Strait of Gibraltar',
    geoId: 'gibraltar',
    relayName: 'Gibraltar Strait',
    portwatchName: 'Gibraltar Strait',
    corridorRiskName: null,
    baselineId: null,
    shockModelSupported: false,
    routeIds: ['gulf-europe-oil', 'singapore-med', 'india-europe', 'asia-europe-cape'],
    lat: 35.9,
    lon: -5.6,
  },
  {
    id: 'bosphorus',
    displayName: 'Bosporus Strait',
    geoId: 'bosphorus',
    relayName: 'Bosporus Strait',
    portwatchName: 'Bosporus Strait',
    corridorRiskName: null,
    baselineId: 'turkish',
    shockModelSupported: false,
    routeIds: ['russia-med-oil'],
    lat: 41.1,
    lon: 29.0,
  },
  {
    id: 'korea_strait',
    displayName: 'Korea Strait',
    geoId: 'korea_strait',
    relayName: 'Korea Strait',
    portwatchName: 'Korea Strait',
    corridorRiskName: null,
    baselineId: null,
    shockModelSupported: false,
    routeIds: [],
    lat: 34.0,
    lon: 129.0,
  },
  {
    id: 'dover_strait',
    displayName: 'Dover Strait',
    geoId: 'dover_strait',
    relayName: 'Dover Strait',
    portwatchName: 'Dover Strait',
    corridorRiskName: null,
    baselineId: 'danish',
    shockModelSupported: false,
    routeIds: [],
    lat: 51.0,
    lon: 1.5,
  },
  {
    id: 'kerch_strait',
    displayName: 'Kerch Strait',
    geoId: 'kerch_strait',
    relayName: 'Kerch Strait',
    portwatchName: 'Kerch Strait',
    corridorRiskName: null,
    baselineId: null,
    shockModelSupported: false,
    routeIds: [],
    lat: 45.3,
    lon: 36.6,
  },
  {
    id: 'lombok_strait',
    displayName: 'Lombok Strait',
    geoId: 'lombok_strait',
    relayName: 'Lombok Strait',
    portwatchName: 'Lombok Strait',
    corridorRiskName: null,
    baselineId: null,
    shockModelSupported: false,
    routeIds: [],
    lat: -8.5,
    lon: 115.7,
  },
];

/** Set of canonical IDs for fast membership checks. */
export const CANONICAL_CHOKEPOINT_IDS = new Set(CHOKEPOINT_REGISTRY.map(c => c.id));

/** Lookup by canonical ID. */
export function getChokepoint(id: string): ChokepointRegistryEntry | undefined {
  return CHOKEPOINT_REGISTRY.find(c => c.id === id);
}

/** Chokepoints that have an energy shock model (oil + LNG). */
export const SHOCK_MODEL_CHOKEPOINTS = CHOKEPOINT_REGISTRY.filter(c => c.shockModelSupported);