@microsoft/terraform-cdk-constructs 1.3.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/.jsii +32238 -27310
  2. package/API.md +43714 -35942
  3. package/lib/azure-actiongroup/lib/action-group.js +1 -1
  4. package/lib/azure-activitylogalert/lib/activity-log-alert.js +1 -1
  5. package/lib/azure-aks/lib/aks-cluster.js +1 -1
  6. package/lib/azure-diagnosticsettings/lib/diagnostic-settings.js +1 -1
  7. package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset.js +1 -1
  8. package/lib/azure-dnsforwardingruleset/lib/forwarding-rule.js +1 -1
  9. package/lib/azure-dnsforwardingruleset/lib/virtual-network-link.js +1 -1
  10. package/lib/azure-dnsresolver/lib/dns-resolver.js +1 -1
  11. package/lib/azure-dnsresolver/lib/inbound-endpoint.js +1 -1
  12. package/lib/azure-dnsresolver/lib/outbound-endpoint.js +1 -1
  13. package/lib/azure-dnszone/lib/dns-zone.js +1 -1
  14. package/lib/azure-metricalert/lib/metric-alert.js +1 -1
  15. package/lib/azure-networkinterface/lib/network-interface.js +1 -1
  16. package/lib/azure-networksecuritygroup/lib/network-security-group.js +1 -1
  17. package/lib/azure-policyassignment/lib/policy-assignment.js +1 -1
  18. package/lib/azure-policydefinition/lib/policy-definition.js +1 -1
  19. package/lib/azure-privatednszone/lib/private-dns-zone.js +1 -1
  20. package/lib/azure-privatednszonelink/lib/private-dns-zone-link.js +1 -1
  21. package/lib/azure-publicipaddress/lib/public-ip-address.js +1 -1
  22. package/lib/azure-resourcegroup/lib/resource-group.js +1 -1
  23. package/lib/azure-roleassignment/lib/role-assignment.js +1 -1
  24. package/lib/azure-roledefinition/lib/role-definition.js +1 -1
  25. package/lib/azure-storageaccount/lib/storage-account.js +1 -1
  26. package/lib/azure-subnet/lib/subnet.js +1 -1
  27. package/lib/azure-virtualmachine/lib/virtual-machine.js +1 -1
  28. package/lib/azure-virtualnetwork/lib/virtual-network.js +1 -1
  29. package/lib/azure-virtualnetworkgateway/index.d.ts +4 -0
  30. package/lib/azure-virtualnetworkgateway/index.js +21 -0
  31. package/lib/azure-virtualnetworkgateway/lib/index.d.ts +5 -0
  32. package/lib/azure-virtualnetworkgateway/lib/index.js +22 -0
  33. package/lib/azure-virtualnetworkgateway/lib/virtual-network-gateway-schemas.d.ts +32 -0
  34. package/lib/azure-virtualnetworkgateway/lib/virtual-network-gateway-schemas.js +298 -0
  35. package/lib/azure-virtualnetworkgateway/lib/virtual-network-gateway.d.ts +368 -0
  36. package/lib/azure-virtualnetworkgateway/lib/virtual-network-gateway.js +285 -0
  37. package/lib/azure-virtualnetworkgateway/test/virtual-network-gateway.integ.d.ts +12 -0
  38. package/lib/azure-virtualnetworkgateway/test/virtual-network-gateway.integ.js +129 -0
  39. package/lib/azure-virtualnetworkgateway/test/virtual-network-gateway.spec.d.ts +8 -0
  40. package/lib/azure-virtualnetworkgateway/test/virtual-network-gateway.spec.js +691 -0
  41. package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration.js +1 -1
  42. package/lib/azure-virtualnetworkmanager/lib/index.d.ts +5 -0
  43. package/lib/azure-virtualnetworkmanager/lib/index.js +6 -1
  44. package/lib/azure-virtualnetworkmanager/lib/ipam-pool-schemas.d.ts +24 -0
  45. package/lib/azure-virtualnetworkmanager/lib/ipam-pool-schemas.js +169 -0
  46. package/lib/azure-virtualnetworkmanager/lib/ipam-pool-static-cidr-schemas.d.ts +32 -0
  47. package/lib/azure-virtualnetworkmanager/lib/ipam-pool-static-cidr-schemas.js +206 -0
  48. package/lib/azure-virtualnetworkmanager/lib/ipam-pool-static-cidr.d.ts +170 -0
  49. package/lib/azure-virtualnetworkmanager/lib/ipam-pool-static-cidr.js +214 -0
  50. package/lib/azure-virtualnetworkmanager/lib/ipam-pool.d.ts +175 -0
  51. package/lib/azure-virtualnetworkmanager/lib/ipam-pool.js +206 -0
  52. package/lib/azure-virtualnetworkmanager/lib/network-group-static-member.js +1 -1
  53. package/lib/azure-virtualnetworkmanager/lib/network-group.js +1 -1
  54. package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration.js +1 -1
  55. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection.js +1 -1
  56. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule.js +1 -1
  57. package/lib/azure-virtualnetworkmanager/lib/utils/cidr-validator.d.ts +225 -0
  58. package/lib/azure-virtualnetworkmanager/lib/utils/cidr-validator.js +389 -0
  59. package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager.d.ts +56 -0
  60. package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager.js +29 -2
  61. package/lib/azure-virtualnetworkmanager/test/cidr-validator.spec.d.ts +6 -0
  62. package/lib/azure-virtualnetworkmanager/test/cidr-validator.spec.js +292 -0
  63. package/lib/azure-virtualnetworkmanager/test/ipam-pool-static-cidr.spec.d.ts +6 -0
  64. package/lib/azure-virtualnetworkmanager/test/ipam-pool-static-cidr.spec.js +430 -0
  65. package/lib/azure-virtualnetworkmanager/test/ipam-pool.spec.d.ts +6 -0
  66. package/lib/azure-virtualnetworkmanager/test/ipam-pool.spec.js +372 -0
  67. package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.integ.d.ts +2 -1
  68. package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.integ.js +30 -3
  69. package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.spec.js +105 -1
  70. package/lib/azure-vmss/lib/virtual-machine-scale-set.js +1 -1
  71. package/lib/core-azure/lib/azapi/azapi-resource.js +2 -2
  72. package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-client-config/index.js +2 -2
  73. package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource/index.js +5 -5
  74. package/lib/core-azure/lib/azapi/providers-azapi/provider/index.js +1 -1
  75. package/lib/core-azure/lib/azapi/providers-azapi/resource/index.js +5 -5
  76. package/lib/core-azure/lib/azapi/providers-azapi/resource-action/index.js +3 -3
  77. package/lib/core-azure/lib/azapi/providers-azapi/update-resource/index.js +3 -3
  78. package/lib/core-azure/lib/azapi/schema-mapper/schema-mapper.js +1 -1
  79. package/lib/core-azure/lib/version-manager/api-version-manager.js +1 -1
  80. package/lib/core-azure/lib/version-manager/interfaces/version-interfaces.js +7 -7
  81. package/lib/index.d.ts +2 -0
  82. package/lib/index.js +4 -2
  83. package/lib/testing/index.js +2 -2
  84. package/lib/testing/lib/cleanup.js +1 -1
  85. package/lib/testing/lib/metadata.js +1 -1
  86. package/package.json +1 -1
@@ -0,0 +1,389 @@
1
+ "use strict";
2
+ /**
3
+ * CIDR Validator Utility
4
+ *
5
+ * Provides comprehensive validation and parsing utilities for IPv4 CIDR notation.
6
+ * Used by IPAM constructs to ensure proper network address space management.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.isValidCidr = isValidCidr;
10
+ exports.isPrivateRange = isPrivateRange;
11
+ exports.cidrsOverlap = cidrsOverlap;
12
+ exports.isSubnet = isSubnet;
13
+ exports.calculateAddressCount = calculateAddressCount;
14
+ exports.isValidPrefixLength = isValidPrefixLength;
15
+ exports.validateCidr = validateCidr;
16
+ exports.parseCidr = parseCidr;
17
+ exports.checkOverlap = checkOverlap;
18
+ exports.validateNoOverlaps = validateNoOverlaps;
19
+ exports.isContained = isContained;
20
+ exports.validateContainment = validateContainment;
21
+ exports.ipToNumber = ipToNumber;
22
+ exports.numberToIp = numberToIp;
23
+ exports.prefixToMask = prefixToMask;
24
+ const IPV4_REGEX = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,2})$/;
25
+ // RFC 1918 private IP ranges
26
+ const PRIVATE_RANGES = [
27
+ { start: "10.0.0.0", end: "10.255.255.255", cidr: "10.0.0.0/8" },
28
+ { start: "172.16.0.0", end: "172.31.255.255", cidr: "172.16.0.0/12" },
29
+ { start: "192.168.0.0", end: "192.168.255.255", cidr: "192.168.0.0/16" },
30
+ ];
31
+ /**
32
+ * Validates if a string is a valid CIDR notation
33
+ *
34
+ * @param cidr - CIDR string (e.g., "10.0.0.0/16")
35
+ * @returns boolean - true if valid CIDR format
36
+ *
37
+ * @example
38
+ * const valid = isValidCidr("10.0.0.0/16");
39
+ * console.log(valid); // true
40
+ */
41
+ function isValidCidr(cidr) {
42
+ const result = validateCidr(cidr);
43
+ return result.valid;
44
+ }
45
+ /**
46
+ * Validates if CIDR is within allowed private ranges (RFC 1918)
47
+ *
48
+ * @param cidr - CIDR string
49
+ * @returns boolean - true if within private IP range
50
+ *
51
+ * @example
52
+ * const isPrivate = isPrivateRange("10.0.0.0/16");
53
+ * console.log(isPrivate); // true
54
+ */
55
+ function isPrivateRange(cidr) {
56
+ if (!isValidCidr(cidr)) {
57
+ return false;
58
+ }
59
+ const parsed = parseCidr(cidr);
60
+ const startNum = ipToNumber(parsed.firstIp);
61
+ const endNum = ipToNumber(parsed.lastIp);
62
+ // Check if the entire CIDR range falls within any private range
63
+ return PRIVATE_RANGES.some((range) => {
64
+ const rangeStart = ipToNumber(range.start);
65
+ const rangeEnd = ipToNumber(range.end);
66
+ return startNum >= rangeStart && endNum <= rangeEnd;
67
+ });
68
+ }
69
+ /**
70
+ * Checks if two CIDR blocks overlap
71
+ *
72
+ * @param cidr1 - First CIDR
73
+ * @param cidr2 - Second CIDR
74
+ * @returns boolean - true if CIDRs overlap
75
+ *
76
+ * @example
77
+ * const overlap = cidrsOverlap("10.0.0.0/8", "10.1.0.0/16");
78
+ * console.log(overlap); // true
79
+ */
80
+ function cidrsOverlap(cidr1, cidr2) {
81
+ return checkOverlap(cidr1, cidr2);
82
+ }
83
+ /**
84
+ * Validates if child CIDR is contained within parent CIDR
85
+ *
86
+ * @param childCidr - Child CIDR block
87
+ * @param parentCidr - Parent CIDR block
88
+ * @returns boolean - true if child is subnet of parent
89
+ *
90
+ * @example
91
+ * const isSubnet = isSubnet("10.1.0.0/16", "10.0.0.0/8");
92
+ * console.log(isSubnet); // true
93
+ */
94
+ function isSubnet(childCidr, parentCidr) {
95
+ return isContained(parentCidr, childCidr);
96
+ }
97
+ /**
98
+ * Calculates number of IP addresses in a CIDR block
99
+ *
100
+ * @param cidr - CIDR string
101
+ * @returns number - Total IP addresses in the block
102
+ *
103
+ * @example
104
+ * const count = calculateAddressCount("10.0.0.0/24");
105
+ * console.log(count); // 256
106
+ */
107
+ function calculateAddressCount(cidr) {
108
+ const parsed = parseCidr(cidr);
109
+ return parsed.totalAddresses;
110
+ }
111
+ /**
112
+ * Validates prefix length is within allowed range
113
+ *
114
+ * @param cidr - CIDR string
115
+ * @param minPrefix - Minimum allowed prefix (e.g., 8)
116
+ * @param maxPrefix - Maximum allowed prefix (e.g., 29)
117
+ * @returns boolean - true if prefix length is within range
118
+ *
119
+ * @example
120
+ * const valid = isValidPrefixLength("10.0.0.0/24", 8, 29);
121
+ * console.log(valid); // true
122
+ */
123
+ function isValidPrefixLength(cidr, minPrefix, maxPrefix) {
124
+ if (!isValidCidr(cidr)) {
125
+ return false;
126
+ }
127
+ const parsed = parseCidr(cidr);
128
+ return parsed.prefix >= minPrefix && parsed.prefix <= maxPrefix;
129
+ }
130
+ /**
131
+ * Validate CIDR format and structure
132
+ *
133
+ * @param cidr - CIDR notation string (e.g., "10.0.0.0/8")
134
+ * @returns Validation result with errors and warnings
135
+ *
136
+ * @example
137
+ * const result = validateCidr("10.0.0.0/8");
138
+ * if (!result.valid) {
139
+ * console.error("Invalid CIDR:", result.errors);
140
+ * }
141
+ */
142
+ function validateCidr(cidr) {
143
+ const errors = [];
144
+ const warnings = [];
145
+ if (!cidr || typeof cidr !== "string") {
146
+ errors.push("CIDR must be a non-empty string");
147
+ return { valid: false, errors, warnings };
148
+ }
149
+ const match = cidr.match(IPV4_REGEX);
150
+ if (!match) {
151
+ errors.push(`Invalid CIDR format: ${cidr}. Expected format: x.x.x.x/y`);
152
+ return { valid: false, errors, warnings };
153
+ }
154
+ const [, oct1, oct2, oct3, oct4, prefix] = match;
155
+ const octets = [oct1, oct2, oct3, oct4].map(Number);
156
+ const prefixLength = Number(prefix);
157
+ // Validate octets (0-255)
158
+ for (let i = 0; i < octets.length; i++) {
159
+ if (octets[i] < 0 || octets[i] > 255) {
160
+ errors.push(`Invalid octet value: ${octets[i]}. Must be between 0 and 255`);
161
+ }
162
+ }
163
+ // Validate prefix length (0-32)
164
+ if (prefixLength < 0 || prefixLength > 32) {
165
+ errors.push(`Invalid prefix length: ${prefixLength}. Must be between 0 and 32`);
166
+ }
167
+ if (errors.length > 0) {
168
+ return { valid: false, errors, warnings };
169
+ }
170
+ // Verify network address alignment
171
+ const ipNum = ipToNumber(octets.join("."));
172
+ const mask = prefixToMask(prefixLength);
173
+ const networkNum = ipNum & mask;
174
+ if (ipNum !== networkNum) {
175
+ const correctNetwork = numberToIp(networkNum);
176
+ warnings.push(`IP address ${octets.join(".")} is not aligned to network boundary. ` +
177
+ `Network address should be ${correctNetwork}/${prefixLength}`);
178
+ }
179
+ return { valid: errors.length === 0, errors, warnings };
180
+ }
181
+ /**
182
+ * Parse CIDR into structured information
183
+ *
184
+ * @param cidr - CIDR notation string
185
+ * @returns Parsed CIDR information
186
+ * @throws Error if CIDR format is invalid
187
+ *
188
+ * @example
189
+ * const parsed = parseCidr("10.0.0.0/8");
190
+ * console.log(`Network: ${parsed.network}, Prefix: ${parsed.prefix}`);
191
+ * console.log(`Range: ${parsed.firstIp} - ${parsed.lastIp}`);
192
+ * console.log(`Total addresses: ${parsed.totalAddresses}`);
193
+ */
194
+ function parseCidr(cidr) {
195
+ const validation = validateCidr(cidr);
196
+ if (!validation.valid) {
197
+ throw new Error(`Invalid CIDR: ${validation.errors.join(", ")}`);
198
+ }
199
+ const match = cidr.match(IPV4_REGEX);
200
+ const [, oct1, oct2, oct3, oct4, prefix] = match;
201
+ const ipAddress = `${oct1}.${oct2}.${oct3}.${oct4}`;
202
+ const prefixLength = Number(prefix);
203
+ const ipNum = ipToNumber(ipAddress);
204
+ const mask = prefixToMask(prefixLength);
205
+ const networkNum = ipNum & mask;
206
+ const broadcastNum = networkNum | (~mask >>> 0);
207
+ const totalAddresses = Math.pow(2, 32 - prefixLength);
208
+ const firstIpNum = networkNum;
209
+ const lastIpNum = broadcastNum;
210
+ return {
211
+ cidr,
212
+ network: numberToIp(networkNum),
213
+ prefix: prefixLength,
214
+ firstIp: numberToIp(firstIpNum),
215
+ lastIp: numberToIp(lastIpNum),
216
+ totalAddresses,
217
+ netmask: numberToIp(mask),
218
+ };
219
+ }
220
+ /**
221
+ * Check if two CIDRs overlap
222
+ *
223
+ * @param cidr1 - First CIDR block
224
+ * @param cidr2 - Second CIDR block
225
+ * @returns True if the CIDRs overlap
226
+ *
227
+ * @example
228
+ * const overlaps = checkOverlap("10.0.0.0/16", "10.0.1.0/24");
229
+ * console.log(overlaps); // true
230
+ */
231
+ function checkOverlap(cidr1, cidr2) {
232
+ const parsed1 = parseCidr(cidr1);
233
+ const parsed2 = parseCidr(cidr2);
234
+ const start1 = ipToNumber(parsed1.firstIp);
235
+ const end1 = ipToNumber(parsed1.lastIp);
236
+ const start2 = ipToNumber(parsed2.firstIp);
237
+ const end2 = ipToNumber(parsed2.lastIp);
238
+ // Check if ranges overlap
239
+ return !(end1 < start2 || end2 < start1);
240
+ }
241
+ /**
242
+ * Validate that multiple CIDRs don't overlap
243
+ *
244
+ * @param cidrs - Array of CIDR blocks to check
245
+ * @returns Validation result with details of any overlaps
246
+ *
247
+ * @example
248
+ * const result = validateNoOverlaps([
249
+ * "10.0.0.0/16",
250
+ * "10.1.0.0/16",
251
+ * "10.0.1.0/24"
252
+ * ]);
253
+ * if (!result.valid) {
254
+ * console.error("Overlapping CIDRs:", result.errors);
255
+ * }
256
+ */
257
+ function validateNoOverlaps(cidrs) {
258
+ const errors = [];
259
+ const warnings = [];
260
+ // First validate each CIDR individually
261
+ for (const cidr of cidrs) {
262
+ const validation = validateCidr(cidr);
263
+ if (!validation.valid) {
264
+ errors.push(`Invalid CIDR ${cidr}: ${validation.errors.join(", ")}`);
265
+ }
266
+ }
267
+ if (errors.length > 0) {
268
+ return { valid: false, errors, warnings };
269
+ }
270
+ // Check for overlaps
271
+ for (let i = 0; i < cidrs.length; i++) {
272
+ for (let j = i + 1; j < cidrs.length; j++) {
273
+ if (checkOverlap(cidrs[i], cidrs[j])) {
274
+ errors.push(`CIDRs overlap: ${cidrs[i]} and ${cidrs[j]}`);
275
+ }
276
+ }
277
+ }
278
+ return { valid: errors.length === 0, errors, warnings };
279
+ }
280
+ /**
281
+ * Check if a child CIDR is contained within a parent CIDR
282
+ *
283
+ * @param parentCidr - Parent CIDR block
284
+ * @param childCidr - Child CIDR block to check
285
+ * @returns True if child is fully contained in parent
286
+ *
287
+ * @example
288
+ * const contained = isContained("10.0.0.0/16", "10.0.1.0/24");
289
+ * console.log(contained); // true
290
+ */
291
+ function isContained(parentCidr, childCidr) {
292
+ const parent = parseCidr(parentCidr);
293
+ const child = parseCidr(childCidr);
294
+ const parentStart = ipToNumber(parent.firstIp);
295
+ const parentEnd = ipToNumber(parent.lastIp);
296
+ const childStart = ipToNumber(child.firstIp);
297
+ const childEnd = ipToNumber(child.lastIp);
298
+ // Child must be fully within parent range
299
+ return childStart >= parentStart && childEnd <= parentEnd;
300
+ }
301
+ /**
302
+ * Validate that multiple child CIDRs are all contained within a parent CIDR
303
+ *
304
+ * @param parentCidr - Parent CIDR block
305
+ * @param childCidrs - Array of child CIDR blocks
306
+ * @returns Validation result with details of any containment violations
307
+ *
308
+ * @example
309
+ * const result = validateContainment("10.0.0.0/16", [
310
+ * "10.0.1.0/24",
311
+ * "10.0.2.0/24"
312
+ * ]);
313
+ * if (!result.valid) {
314
+ * console.error("Containment violations:", result.errors);
315
+ * }
316
+ */
317
+ function validateContainment(parentCidr, childCidrs) {
318
+ const errors = [];
319
+ const warnings = [];
320
+ // Validate parent CIDR
321
+ const parentValidation = validateCidr(parentCidr);
322
+ if (!parentValidation.valid) {
323
+ errors.push(`Invalid parent CIDR ${parentCidr}: ${parentValidation.errors.join(", ")}`);
324
+ return { valid: false, errors, warnings };
325
+ }
326
+ // Validate each child CIDR
327
+ for (const childCidr of childCidrs) {
328
+ const childValidation = validateCidr(childCidr);
329
+ if (!childValidation.valid) {
330
+ errors.push(`Invalid child CIDR ${childCidr}: ${childValidation.errors.join(", ")}`);
331
+ continue;
332
+ }
333
+ // Check containment
334
+ if (!isContained(parentCidr, childCidr)) {
335
+ errors.push(`Child CIDR ${childCidr} is not contained within parent CIDR ${parentCidr}`);
336
+ }
337
+ }
338
+ return { valid: errors.length === 0, errors, warnings };
339
+ }
340
+ /**
341
+ * Convert an IP address string to a 32-bit number
342
+ *
343
+ * @param ip - IP address string (e.g., "10.0.0.1")
344
+ * @returns 32-bit number representation
345
+ *
346
+ * @example
347
+ * const num = ipToNumber("10.0.0.1");
348
+ * console.log(num); // 167772161
349
+ */
350
+ function ipToNumber(ip) {
351
+ const octets = ip.split(".").map(Number);
352
+ return (((octets[0] << 24) >>> 0) +
353
+ ((octets[1] << 16) >>> 0) +
354
+ ((octets[2] << 8) >>> 0) +
355
+ octets[3]);
356
+ }
357
+ /**
358
+ * Convert a 32-bit number to an IP address string
359
+ *
360
+ * @param num - 32-bit number representation
361
+ * @returns IP address string
362
+ *
363
+ * @example
364
+ * const ip = numberToIp(167772161);
365
+ * console.log(ip); // "10.0.0.1"
366
+ */
367
+ function numberToIp(num) {
368
+ return [
369
+ (num >>> 24) & 0xff,
370
+ (num >>> 16) & 0xff,
371
+ (num >>> 8) & 0xff,
372
+ num & 0xff,
373
+ ].join(".");
374
+ }
375
+ /**
376
+ * Convert a prefix length to a netmask number
377
+ *
378
+ * @param prefix - Prefix length (0-32)
379
+ * @returns 32-bit netmask number
380
+ *
381
+ * @example
382
+ * const mask = prefixToMask(24);
383
+ * const maskIp = numberToIp(mask);
384
+ * console.log(maskIp); // "255.255.255.0"
385
+ */
386
+ function prefixToMask(prefix) {
387
+ return prefix === 0 ? 0 : (0xffffffff << (32 - prefix)) >>> 0;
388
+ }
389
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2lkci12YWxpZGF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXp1cmUtdmlydHVhbG5ldHdvcmttYW5hZ2VyL2xpYi91dGlscy9jaWRyLXZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7O0dBS0c7O0FBdURILGtDQUdDO0FBWUQsd0NBZUM7QUFhRCxvQ0FFQztBQWFELDRCQUVDO0FBWUQsc0RBR0M7QUFjRCxrREFXQztBQWNELG9DQXFEQztBQWVELDhCQTZCQztBQWFELG9DQVdDO0FBa0JELGdEQTBCQztBQWFELGtDQVdDO0FBa0JELGtEQW1DQztBQVlELGdDQVFDO0FBWUQsZ0NBT0M7QUFhRCxvQ0FFQztBQTdhRCxNQUFNLFVBQVUsR0FBRyx5REFBeUQsQ0FBQztBQUU3RSw2QkFBNkI7QUFDN0IsTUFBTSxjQUFjLEdBQUc7SUFDckIsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxnQkFBZ0IsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFO0lBQ2hFLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxHQUFHLEVBQUUsZ0JBQWdCLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRTtJQUNyRSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsR0FBRyxFQUFFLGlCQUFpQixFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRTtDQUN6RSxDQUFDO0FBRUY7Ozs7Ozs7OztHQVNHO0FBQ0gsU0FBZ0IsV0FBVyxDQUFDLElBQVk7SUFDdEMsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xDLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQztBQUN0QixDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsU0FBZ0IsY0FBYyxDQUFDLElBQVk7SUFDekMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3ZCLE9BQU8sS0FBSyxDQUFDO0lBQ2Ys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QUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsQ0FBQztBQUVEOzs7Ozs7Ozs7O0dBVUc7QUFDSCxTQUFnQixZQUFZLENBQUMsTUFBYztJQUN6QyxPQUFPLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLElBQUksQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDaEUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ0lEUiBWYWxpZGF0b3IgVXRpbGl0eVxuICpcbiAqIFByb3ZpZGVzIGNvbXByZWhlbnNpdmUgdmFsaWRhdGlvbiBhbmQgcGFyc2luZyB1dGlsaXRpZXMgZm9yIElQdjQgQ0lEUiBub3RhdGlvbi5cbiAqIFVzZWQgYnkgSVBBTSBjb25zdHJ1Y3RzIHRvIGVuc3VyZSBwcm9wZXIgbmV0d29yayBhZGRyZXNzIHNwYWNlIG1hbmFnZW1lbnQuXG4gKi9cblxuLyogZXNsaW50LWRpc2FibGUgbm8tYml0d2lzZSAqL1xuXG4vKipcbiAqIFJlc3VsdCBvZiBDSURSIHZhbGlkYXRpb24gb3BlcmF0aW9uc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIENpZHJWYWxpZGF0aW9uUmVzdWx0IHtcbiAgLyoqIFdoZXRoZXIgdGhlIHZhbGlkYXRpb24gcGFzc2VkICovXG4gIHJlYWRvbmx5IHZhbGlkOiBib29sZWFuO1xuICAvKiogTGlzdCBvZiB2YWxpZGF0aW9uIGVycm9ycyAqL1xuICByZWFkb25seSBlcnJvcnM6IHN0cmluZ1tdO1xuICAvKiogTGlzdCBvZiB2YWxpZGF0aW9uIHdhcm5pbmdzICovXG4gIHJlYWRvbmx5IHdhcm5pbmdzOiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBQYXJzZWQgQ0lEUiBpbmZvcm1hdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhcnNlZENpZHIge1xuICAvKiogT3JpZ2luYWwgQ0lEUiBub3RhdGlvbiAoZS5nLiwgXCIxMC4wLjAuMC84XCIpICovXG4gIHJlYWRvbmx5IGNpZHI6IHN0cmluZztcbiAgLyoqIE5ldHdvcmsgYWRkcmVzcyAoZS5nLiwgXCIxMC4wLjAuMFwiKSAqL1xuICByZWFkb25seSBuZXR3b3JrOiBzdHJpbmc7XG4gIC8qKiBQcmVmaXggbGVuZ3RoIChlLmcuLCA4KSAqL1xuICByZWFkb25seSBwcmVmaXg6IG51bWJlcjtcbiAgLyoqIEZpcnN0IHVzYWJsZSBJUCBhZGRyZXNzICovXG4gIHJlYWRvbmx5IGZpcnN0SXA6IHN0cmluZztcbiAgLyoqIExhc3QgdXNhYmxlIElQIGFkZHJlc3MgKi9cbiAgcmVhZG9ubHkgbGFzdElwOiBzdHJpbmc7XG4gIC8qKiBUb3RhbCBudW1iZXIgb2YgYWRkcmVzc2VzIGluIHRoZSByYW5nZSAqL1xuICByZWFkb25seSB0b3RhbEFkZHJlc3NlczogbnVtYmVyO1xuICAvKiogTmV0d29yayBtYXNrIChlLmcuLCBcIjI1NS4wLjAuMFwiKSAqL1xuICByZWFkb25seSBuZXRtYXNrOiBzdHJpbmc7XG59XG5cbmNvbnN0IElQVjRfUkVHRVggPSAvXihcXGR7MSwzfSlcXC4oXFxkezEsM30pXFwuKFxcZHsxLDN9KVxcLihcXGR7MSwzfSlcXC8oXFxkezEsMn0pJC87XG5cbi8vIFJGQyAxOTE4IHByaXZhdGUgSVAgcmFuZ2VzXG5jb25zdCBQUklWQVRFX1JBTkdFUyA9IFtcbiAgeyBzdGFydDogXCIxMC4wLjAuMFwiLCBlbmQ6IFwiMTAuMjU1LjI1NS4yNTVcIiwgY2lkcjogXCIxMC4wLjAuMC84XCIgfSxcbiAgeyBzdGFydDogXCIxNzIuMTYuMC4wXCIsIGVuZDogXCIxNzIuMzEuMjU1LjI1NVwiLCBjaWRyOiBcIjE3Mi4xNi4wLjAvMTJcIiB9LFxuICB7IHN0YXJ0OiBcIjE5Mi4xNjguMC4wXCIsIGVuZDogXCIxOTIuMTY4LjI1NS4yNTVcIiwgY2lkcjogXCIxOTIuMTY4LjAuMC8xNlwiIH0sXG5dO1xuXG4vKipcbiAqIFZhbGlkYXRlcyBpZiBhIHN0cmluZyBpcyBhIHZhbGlkIENJRFIgbm90YXRpb25cbiAqXG4gKiBAcGFyYW0gY2lkciAtIENJRFIgc3RyaW5nIChlLmcuLCBcIjEwLjAuMC4wLzE2XCIpXG4gKiBAcmV0dXJucyBib29sZWFuIC0gdHJ1ZSBpZiB2YWxpZCBDSURSIGZvcm1hdFxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCB2YWxpZCA9IGlzVmFsaWRDaWRyKFwiMTAuMC4wLjAvMTZcIik7XG4gKiBjb25zb2xlLmxvZyh2YWxpZCk7IC8vIHRydWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRDaWRyKGNpZHI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCByZXN1bHQgPSB2YWxpZGF0ZUNpZHIoY2lkcik7XG4gIHJldHVybiByZXN1bHQudmFsaWQ7XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIGlmIENJRFIgaXMgd2l0aGluIGFsbG93ZWQgcHJpdmF0ZSByYW5nZXMgKFJGQyAxOTE4KVxuICpcbiAqIEBwYXJhbSBjaWRyIC0gQ0lEUiBzdHJpbmdcbiAqIEByZXR1cm5zIGJvb2xlYW4gLSB0cnVlIGlmIHdpdGhpbiBwcml2YXRlIElQIHJhbmdlXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGlzUHJpdmF0ZSA9IGlzUHJpdmF0ZVJhbmdlKFwiMTAuMC4wLjAvMTZcIik7XG4gKiBjb25zb2xlLmxvZyhpc1ByaXZhdGUpOyAvLyB0cnVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ByaXZhdGVSYW5nZShjaWRyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKCFpc1ZhbGlkQ2lkcihjaWRyKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHBhcnNlZCA9IHBhcnNlQ2lkcihjaWRyKTtcbiAgY29uc3Qgc3RhcnROdW0gPSBpcFRvTnVtYmVyKHBhcnNlZC5maXJzdElwKTtcbiAgY29uc3QgZW5kTnVtID0gaXBUb051bWJlcihwYXJzZWQubGFzdElwKTtcblxuICAvLyBDaGVjayBpZiB0aGUgZW50aXJlIENJRFIgcmFuZ2UgZmFsbHMgd2l0aGluIGFueSBwcml2YXRlIHJhbmdlXG4gIHJldHVybiBQUklWQVRFX1JBTkdFUy5zb21lKChyYW5nZSkgPT4ge1xuICAgIGNvbnN0IHJhbmdlU3RhcnQgPSBpcFRvTnVtYmVyKHJhbmdlLnN0YXJ0KTtcbiAgICBjb25zdCByYW5nZUVuZCA9IGlwVG9OdW1iZXIocmFuZ2UuZW5kKTtcbiAgICByZXR1cm4gc3RhcnROdW0gPj0gcmFuZ2VTdGFydCAmJiBlbmROdW0gPD0gcmFuZ2VFbmQ7XG4gIH0pO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0d28gQ0lEUiBibG9ja3Mgb3ZlcmxhcFxuICpcbiAqIEBwYXJhbSBjaWRyMSAtIEZpcnN0IENJRFJcbiAqIEBwYXJhbSBjaWRyMiAtIFNlY29uZCBDSURSXG4gKiBAcmV0dXJucyBib29sZWFuIC0gdHJ1ZSBpZiBDSURScyBvdmVybGFwXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG92ZXJsYXAgPSBjaWRyc092ZXJsYXAoXCIxMC4wLjAuMC84XCIsIFwiMTAuMS4wLjAvMTZcIik7XG4gKiBjb25zb2xlLmxvZyhvdmVybGFwKTsgLy8gdHJ1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gY2lkcnNPdmVybGFwKGNpZHIxOiBzdHJpbmcsIGNpZHIyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGNoZWNrT3ZlcmxhcChjaWRyMSwgY2lkcjIpO1xufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBpZiBjaGlsZCBDSURSIGlzIGNvbnRhaW5lZCB3aXRoaW4gcGFyZW50IENJRFJcbiAqXG4gKiBAcGFyYW0gY2hpbGRDaWRyIC0gQ2hpbGQgQ0lEUiBibG9ja1xuICogQHBhcmFtIHBhcmVudENpZHIgLSBQYXJlbnQgQ0lEUiBibG9ja1xuICogQHJldHVybnMgYm9vbGVhbiAtIHRydWUgaWYgY2hpbGQgaXMgc3VibmV0IG9mIHBhcmVudFxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBpc1N1Ym5ldCA9IGlzU3VibmV0KFwiMTAuMS4wLjAvMTZcIiwgXCIxMC4wLjAuMC84XCIpO1xuICogY29uc29sZS5sb2coaXNTdWJuZXQpOyAvLyB0cnVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N1Ym5ldChjaGlsZENpZHI6IHN0cmluZywgcGFyZW50Q2lkcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBpc0NvbnRhaW5lZChwYXJlbnRDaWRyLCBjaGlsZENpZHIpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgbnVtYmVyIG9mIElQIGFkZHJlc3NlcyBpbiBhIENJRFIgYmxvY2tcbiAqXG4gKiBAcGFyYW0gY2lkciAtIENJRFIgc3RyaW5nXG4gKiBAcmV0dXJucyBudW1iZXIgLSBUb3RhbCBJUCBhZGRyZXNzZXMgaW4gdGhlIGJsb2NrXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGNvdW50ID0gY2FsY3VsYXRlQWRkcmVzc0NvdW50KFwiMTAuMC4wLjAvMjRcIik7XG4gKiBjb25zb2xlLmxvZyhjb3VudCk7IC8vIDI1NlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlQWRkcmVzc0NvdW50KGNpZHI6IHN0cmluZyk6IG51bWJlciB7XG4gIGNvbnN0IHBhcnNlZCA9IHBhcnNlQ2lkcihjaWRyKTtcbiAgcmV0dXJuIHBhcnNlZC50b3RhbEFkZHJlc3Nlcztcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgcHJlZml4IGxlbmd0aCBpcyB3aXRoaW4gYWxsb3dlZCByYW5nZVxuICpcbiAqIEBwYXJhbSBjaWRyIC0gQ0lEUiBzdHJpbmdcbiAqIEBwYXJhbSBtaW5QcmVmaXggLSBNaW5pbXVtIGFsbG93ZWQgcHJlZml4IChlLmcuLCA4KVxuICogQHBhcmFtIG1heFByZWZpeCAtIE1heGltdW0gYWxsb3dlZCBwcmVmaXggKGUuZy4sIDI5KVxuICogQHJldHVybnMgYm9vbGVhbiAtIHRydWUgaWYgcHJlZml4IGxlbmd0aCBpcyB3aXRoaW4gcmFuZ2VcbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgdmFsaWQgPSBpc1ZhbGlkUHJlZml4TGVuZ3RoKFwiMTAuMC4wLjAvMjRcIiwgOCwgMjkpO1xuICogY29uc29sZS5sb2codmFsaWQpOyAvLyB0cnVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkUHJlZml4TGVuZ3RoKFxuICBjaWRyOiBzdHJpbmcsXG4gIG1pblByZWZpeDogbnVtYmVyLFxuICBtYXhQcmVmaXg6IG51bWJlcixcbik6IGJvb2xlYW4ge1xuICBpZiAoIWlzVmFsaWRDaWRyKGNpZHIpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgcGFyc2VkID0gcGFyc2VDaWRyKGNpZHIpO1xuICByZXR1cm4gcGFyc2VkLnByZWZpeCA+PSBtaW5QcmVmaXggJiYgcGFyc2VkLnByZWZpeCA8PSBtYXhQcmVmaXg7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgQ0lEUiBmb3JtYXQgYW5kIHN0cnVjdHVyZVxuICpcbiAqIEBwYXJhbSBjaWRyIC0gQ0lEUiBub3RhdGlvbiBzdHJpbmcgKGUuZy4sIFwiMTAuMC4wLjAvOFwiKVxuICogQHJldHVybnMgVmFsaWRhdGlvbiByZXN1bHQgd2l0aCBlcnJvcnMgYW5kIHdhcm5pbmdzXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHJlc3VsdCA9IHZhbGlkYXRlQ2lkcihcIjEwLjAuMC4wLzhcIik7XG4gKiBpZiAoIXJlc3VsdC52YWxpZCkge1xuICogICBjb25zb2xlLmVycm9yKFwiSW52YWxpZCBDSURSOlwiLCByZXN1bHQuZXJyb3JzKTtcbiAqIH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQ2lkcihjaWRyOiBzdHJpbmcpOiBDaWRyVmFsaWRhdGlvblJlc3VsdCB7XG4gIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgd2FybmluZ3M6IHN0cmluZ1tdID0gW107XG5cbiAgaWYgKCFjaWRyIHx8IHR5cGVvZiBjaWRyICE9PSBcInN0cmluZ1wiKSB7XG4gICAgZXJyb3JzLnB1c2goXCJDSURSIG11c3QgYmUgYSBub24tZW1wdHkgc3RyaW5nXCIpO1xuICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSwgZXJyb3JzLCB3YXJuaW5ncyB9O1xuICB9XG5cbiAgY29uc3QgbWF0Y2ggPSBjaWRyLm1hdGNoKElQVjRfUkVHRVgpO1xuICBpZiAoIW1hdGNoKSB7XG4gICAgZXJyb3JzLnB1c2goYEludmFsaWQgQ0lEUiBmb3JtYXQ6ICR7Y2lkcn0uIEV4cGVjdGVkIGZvcm1hdDogeC54LngueC95YCk7XG4gICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlLCBlcnJvcnMsIHdhcm5pbmdzIH07XG4gIH1cblxuICBjb25zdCBbLCBvY3QxLCBvY3QyLCBvY3QzLCBvY3Q0LCBwcmVmaXhdID0gbWF0Y2g7XG4gIGNvbnN0IG9jdGV0cyA9IFtvY3QxLCBvY3QyLCBvY3QzLCBvY3Q0XS5tYXAoTnVtYmVyKTtcbiAgY29uc3QgcHJlZml4TGVuZ3RoID0gTnVtYmVyKHByZWZpeCk7XG5cbiAgLy8gVmFsaWRhdGUgb2N0ZXRzICgwLTI1NSlcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBvY3RldHMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAob2N0ZXRzW2ldIDwgMCB8fCBvY3RldHNbaV0gPiAyNTUpIHtcbiAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICBgSW52YWxpZCBvY3RldCB2YWx1ZTogJHtvY3RldHNbaV19LiBNdXN0IGJlIGJldHdlZW4gMCBhbmQgMjU1YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gVmFsaWRhdGUgcHJlZml4IGxlbmd0aCAoMC0zMilcbiAgaWYgKHByZWZpeExlbmd0aCA8IDAgfHwgcHJlZml4TGVuZ3RoID4gMzIpIHtcbiAgICBlcnJvcnMucHVzaChcbiAgICAgIGBJbnZhbGlkIHByZWZpeCBsZW5ndGg6ICR7cHJlZml4TGVuZ3RofS4gTXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDMyYCxcbiAgICApO1xuICB9XG5cbiAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlLCBlcnJvcnMsIHdhcm5pbmdzIH07XG4gIH1cblxuICAvLyBWZXJpZnkgbmV0d29yayBhZGRyZXNzIGFsaWdubWVudFxuICBjb25zdCBpcE51bSA9IGlwVG9OdW1iZXIob2N0ZXRzLmpvaW4oXCIuXCIpKTtcbiAgY29uc3QgbWFzayA9IHByZWZpeFRvTWFzayhwcmVmaXhMZW5ndGgpO1xuICBjb25zdCBuZXR3b3JrTnVtID0gaXBOdW0gJiBtYXNrO1xuXG4gIGlmIChpcE51bSAhPT0gbmV0d29ya051bSkge1xuICAgIGNvbnN0IGNvcnJlY3ROZXR3b3JrID0gbnVtYmVyVG9JcChuZXR3b3JrTnVtKTtcbiAgICB3YXJuaW5ncy5wdXNoKFxuICAgICAgYElQIGFkZHJlc3MgJHtvY3RldHMuam9pbihcIi5cIil9IGlzIG5vdCBhbGlnbmVkIHRvIG5ldHdvcmsgYm91bmRhcnkuIGAgK1xuICAgICAgICBgTmV0d29yayBhZGRyZXNzIHNob3VsZCBiZSAke2NvcnJlY3ROZXR3b3JrfS8ke3ByZWZpeExlbmd0aH1gLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4geyB2YWxpZDogZXJyb3JzLmxlbmd0aCA9PT0gMCwgZXJyb3JzLCB3YXJuaW5ncyB9O1xufVxuXG4vKipcbiAqIFBhcnNlIENJRFIgaW50byBzdHJ1Y3R1cmVkIGluZm9ybWF0aW9uXG4gKlxuICogQHBhcmFtIGNpZHIgLSBDSURSIG5vdGF0aW9uIHN0cmluZ1xuICogQHJldHVybnMgUGFyc2VkIENJRFIgaW5mb3JtYXRpb25cbiAqIEB0aHJvd3MgRXJyb3IgaWYgQ0lEUiBmb3JtYXQgaXMgaW52YWxpZFxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBwYXJzZWQgPSBwYXJzZUNpZHIoXCIxMC4wLjAuMC84XCIpO1xuICogY29uc29sZS5sb2coYE5ldHdvcms6ICR7cGFyc2VkLm5ldHdvcmt9LCBQcmVmaXg6ICR7cGFyc2VkLnByZWZpeH1gKTtcbiAqIGNvbnNvbGUubG9nKGBSYW5nZTogJHtwYXJzZWQuZmlyc3RJcH0gLSAke3BhcnNlZC5sYXN0SXB9YCk7XG4gKiBjb25zb2xlLmxvZyhgVG90YWwgYWRkcmVzc2VzOiAke3BhcnNlZC50b3RhbEFkZHJlc3Nlc31gKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQ2lkcihjaWRyOiBzdHJpbmcpOiBQYXJzZWRDaWRyIHtcbiAgY29uc3QgdmFsaWRhdGlvbiA9IHZhbGlkYXRlQ2lkcihjaWRyKTtcbiAgaWYgKCF2YWxpZGF0aW9uLnZhbGlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIENJRFI6ICR7dmFsaWRhdGlvbi5lcnJvcnMuam9pbihcIiwgXCIpfWApO1xuICB9XG5cbiAgY29uc3QgbWF0Y2ggPSBjaWRyLm1hdGNoKElQVjRfUkVHRVgpITtcbiAgY29uc3QgWywgb2N0MSwgb2N0Miwgb2N0Mywgb2N0NCwgcHJlZml4XSA9IG1hdGNoO1xuICBjb25zdCBpcEFkZHJlc3MgPSBgJHtvY3QxfS4ke29jdDJ9LiR7b2N0M30uJHtvY3Q0fWA7XG4gIGNvbnN0IHByZWZpeExlbmd0aCA9IE51bWJlcihwcmVmaXgpO1xuXG4gIGNvbnN0IGlwTnVtID0gaXBUb051bWJlcihpcEFkZHJlc3MpO1xuICBjb25zdCBtYXNrID0gcHJlZml4VG9NYXNrKHByZWZpeExlbmd0aCk7XG4gIGNvbnN0IG5ldHdvcmtOdW0gPSBpcE51bSAmIG1hc2s7XG4gIGNvbnN0IGJyb2FkY2FzdE51bSA9IG5ldHdvcmtOdW0gfCAofm1hc2sgPj4+IDApO1xuXG4gIGNvbnN0IHRvdGFsQWRkcmVzc2VzID0gTWF0aC5wb3coMiwgMzIgLSBwcmVmaXhMZW5ndGgpO1xuICBjb25zdCBmaXJzdElwTnVtID0gbmV0d29ya051bTtcbiAgY29uc3QgbGFzdElwTnVtID0gYnJvYWRjYXN0TnVtO1xuXG4gIHJldHVybiB7XG4gICAgY2lkcixcbiAgICBuZXR3b3JrOiBudW1iZXJUb0lwKG5ldHdvcmtOdW0pLFxuICAgIHByZWZpeDogcHJlZml4TGVuZ3RoLFxuICAgIGZpcnN0SXA6IG51bWJlclRvSXAoZmlyc3RJcE51bSksXG4gICAgbGFzdElwOiBudW1iZXJUb0lwKGxhc3RJcE51bSksXG4gICAgdG90YWxBZGRyZXNzZXMsXG4gICAgbmV0bWFzazogbnVtYmVyVG9JcChtYXNrKSxcbiAgfTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB0d28gQ0lEUnMgb3ZlcmxhcFxuICpcbiAqIEBwYXJhbSBjaWRyMSAtIEZpcnN0IENJRFIgYmxvY2tcbiAqIEBwYXJhbSBjaWRyMiAtIFNlY29uZCBDSURSIGJsb2NrXG4gKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBDSURScyBvdmVybGFwXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG92ZXJsYXBzID0gY2hlY2tPdmVybGFwKFwiMTAuMC4wLjAvMTZcIiwgXCIxMC4wLjEuMC8yNFwiKTtcbiAqIGNvbnNvbGUubG9nKG92ZXJsYXBzKTsgLy8gdHJ1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tPdmVybGFwKGNpZHIxOiBzdHJpbmcsIGNpZHIyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgcGFyc2VkMSA9IHBhcnNlQ2lkcihjaWRyMSk7XG4gIGNvbnN0IHBhcnNlZDIgPSBwYXJzZUNpZHIoY2lkcjIpO1xuXG4gIGNvbnN0IHN0YXJ0MSA9IGlwVG9OdW1iZXIocGFyc2VkMS5maXJzdElwKTtcbiAgY29uc3QgZW5kMSA9IGlwVG9OdW1iZXIocGFyc2VkMS5sYXN0SXApO1xuICBjb25zdCBzdGFydDIgPSBpcFRvTnVtYmVyKHBhcnNlZDIuZmlyc3RJcCk7XG4gIGNvbnN0IGVuZDIgPSBpcFRvTnVtYmVyKHBhcnNlZDIubGFzdElwKTtcblxuICAvLyBDaGVjayBpZiByYW5nZXMgb3ZlcmxhcFxuICByZXR1cm4gIShlbmQxIDwgc3RhcnQyIHx8IGVuZDIgPCBzdGFydDEpO1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIHRoYXQgbXVsdGlwbGUgQ0lEUnMgZG9uJ3Qgb3ZlcmxhcFxuICpcbiAqIEBwYXJhbSBjaWRycyAtIEFycmF5IG9mIENJRFIgYmxvY2tzIHRvIGNoZWNrXG4gKiBAcmV0dXJucyBWYWxpZGF0aW9uIHJlc3VsdCB3aXRoIGRldGFpbHMgb2YgYW55IG92ZXJsYXBzXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHJlc3VsdCA9IHZhbGlkYXRlTm9PdmVybGFwcyhbXG4gKiAgIFwiMTAuMC4wLjAvMTZcIixcbiAqICAgXCIxMC4xLjAuMC8xNlwiLFxuICogICBcIjEwLjAuMS4wLzI0XCJcbiAqIF0pO1xuICogaWYgKCFyZXN1bHQudmFsaWQpIHtcbiAqICAgY29uc29sZS5lcnJvcihcIk92ZXJsYXBwaW5nIENJRFJzOlwiLCByZXN1bHQuZXJyb3JzKTtcbiAqIH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlTm9PdmVybGFwcyhjaWRyczogc3RyaW5nW10pOiBDaWRyVmFsaWRhdGlvblJlc3VsdCB7XG4gIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgd2FybmluZ3M6IHN0cmluZ1tdID0gW107XG5cbiAgLy8gRmlyc3QgdmFsaWRhdGUgZWFjaCBDSURSIGluZGl2aWR1YWxseVxuICBmb3IgKGNvbnN0IGNpZHIgb2YgY2lkcnMpIHtcbiAgICBjb25zdCB2YWxpZGF0aW9uID0gdmFsaWRhdGVDaWRyKGNpZHIpO1xuICAgIGlmICghdmFsaWRhdGlvbi52YWxpZCkge1xuICAgICAgZXJyb3JzLnB1c2goYEludmFsaWQgQ0lEUiAke2NpZHJ9OiAke3ZhbGlkYXRpb24uZXJyb3JzLmpvaW4oXCIsIFwiKX1gKTtcbiAgICB9XG4gIH1cblxuICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4geyB2YWxpZDogZmFsc2UsIGVycm9ycywgd2FybmluZ3MgfTtcbiAgfVxuXG4gIC8vIENoZWNrIGZvciBvdmVybGFwc1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGNpZHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgY2lkcnMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGlmIChjaGVja092ZXJsYXAoY2lkcnNbaV0sIGNpZHJzW2pdKSkge1xuICAgICAgICBlcnJvcnMucHVzaChgQ0lEUnMgb3ZlcmxhcDogJHtjaWRyc1tpXX0gYW5kICR7Y2lkcnNbal19YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgdmFsaWQ6IGVycm9ycy5sZW5ndGggPT09IDAsIGVycm9ycywgd2FybmluZ3MgfTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhIGNoaWxkIENJRFIgaXMgY29udGFpbmVkIHdpdGhpbiBhIHBhcmVudCBDSURSXG4gKlxuICogQHBhcmFtIHBhcmVudENpZHIgLSBQYXJlbnQgQ0lEUiBibG9ja1xuICogQHBhcmFtIGNoaWxkQ2lkciAtIENoaWxkIENJRFIgYmxvY2sgdG8gY2hlY2tcbiAqIEByZXR1cm5zIFRydWUgaWYgY2hpbGQgaXMgZnVsbHkgY29udGFpbmVkIGluIHBhcmVudFxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBjb250YWluZWQgPSBpc0NvbnRhaW5lZChcIjEwLjAuMC4wLzE2XCIsIFwiMTAuMC4xLjAvMjRcIik7XG4gKiBjb25zb2xlLmxvZyhjb250YWluZWQpOyAvLyB0cnVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbnRhaW5lZChwYXJlbnRDaWRyOiBzdHJpbmcsIGNoaWxkQ2lkcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IHBhcmVudCA9IHBhcnNlQ2lkcihwYXJlbnRDaWRyKTtcbiAgY29uc3QgY2hpbGQgPSBwYXJzZUNpZHIoY2hpbGRDaWRyKTtcblxuICBjb25zdCBwYXJlbnRTdGFydCA9IGlwVG9OdW1iZXIocGFyZW50LmZpcnN0SXApO1xuICBjb25zdCBwYXJlbnRFbmQgPSBpcFRvTnVtYmVyKHBhcmVudC5sYXN0SXApO1xuICBjb25zdCBjaGlsZFN0YXJ0ID0gaXBUb051bWJlcihjaGlsZC5maXJzdElwKTtcbiAgY29uc3QgY2hpbGRFbmQgPSBpcFRvTnVtYmVyKGNoaWxkLmxhc3RJcCk7XG5cbiAgLy8gQ2hpbGQgbXVzdCBiZSBmdWxseSB3aXRoaW4gcGFyZW50IHJhbmdlXG4gIHJldHVybiBjaGlsZFN0YXJ0ID49IHBhcmVudFN0YXJ0ICYmIGNoaWxkRW5kIDw9IHBhcmVudEVuZDtcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSB0aGF0IG11bHRpcGxlIGNoaWxkIENJRFJzIGFyZSBhbGwgY29udGFpbmVkIHdpdGhpbiBhIHBhcmVudCBDSURSXG4gKlxuICogQHBhcmFtIHBhcmVudENpZHIgLSBQYXJlbnQgQ0lEUiBibG9ja1xuICogQHBhcmFtIGNoaWxkQ2lkcnMgLSBBcnJheSBvZiBjaGlsZCBDSURSIGJsb2Nrc1xuICogQHJldHVybnMgVmFsaWRhdGlvbiByZXN1bHQgd2l0aCBkZXRhaWxzIG9mIGFueSBjb250YWlubWVudCB2aW9sYXRpb25zXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHJlc3VsdCA9IHZhbGlkYXRlQ29udGFpbm1lbnQoXCIxMC4wLjAuMC8xNlwiLCBbXG4gKiAgIFwiMTAuMC4xLjAvMjRcIixcbiAqICAgXCIxMC4wLjIuMC8yNFwiXG4gKiBdKTtcbiAqIGlmICghcmVzdWx0LnZhbGlkKSB7XG4gKiAgIGNvbnNvbGUuZXJyb3IoXCJDb250YWlubWVudCB2aW9sYXRpb25zOlwiLCByZXN1bHQuZXJyb3JzKTtcbiAqIH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQ29udGFpbm1lbnQoXG4gIHBhcmVudENpZHI6IHN0cmluZyxcbiAgY2hpbGRDaWRyczogc3RyaW5nW10sXG4pOiBDaWRyVmFsaWRhdGlvblJlc3VsdCB7XG4gIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgd2FybmluZ3M6IHN0cmluZ1tdID0gW107XG5cbiAgLy8gVmFsaWRhdGUgcGFyZW50IENJRFJcbiAgY29uc3QgcGFyZW50VmFsaWRhdGlvbiA9IHZhbGlkYXRlQ2lkcihwYXJlbnRDaWRyKTtcbiAgaWYgKCFwYXJlbnRWYWxpZGF0aW9uLnZhbGlkKSB7XG4gICAgZXJyb3JzLnB1c2goXG4gICAgICBgSW52YWxpZCBwYXJlbnQgQ0lEUiAke3BhcmVudENpZHJ9OiAke3BhcmVudFZhbGlkYXRpb24uZXJyb3JzLmpvaW4oXCIsIFwiKX1gLFxuICAgICk7XG4gICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlLCBlcnJvcnMsIHdhcm5pbmdzIH07XG4gIH1cblxuICAvLyBWYWxpZGF0ZSBlYWNoIGNoaWxkIENJRFJcbiAgZm9yIChjb25zdCBjaGlsZENpZHIgb2YgY2hpbGRDaWRycykge1xuICAgIGNvbnN0IGNoaWxkVmFsaWRhdGlvbiA9IHZhbGlkYXRlQ2lkcihjaGlsZENpZHIpO1xuICAgIGlmICghY2hpbGRWYWxpZGF0aW9uLnZhbGlkKSB7XG4gICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgYEludmFsaWQgY2hpbGQgQ0lEUiAke2NoaWxkQ2lkcn06ICR7Y2hpbGRWYWxpZGF0aW9uLmVycm9ycy5qb2luKFwiLCBcIil9YCxcbiAgICAgICk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBjb250YWlubWVudFxuICAgIGlmICghaXNDb250YWluZWQocGFyZW50Q2lkciwgY2hpbGRDaWRyKSkge1xuICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgIGBDaGlsZCBDSURSICR7Y2hpbGRDaWRyfSBpcyBub3QgY29udGFpbmVkIHdpdGhpbiBwYXJlbnQgQ0lEUiAke3BhcmVudENpZHJ9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgdmFsaWQ6IGVycm9ycy5sZW5ndGggPT09IDAsIGVycm9ycywgd2FybmluZ3MgfTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGFuIElQIGFkZHJlc3Mgc3RyaW5nIHRvIGEgMzItYml0IG51bWJlclxuICpcbiAqIEBwYXJhbSBpcCAtIElQIGFkZHJlc3Mgc3RyaW5nIChlLmcuLCBcIjEwLjAuMC4xXCIpXG4gKiBAcmV0dXJucyAzMi1iaXQgbnVtYmVyIHJlcHJlc2VudGF0aW9uXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG51bSA9IGlwVG9OdW1iZXIoXCIxMC4wLjAuMVwiKTtcbiAqIGNvbnNvbGUubG9nKG51bSk7IC8vIDE2Nzc3MjE2MVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXBUb051bWJlcihpcDogc3RyaW5nKTogbnVtYmVyIHtcbiAgY29uc3Qgb2N0ZXRzID0gaXAuc3BsaXQoXCIuXCIpLm1hcChOdW1iZXIpO1xuICByZXR1cm4gKFxuICAgICgob2N0ZXRzWzBdIDw8IDI0KSA+Pj4gMCkgK1xuICAgICgob2N0ZXRzWzFdIDw8IDE2KSA+Pj4gMCkgK1xuICAgICgob2N0ZXRzWzJdIDw8IDgpID4+PiAwKSArXG4gICAgb2N0ZXRzWzNdXG4gICk7XG59XG5cbi8qKlxuICogQ29udmVydCBhIDMyLWJpdCBudW1iZXIgdG8gYW4gSVAgYWRkcmVzcyBzdHJpbmdcbiAqXG4gKiBAcGFyYW0gbnVtIC0gMzItYml0IG51bWJlciByZXByZXNlbnRhdGlvblxuICogQHJldHVybnMgSVAgYWRkcmVzcyBzdHJpbmdcbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgaXAgPSBudW1iZXJUb0lwKDE2Nzc3MjE2MSk7XG4gKiBjb25zb2xlLmxvZyhpcCk7IC8vIFwiMTAuMC4wLjFcIlxuICovXG5leHBvcnQgZnVuY3Rpb24gbnVtYmVyVG9JcChudW06IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBbXG4gICAgKG51bSA+Pj4gMjQpICYgMHhmZixcbiAgICAobnVtID4+PiAxNikgJiAweGZmLFxuICAgIChudW0gPj4+IDgpICYgMHhmZixcbiAgICBudW0gJiAweGZmLFxuICBdLmpvaW4oXCIuXCIpO1xufVxuXG4vKipcbiAqIENvbnZlcnQgYSBwcmVmaXggbGVuZ3RoIHRvIGEgbmV0bWFzayBudW1iZXJcbiAqXG4gKiBAcGFyYW0gcHJlZml4IC0gUHJlZml4IGxlbmd0aCAoMC0zMilcbiAqIEByZXR1cm5zIDMyLWJpdCBuZXRtYXNrIG51bWJlclxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtYXNrID0gcHJlZml4VG9NYXNrKDI0KTtcbiAqIGNvbnN0IG1hc2tJcCA9IG51bWJlclRvSXAobWFzayk7XG4gKiBjb25zb2xlLmxvZyhtYXNrSXApOyAvLyBcIjI1NS4yNTUuMjU1LjBcIlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJlZml4VG9NYXNrKHByZWZpeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIHByZWZpeCA9PT0gMCA/IDAgOiAoMHhmZmZmZmZmZiA8PCAoMzIgLSBwcmVmaXgpKSA+Pj4gMDtcbn1cbiJdfQ==
@@ -21,6 +21,7 @@ import * as cdktf from "cdktf";
21
21
  import { Construct } from "constructs";
22
22
  import { ConnectivityConfiguration } from "./connectivity-configuration";
23
23
  import { ConnectivityGroupItem, Hub } from "./connectivity-configuration-schemas";
24
+ import { IpamPool } from "./ipam-pool";
24
25
  import { NetworkGroup } from "./network-group";
25
26
  import { SecurityAdminConfiguration } from "./security-admin-configuration";
26
27
  import { AzapiResource, AzapiResourceProps } from "../../core-azure/lib/azapi/azapi-resource";
@@ -165,6 +166,40 @@ export interface AddSecurityAdminConfigurationProps extends AzapiResourceProps {
165
166
  */
166
167
  readonly ignoreChanges?: string[];
167
168
  }
169
+ /**
170
+ * Properties for adding an IpamPool via the convenience method
171
+ * This interface excludes networkManagerId as it's automatically set
172
+ */
173
+ export interface AddIpamPoolProps extends AzapiResourceProps {
174
+ /**
175
+ * IP address prefixes for the pool
176
+ * Must be valid CIDR notation (e.g., "10.0.0.0/8")
177
+ * Multiple prefixes must not overlap
178
+ * @example ["10.0.0.0/8", "172.16.0.0/12"]
179
+ */
180
+ readonly addressPrefixes: string[];
181
+ /**
182
+ * Optional description of the IPAM pool
183
+ * @example "Production IP address pool for East US region"
184
+ */
185
+ readonly description?: string;
186
+ /**
187
+ * Optional friendly display name
188
+ * @example "East US Production Pool"
189
+ */
190
+ readonly displayName?: string;
191
+ /**
192
+ * Name of parent pool for hierarchical pools
193
+ * Leave empty/undefined for root pools
194
+ * @example "root-pool"
195
+ */
196
+ readonly parentPoolName?: string;
197
+ /**
198
+ * The lifecycle rules to ignore changes
199
+ * @example ["tags"]
200
+ */
201
+ readonly ignoreChanges?: string[];
202
+ }
168
203
  /**
169
204
  * Properties for Virtual Network Manager body
170
205
  */
@@ -330,6 +365,27 @@ export declare class VirtualNetworkManager extends AzapiResource {
330
365
  * });
331
366
  */
332
367
  addSecurityAdminConfiguration(id: string, props: AddSecurityAdminConfigurationProps): SecurityAdminConfiguration;
368
+ /**
369
+ * Convenience method to create an IpamPool
370
+ *
371
+ * This is a helper method that creates an IpamPool with the networkManagerId
372
+ * automatically set to this Network Manager's ID. You can also create IpamPools
373
+ * directly using: new IpamPool(scope, id, { networkManagerId: vnm.id, ...props })
374
+ *
375
+ * @param id - The unique identifier for the IPAM pool construct
376
+ * @param props - IpamPool properties (networkManagerId will be set automatically)
377
+ * @returns The created IpamPool instance
378
+ *
379
+ * @example
380
+ * const ipamPool = networkManager.addIpamPool("prod-pool", {
381
+ * name: "production-pool",
382
+ * location: "eastus",
383
+ * addressPrefixes: ["10.0.0.0/8"],
384
+ * description: "Production IP address pool",
385
+ * displayName: "Production Pool"
386
+ * });
387
+ */
388
+ addIpamPool(id: string, props: AddIpamPoolProps): IpamPool;
333
389
  /**
334
390
  * Applies ignore changes lifecycle rules if specified in props
335
391
  */