@oneuptime/common 12.0.14 → 12.0.15
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.
- package/Models/DatabaseModels/GlobalOidc.ts +20 -0
- package/Models/DatabaseModels/GlobalSso.ts +20 -0
- package/Models/DatabaseModels/MarketingConversion.ts +19 -9
- package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +46 -0
- package/Models/DatabaseModels/StatusPage.ts +7 -4
- package/Server/API/StatusPageAPI.ts +29 -4
- package/Server/EnvironmentConfig.ts +7 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.ts +19 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.ts +40 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Middleware/SlackAuthorization.ts +43 -6
- package/Server/Middleware/UserAuthorization.ts +236 -26
- package/Server/Middleware/WhatsAppAuthorization.ts +43 -3
- package/Server/Services/GlobalOidcProjectService.ts +126 -1
- package/Server/Services/GlobalOidcService.ts +132 -0
- package/Server/Services/GlobalSsoProjectService.ts +126 -1
- package/Server/Services/GlobalSsoService.ts +132 -0
- package/Server/Services/UserEmailService.ts +4 -4
- package/Server/Utils/CronTab.ts +73 -0
- package/Server/Utils/GlobalSsoAuthorization.ts +175 -0
- package/Server/Utils/Marketing/ConversionUploadProvider.ts +35 -5
- package/Server/Utils/Marketing/Providers/GoogleAds.ts +1 -1
- package/Server/Utils/Marketing/Providers/LinkedIn.ts +1 -1
- package/Server/Utils/Marketing/Providers/Meta.ts +1 -1
- package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +1 -1
- package/Server/Utils/Marketing/Providers/Reddit.ts +1 -1
- package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +48 -33
- package/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.ts +35 -30
- package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +33 -28
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +475 -47
- package/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.ts +35 -30
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +34 -28
- package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +33 -28
- package/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.ts +69 -40
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +35 -29
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +8 -0
- package/Server/Utils/Monitor/MonitorResource.ts +161 -21
- package/Server/Utils/StatusPageContentSecurityPolicy.ts +56 -0
- package/Server/Utils/StatusPageCustomizationAccess.ts +117 -0
- package/Tests/Server/API/StatusPageCustomizationOrigin.test.ts +348 -0
- package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +9 -59
- package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +227 -0
- package/Tests/Server/Middleware/SlackAuthorization.test.ts +149 -0
- package/Tests/Server/Middleware/UserAuthorization.test.ts +27 -13
- package/Tests/Server/Middleware/UserAuthorizationGlobalSsoGovernance.test.ts +1455 -0
- package/Tests/Server/Middleware/UserAuthorizationSSOProvider.test.ts +91 -2
- package/Tests/Server/Middleware/WhatsAppAuthorization.test.ts +233 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +21 -8
- package/Tests/Server/Services/GlobalSsoProviderAuthorization.test.ts +1242 -0
- package/Tests/Server/Services/MonitorResourceProbeAgreementHydration.test.ts +459 -0
- package/Tests/Server/Services/MonitorResourceProbeAgreementReuse.test.ts +10 -0
- package/Tests/Server/Types/AnalyticsDatabase/AggregateUtilBucketTimestamp.test.ts +416 -0
- package/Tests/Server/Types/Database/QueryHelperManyToManyAndEmptyValues.test.ts +551 -0
- package/Tests/Server/Types/Database/SelectUtil.test.ts +348 -0
- package/Tests/Server/Utils/CronTab.test.ts +116 -0
- package/Tests/Server/Utils/GlobalSSOToken.test.ts +581 -0
- package/Tests/Server/Utils/GlobalSsoAuthorization.test.ts +1401 -0
- package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +254 -0
- package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +1 -1
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaEvaluateOverTime.test.ts +508 -0
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +30 -9
- package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +987 -0
- package/Tests/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.test.ts +916 -0
- package/Tests/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.test.ts +382 -0
- package/Tests/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.test.ts +1219 -0
- package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +86 -0
- package/Tests/Server/Utils/StatusPageContentSecurityPolicy.test.ts +136 -0
- package/Tests/Server/Utils/StatusPageCustomizationAccess.test.ts +223 -0
- package/Tests/Types/Monitor/MonitorStepConfigHelpers.test.ts +165 -0
- package/Tests/Types/NetworkDevice/NetworkDeviceLinkRuleScope.test.ts +215 -0
- package/Tests/UI/Components/Forms/FormSubmitAnalytics.test.tsx +206 -0
- package/Tests/UI/Utils/AIChatExport/ConversationMarkdown.test.ts +774 -0
- package/Tests/UI/Utils/AIChatExport/MarkdownBlocks.test.ts +791 -0
- package/Tests/UI/Utils/AIChatExport/MarkdownSafety.test.ts +544 -0
- package/Tests/Utils/Analytics.test.ts +187 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +80 -0
- package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +1291 -0
- package/Tests/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.test.ts +214 -0
- package/Types/Marketing/MarketingConversion.ts +12 -0
- package/Types/Monitor/CriteriaFilter.ts +9 -0
- package/Types/NetworkDevice/NetworkDeviceLinkRuleScope.ts +51 -0
- package/UI/Components/FormModal/BasicFormModal.tsx +12 -0
- package/UI/Components/Forms/BasicForm.tsx +13 -1
- package/UI/Components/Forms/BasicModelForm.tsx +2 -1
- package/UI/Components/Forms/ModelForm.tsx +10 -1
- package/UI/Components/Forms/Utils/FormAnalyticsName.ts +39 -0
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +6 -1
- package/Utils/Analytics.ts +55 -2
- package/Utils/Monitor/MonitorMetricType.ts +40 -0
- package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +587 -37
- package/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.ts +115 -0
- package/build/dist/Models/DatabaseModels/GlobalOidc.js +21 -0
- package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSso.js +21 -0
- package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MarketingConversion.js +20 -10
- package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +47 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +4 -4
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +25 -4
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +6 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js +29 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/SlackAuthorization.js +28 -4
- package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +197 -22
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/WhatsAppAuthorization.js +32 -2
- package/build/dist/Server/Middleware/WhatsAppAuthorization.js.map +1 -1
- package/build/dist/Server/Services/GlobalOidcProjectService.js +105 -0
- package/build/dist/Server/Services/GlobalOidcProjectService.js.map +1 -1
- package/build/dist/Server/Services/GlobalOidcService.js +127 -0
- package/build/dist/Server/Services/GlobalOidcService.js.map +1 -1
- package/build/dist/Server/Services/GlobalSsoProjectService.js +105 -0
- package/build/dist/Server/Services/GlobalSsoProjectService.js.map +1 -1
- package/build/dist/Server/Services/GlobalSsoService.js +127 -0
- package/build/dist/Server/Services/GlobalSsoService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +4 -4
- package/build/dist/Server/Utils/CronTab.js +66 -0
- package/build/dist/Server/Utils/CronTab.js.map +1 -1
- package/build/dist/Server/Utils/GlobalSsoAuthorization.js +112 -0
- package/build/dist/Server/Utils/GlobalSsoAuthorization.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +17 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +37 -35
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +20 -22
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +370 -42
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js +64 -52
- package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +25 -29
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +8 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +123 -23
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js +39 -0
- package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js.map +1 -0
- package/build/dist/Server/Utils/StatusPageCustomizationAccess.js +85 -0
- package/build/dist/Server/Utils/StatusPageCustomizationAccess.js.map +1 -0
- package/build/dist/Types/Marketing/MarketingConversion.js +10 -0
- package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js +46 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js.map +1 -0
- package/build/dist/UI/Components/FormModal/BasicFormModal.js +2 -1
- package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +10 -1
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicModelForm.js +2 -1
- package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +4 -1
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js +33 -0
- package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js.map +1 -0
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js +2 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- package/build/dist/Utils/Analytics.js +50 -2
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +37 -0
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +318 -37
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js +87 -0
- package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,27 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* Pure data-in/data-out so the whole decision matrix — which is mostly about
|
|
5
|
-
* REFUSING to draw things — is unit-testable without a database.
|
|
6
|
-
*
|
|
7
|
-
* The shape is a star, not a clique. A rule names a set of child labels and a
|
|
8
|
-
* set of parent labels; every device carrying all the child labels gets one
|
|
9
|
-
* edge to the single device carrying all the parent labels. Matching "devices
|
|
10
|
-
* that share a label" symmetrically, which is what was originally asked for,
|
|
11
|
-
* would turn one forty-device site label into 780 edges.
|
|
12
|
-
*/
|
|
13
|
-
export default class NetworkDeviceLinkRuleUtil {
|
|
1
|
+
import { NetworkDeviceLinkRuleScopeUtil } from "../../Types/NetworkDevice/NetworkDeviceLinkRuleScope";
|
|
2
|
+
class NetworkDeviceLinkRuleUtil {
|
|
14
3
|
/*
|
|
15
4
|
* ALL of the rule's labels must be present on the device, not any. "Devices
|
|
16
5
|
* that are both an access point AND on floor 1" is the question an operator
|
|
17
6
|
* is asking; any-of would sweep in every access point in the building.
|
|
18
7
|
*/
|
|
19
|
-
static
|
|
20
|
-
const owned = new Set(device.labelIds);
|
|
8
|
+
static matches(labelSet, requiredLabelIds) {
|
|
21
9
|
return requiredLabelIds.every((labelId) => {
|
|
22
|
-
return
|
|
10
|
+
return labelSet.has(labelId);
|
|
23
11
|
});
|
|
24
12
|
}
|
|
13
|
+
static resolveGroup(rule, group) {
|
|
14
|
+
const parents = group.filter((entry) => {
|
|
15
|
+
return NetworkDeviceLinkRuleUtil.matches(entry.labelSet, rule.parentLabelIds);
|
|
16
|
+
});
|
|
17
|
+
/*
|
|
18
|
+
* Counted before the parent branch, not after: a site that failed to
|
|
19
|
+
* resolve still has to report how many devices are floating there, and
|
|
20
|
+
* that number is the operator's damage assessment.
|
|
21
|
+
*/
|
|
22
|
+
const childCandidates = group.filter((entry) => {
|
|
23
|
+
return NetworkDeviceLinkRuleUtil.matches(entry.labelSet, rule.childLabelIds);
|
|
24
|
+
});
|
|
25
|
+
const childMatchCount = childCandidates.length;
|
|
26
|
+
if (parents.length === 0) {
|
|
27
|
+
return {
|
|
28
|
+
links: [],
|
|
29
|
+
parentMatchCount: 0,
|
|
30
|
+
childMatchCount: childMatchCount,
|
|
31
|
+
failure: "noParentMatched",
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/*
|
|
35
|
+
* Two candidate parents is not a tie to break — it is a question the
|
|
36
|
+
* labels do not answer. Drawing to either one would assert a cabling
|
|
37
|
+
* fact nobody stated.
|
|
38
|
+
*/
|
|
39
|
+
if (parents.length > 1) {
|
|
40
|
+
return {
|
|
41
|
+
links: [],
|
|
42
|
+
parentMatchCount: parents.length,
|
|
43
|
+
childMatchCount: childMatchCount,
|
|
44
|
+
failure: "ambiguousParent",
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const parent = parents[0];
|
|
48
|
+
// The parent is excluded even when it matches both sets: no self-links.
|
|
49
|
+
const children = childCandidates.filter((entry) => {
|
|
50
|
+
return entry.device.id !== parent.device.id;
|
|
51
|
+
});
|
|
52
|
+
if (children.length === 0) {
|
|
53
|
+
return {
|
|
54
|
+
links: [],
|
|
55
|
+
parentMatchCount: 1,
|
|
56
|
+
childMatchCount: childMatchCount,
|
|
57
|
+
failure: "noChildrenMatched",
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
links: children.map((child) => {
|
|
62
|
+
return { fromDeviceId: child.device.id, toDeviceId: parent.device.id };
|
|
63
|
+
}),
|
|
64
|
+
parentMatchCount: 1,
|
|
65
|
+
childMatchCount: childMatchCount,
|
|
66
|
+
failure: null,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
25
69
|
static resolveRule(rule, devices) {
|
|
26
70
|
const empty = (reason, parents = 0, children = 0) => {
|
|
27
71
|
return {
|
|
@@ -33,6 +77,13 @@ export default class NetworkDeviceLinkRuleUtil {
|
|
|
33
77
|
matchedChildCount: children,
|
|
34
78
|
};
|
|
35
79
|
};
|
|
80
|
+
/*
|
|
81
|
+
* The three checks below are properties of the rule's TEXT, true in every
|
|
82
|
+
* site, so they are settled before scope is even read. A disabled rule is
|
|
83
|
+
* not "disabled in Unit 7", and partitioning a rule with an empty parent
|
|
84
|
+
* label set would make every site in the project ambiguous at once — the
|
|
85
|
+
* worst noise outcome available.
|
|
86
|
+
*/
|
|
36
87
|
if (rule.isEnabled === false) {
|
|
37
88
|
return empty("disabled");
|
|
38
89
|
}
|
|
@@ -47,38 +98,172 @@ export default class NetworkDeviceLinkRuleUtil {
|
|
|
47
98
|
if (rule.parentLabelIds.length === 0) {
|
|
48
99
|
return empty("noParentLabels");
|
|
49
100
|
}
|
|
50
|
-
const
|
|
51
|
-
return
|
|
101
|
+
const normalized = devices.map((device) => {
|
|
102
|
+
return {
|
|
103
|
+
device: device,
|
|
104
|
+
labelSet: new Set(device.labelIds),
|
|
105
|
+
siteKey: (device.siteId || "").toString().trim(),
|
|
106
|
+
};
|
|
52
107
|
});
|
|
53
|
-
if (
|
|
108
|
+
if (NetworkDeviceLinkRuleScopeUtil.isSiteScoped(rule.scope)) {
|
|
109
|
+
return NetworkDeviceLinkRuleUtil.resolvePerSite(rule, normalized);
|
|
110
|
+
}
|
|
111
|
+
return NetworkDeviceLinkRuleUtil.resolveProject(rule, normalized, empty);
|
|
112
|
+
}
|
|
113
|
+
static resolveProject(rule, normalized, empty) {
|
|
114
|
+
const result = NetworkDeviceLinkRuleUtil.resolveGroup(rule, normalized);
|
|
115
|
+
if (result.failure === "noParentMatched") {
|
|
54
116
|
return empty("noParentMatched", 0);
|
|
55
117
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
* labels do not answer. Drawing to either one would assert a cabling
|
|
59
|
-
* fact nobody stated.
|
|
60
|
-
*/
|
|
61
|
-
if (parents.length > 1) {
|
|
62
|
-
return empty("ambiguousParent", parents.length);
|
|
118
|
+
if (result.failure === "ambiguousParent") {
|
|
119
|
+
return empty("ambiguousParent", result.parentMatchCount);
|
|
63
120
|
}
|
|
64
|
-
|
|
65
|
-
const children = devices.filter((device) => {
|
|
66
|
-
// The parent is excluded even when it matches both sets: no self-links.
|
|
67
|
-
return (device.id !== parent.id &&
|
|
68
|
-
NetworkDeviceLinkRuleUtil.deviceMatches(device, rule.childLabelIds));
|
|
69
|
-
});
|
|
70
|
-
if (children.length === 0) {
|
|
121
|
+
if (result.failure === "noChildrenMatched") {
|
|
71
122
|
return empty("noChildrenMatched", 1);
|
|
72
123
|
}
|
|
73
124
|
return {
|
|
74
125
|
ruleId: rule.id,
|
|
75
126
|
ruleName: rule.name,
|
|
76
|
-
links:
|
|
77
|
-
return { fromDeviceId: child.id, toDeviceId: parent.id };
|
|
78
|
-
}),
|
|
127
|
+
links: result.links,
|
|
79
128
|
matchedParentCount: 1,
|
|
80
|
-
matchedChildCount:
|
|
129
|
+
matchedChildCount: result.links.length,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
static resolvePerSite(rule, normalized) {
|
|
133
|
+
/*
|
|
134
|
+
* Bucketed in ONE pass in first-appearance order. Never
|
|
135
|
+
* `devices.filter(...)` inside a loop over sites: that is O(devices x
|
|
136
|
+
* sites) per rule, and this endpoint runs at ten thousand devices.
|
|
137
|
+
*/
|
|
138
|
+
const buckets = new Map();
|
|
139
|
+
let unsitedChildDeviceCount = 0;
|
|
140
|
+
for (const entry of normalized) {
|
|
141
|
+
/*
|
|
142
|
+
* A device with no site is EXCLUDED, not pooled with the other unsited
|
|
143
|
+
* ones and not given a group of its own. Pooling would ask "exactly one
|
|
144
|
+
* parent among all the unsited devices", a question nobody posed, and
|
|
145
|
+
* would draw an edge between two boxes whose only relationship is that
|
|
146
|
+
* neither has been assigned a site yet. Counted instead, so the map can
|
|
147
|
+
* say how many the rule walked past.
|
|
148
|
+
*/
|
|
149
|
+
if (entry.siteKey === "") {
|
|
150
|
+
if (NetworkDeviceLinkRuleUtil.matches(entry.labelSet, rule.childLabelIds)) {
|
|
151
|
+
unsitedChildDeviceCount++;
|
|
152
|
+
}
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const bucket = buckets.get(entry.siteKey);
|
|
156
|
+
if (bucket) {
|
|
157
|
+
bucket.push(entry);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
buckets.set(entry.siteKey, [entry]);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
const links = [];
|
|
164
|
+
const groupFailures = [];
|
|
165
|
+
let applicableSiteCount = 0;
|
|
166
|
+
let matchedParentCount = 0;
|
|
167
|
+
for (const [siteId, group] of buckets) {
|
|
168
|
+
const result = NetworkDeviceLinkRuleUtil.resolveGroup(rule, group);
|
|
169
|
+
if (result.links.length > 0) {
|
|
170
|
+
applicableSiteCount++;
|
|
171
|
+
matchedParentCount += result.parentMatchCount;
|
|
172
|
+
links.push(...result.links);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
/*
|
|
176
|
+
* A site speaks only when it holds devices this rule wanted to place.
|
|
177
|
+
* Sites with nothing to place are not misconfigured — the rule simply
|
|
178
|
+
* does not apply there, and a parent label like `SubCategory:Router` is
|
|
179
|
+
* present in nearly every site by construction. Without this gate, site
|
|
180
|
+
* scoping would trade one loud failure for two hundred quiet ones and
|
|
181
|
+
* the banner would be ignored inside a week.
|
|
182
|
+
*
|
|
183
|
+
* `noChildrenMatched` lands here too: the only child candidate was the
|
|
184
|
+
* parent itself, so after the self-link exclusion there is nothing to
|
|
185
|
+
* place and nothing to report.
|
|
186
|
+
*/
|
|
187
|
+
if (result.childMatchCount === 0 ||
|
|
188
|
+
result.failure === null ||
|
|
189
|
+
result.failure === "noChildrenMatched") {
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
applicableSiteCount++;
|
|
193
|
+
matchedParentCount += result.parentMatchCount;
|
|
194
|
+
groupFailures.push({
|
|
195
|
+
siteId: siteId,
|
|
196
|
+
siteName: NetworkDeviceLinkRuleUtil.siteNameOf(group),
|
|
197
|
+
reason: result.failure,
|
|
198
|
+
matchedParentCount: result.parentMatchCount,
|
|
199
|
+
matchedChildCount: result.childMatchCount,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
const outcome = {
|
|
203
|
+
ruleId: rule.id,
|
|
204
|
+
ruleName: rule.name,
|
|
205
|
+
links: links,
|
|
206
|
+
matchedParentCount: matchedParentCount,
|
|
207
|
+
matchedChildCount: links.length,
|
|
208
|
+
applicableSiteCount: applicableSiteCount,
|
|
81
209
|
};
|
|
210
|
+
/*
|
|
211
|
+
* Keeps `links.length === 0 <=> skipReason defined` true with no gaps, so
|
|
212
|
+
* describeOutcome can never fall through to "Draws 0 uplinks" on an empty
|
|
213
|
+
* outcome. The second arm covers both an empty device list and a rule
|
|
214
|
+
* whose labels match nothing anywhere.
|
|
215
|
+
*/
|
|
216
|
+
if (links.length === 0) {
|
|
217
|
+
outcome.skipReason =
|
|
218
|
+
groupFailures.length > 0 ? "noSiteResolved" : "noChildrenMatched";
|
|
219
|
+
}
|
|
220
|
+
if (groupFailures.length > 0) {
|
|
221
|
+
outcome.groupFailures = groupFailures;
|
|
222
|
+
}
|
|
223
|
+
if (unsitedChildDeviceCount > 0) {
|
|
224
|
+
outcome.unsitedChildDeviceCount = unsitedChildDeviceCount;
|
|
225
|
+
}
|
|
226
|
+
return outcome;
|
|
227
|
+
}
|
|
228
|
+
/** First non-empty site name among a site's devices, if any of them carry one. */
|
|
229
|
+
static siteNameOf(group) {
|
|
230
|
+
for (const entry of group) {
|
|
231
|
+
if (entry.device.siteName) {
|
|
232
|
+
return entry.device.siteName;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
237
|
+
/*
|
|
238
|
+
* "Unit 4, Unit 9 and 2 more sites".
|
|
239
|
+
*
|
|
240
|
+
* Sorted before naming, and that is load-bearing rather than cosmetic: the
|
|
241
|
+
* live view refetches every sixty seconds and the device query has no ORDER
|
|
242
|
+
* BY, so an unsorted list would reshuffle the banner on every poll and read
|
|
243
|
+
* as a change that did not happen. The count stays exact even when the names
|
|
244
|
+
* are elided, so the operator always knows the true blast radius.
|
|
245
|
+
*/
|
|
246
|
+
static describeSiteList(failures) {
|
|
247
|
+
const sorted = [...failures].sort((a, b) => {
|
|
248
|
+
return ((a.siteName || "").localeCompare(b.siteName || "") ||
|
|
249
|
+
a.siteId.localeCompare(b.siteId));
|
|
250
|
+
});
|
|
251
|
+
const names = sorted
|
|
252
|
+
.slice(0, NetworkDeviceLinkRuleUtil.MAX_NAMED_SITES)
|
|
253
|
+
.map((failure) => {
|
|
254
|
+
const name = failure.siteName || NetworkDeviceLinkRuleUtil.UNNAMED_SITE;
|
|
255
|
+
return name.length > NetworkDeviceLinkRuleUtil.MAX_SITE_NAME_LENGTH
|
|
256
|
+
? `${name.slice(0, NetworkDeviceLinkRuleUtil.MAX_SITE_NAME_LENGTH - 1)}…`
|
|
257
|
+
: name;
|
|
258
|
+
});
|
|
259
|
+
const remaining = sorted.length - names.length;
|
|
260
|
+
if (remaining > 0) {
|
|
261
|
+
return `${names.join(", ")} and ${remaining} more site${remaining === 1 ? "" : "s"}`;
|
|
262
|
+
}
|
|
263
|
+
if (names.length === 1) {
|
|
264
|
+
return names[0];
|
|
265
|
+
}
|
|
266
|
+
return `${names.slice(0, -1).join(", ")} and ${names[names.length - 1]}`;
|
|
82
267
|
}
|
|
83
268
|
static resolveRules(rules, devices) {
|
|
84
269
|
return rules.map((rule) => {
|
|
@@ -100,9 +285,105 @@ export default class NetworkDeviceLinkRuleUtil {
|
|
|
100
285
|
return `${outcome.matchedParentCount} devices carry the parent labels. Exactly one must, or there is no way to tell which is the uplink.`;
|
|
101
286
|
case "noChildrenMatched":
|
|
102
287
|
return "No device carries the child labels yet.";
|
|
288
|
+
case "noSiteResolved":
|
|
289
|
+
return "No site resolved this rule.";
|
|
103
290
|
default:
|
|
104
291
|
return `Draws ${outcome.matchedChildCount} uplink${outcome.matchedChildCount === 1 ? "" : "s"}.`;
|
|
105
292
|
}
|
|
106
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* The operator-facing warning, or null when the rule needs no explanation.
|
|
296
|
+
*
|
|
297
|
+
* Singular on purpose: ONE bullet per rule, never one per site. The banner's
|
|
298
|
+
* length is then bounded by the number of rules the operator wrote — a small
|
|
299
|
+
* number they control — rather than by the number of sites in their project.
|
|
300
|
+
*
|
|
301
|
+
* This is also the only sanctioned "did this rule fail" predicate. A caller
|
|
302
|
+
* must not go back to testing `outcome.links.length === 0`, which a rule
|
|
303
|
+
* drawing thirteen of fourteen sites passes while genuinely failing.
|
|
304
|
+
*/
|
|
305
|
+
static getWarning(outcome) {
|
|
306
|
+
const failures = outcome.groupFailures || [];
|
|
307
|
+
const unsited = outcome.unsitedChildDeviceCount || 0;
|
|
308
|
+
/*
|
|
309
|
+
* Project scope always lands here, and this branch is what the topology
|
|
310
|
+
* API used to compute inline: warn iff the rule drew nothing, using
|
|
311
|
+
* describeOutcome's own words. The `!skipReason` guard makes the old
|
|
312
|
+
* code's implicit assumption explicit rather than emitting a warning with
|
|
313
|
+
* an undefined reason.
|
|
314
|
+
*/
|
|
315
|
+
if (failures.length === 0 && unsited === 0) {
|
|
316
|
+
if (outcome.links.length > 0 || !outcome.skipReason) {
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
return {
|
|
320
|
+
ruleId: outcome.ruleId,
|
|
321
|
+
ruleName: outcome.ruleName,
|
|
322
|
+
reason: outcome.skipReason,
|
|
323
|
+
message: NetworkDeviceLinkRuleUtil.describeOutcome(outcome),
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
const parts = [];
|
|
327
|
+
const applicableSiteCount = outcome.applicableSiteCount || 0;
|
|
328
|
+
if (outcome.links.length === 0) {
|
|
329
|
+
parts.push("No site resolved this rule.");
|
|
330
|
+
}
|
|
331
|
+
else if (applicableSiteCount > 1) {
|
|
332
|
+
// A single applicable site needs no coverage fraction.
|
|
333
|
+
parts.push(`Drawing in ${applicableSiteCount - failures.length} of ${applicableSiteCount} sites.`);
|
|
334
|
+
}
|
|
335
|
+
const ambiguous = failures.filter((failure) => {
|
|
336
|
+
return failure.reason === "ambiguousParent";
|
|
337
|
+
});
|
|
338
|
+
const parentless = failures.filter((failure) => {
|
|
339
|
+
return failure.reason === "noParentMatched";
|
|
340
|
+
});
|
|
341
|
+
if (ambiguous.length === 1) {
|
|
342
|
+
/*
|
|
343
|
+
* The trailing sentence deliberately echoes the project-scope wording so
|
|
344
|
+
* an operator's vocabulary does not fork between the two scopes.
|
|
345
|
+
*/
|
|
346
|
+
parts.push(`${ambiguous[0].matchedParentCount} devices carry the parent labels in ${NetworkDeviceLinkRuleUtil.describeSiteList(ambiguous)}. Exactly one must, or there is no way to tell which is the uplink.`);
|
|
347
|
+
}
|
|
348
|
+
else if (ambiguous.length > 1) {
|
|
349
|
+
parts.push(`Several devices carry the parent labels in ${NetworkDeviceLinkRuleUtil.describeSiteList(ambiguous)}. Exactly one per site must, or there is no way to tell which is the uplink.`);
|
|
350
|
+
}
|
|
351
|
+
if (parentless.length > 0) {
|
|
352
|
+
const stranded = parentless.reduce((sum, failure) => {
|
|
353
|
+
return sum + failure.matchedChildCount;
|
|
354
|
+
}, 0);
|
|
355
|
+
parts.push(`No device carries the parent labels in ${NetworkDeviceLinkRuleUtil.describeSiteList(parentless)}, so ${stranded} ${stranded === 1 ? "device" : "devices"} there ${stranded === 1 ? "has" : "have"} no uplink.`);
|
|
356
|
+
}
|
|
357
|
+
/*
|
|
358
|
+
* Always last and always its own sentence: the fix here is "assign these
|
|
359
|
+
* devices to a site", not "fix your labels", so they are never folded into
|
|
360
|
+
* a site-name list.
|
|
361
|
+
*/
|
|
362
|
+
if (unsited > 0) {
|
|
363
|
+
parts.push(`${unsited} ${unsited === 1 ? "device" : "devices"} carrying the child labels ${unsited === 1 ? "is" : "are"} not assigned to a site, so this site-scoped rule skips ${unsited === 1 ? "it" : "them"}.`);
|
|
364
|
+
}
|
|
365
|
+
return {
|
|
366
|
+
ruleId: outcome.ruleId,
|
|
367
|
+
ruleName: outcome.ruleName,
|
|
368
|
+
// Highest-ranked condition present. Ambiguity outranks a missing parent.
|
|
369
|
+
reason: ambiguous.length > 0
|
|
370
|
+
? "ambiguousParent"
|
|
371
|
+
: parentless.length > 0
|
|
372
|
+
? "noParentMatched"
|
|
373
|
+
: "devicesWithoutSite",
|
|
374
|
+
message: parts.join(" "),
|
|
375
|
+
};
|
|
376
|
+
}
|
|
107
377
|
}
|
|
378
|
+
/*
|
|
379
|
+
* Appended by the caller when the device list hit its row cap. Lives here so
|
|
380
|
+
* every operator-facing string this feature produces stays in one file.
|
|
381
|
+
*/
|
|
382
|
+
NetworkDeviceLinkRuleUtil.TRUNCATED_DEVICE_LIST_NOTE = "The device list was truncated, so some of these may be false alarms.";
|
|
383
|
+
// Three names is enough to recognise a pattern; fourteen is a wall of text.
|
|
384
|
+
NetworkDeviceLinkRuleUtil.MAX_NAMED_SITES = 3;
|
|
385
|
+
// Site names are ShortText and can run to 100 characters.
|
|
386
|
+
NetworkDeviceLinkRuleUtil.MAX_SITE_NAME_LENGTH = 40;
|
|
387
|
+
NetworkDeviceLinkRuleUtil.UNNAMED_SITE = "an unnamed site";
|
|
388
|
+
export default NetworkDeviceLinkRuleUtil;
|
|
108
389
|
//# sourceMappingURL=NetworkDeviceLinkRuleUtil.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NetworkDeviceLinkRuleUtil.js","sourceRoot":"","sources":["../../../../Utils/Monitor/NetworkDeviceLinkRuleUtil.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"NetworkDeviceLinkRuleUtil.js","sourceRoot":"","sources":["../../../../Utils/Monitor/NetworkDeviceLinkRuleUtil.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import OneUptimeDate from "../../Types/Date";
|
|
2
|
+
import ColumnLength from "../../Types/Database/ColumnLength";
|
|
3
|
+
/*
|
|
4
|
+
* Why a network discovery scan is still sitting in "Pending".
|
|
5
|
+
*
|
|
6
|
+
* A scan leaves "Pending" in exactly one place: the probe asks
|
|
7
|
+
* /probe/discovery-scan/list and the server claims a row for it
|
|
8
|
+
* (App/FeatureSet/Telemetry/API/ProbeIngest/DiscoveryScan.ts). Nothing on the
|
|
9
|
+
* server can make that happen — if the probe never asks, the row simply never
|
|
10
|
+
* moves.
|
|
11
|
+
*
|
|
12
|
+
* Until this existed, that outcome was completely silent. The scans list
|
|
13
|
+
* showed "Pending" and an em-dash in Responded Hosts, forever, with no
|
|
14
|
+
* timestamp, no probe state and no message anywhere in the product; the only
|
|
15
|
+
* evidence lived in the probe container's log, if the operator had it. That is
|
|
16
|
+
* what OneUptime issue #3287 reported: four scans submitted over an hour, all
|
|
17
|
+
* "Pending", nothing to act on.
|
|
18
|
+
*
|
|
19
|
+
* So this module writes the sentence the operator was missing. It is pure and
|
|
20
|
+
* lives in Common so the wording can be unit-tested without a database, the
|
|
21
|
+
* same way ScanTargetUtil's messages are.
|
|
22
|
+
*
|
|
23
|
+
* It deliberately does NOT fail the scan. A scan nobody has claimed is still
|
|
24
|
+
* perfectly runnable the moment the probe comes back, and a recurring one
|
|
25
|
+
* would tangle with the re-queue pass; what was missing was information, not a
|
|
26
|
+
* state change.
|
|
27
|
+
*/
|
|
28
|
+
/*
|
|
29
|
+
* How long a scan may sit unclaimed before the job says anything.
|
|
30
|
+
*
|
|
31
|
+
* The probe polls every minute, so this is fifteen consecutive failed polls —
|
|
32
|
+
* long enough that a restarting probe, a redeploy or a brief network blip
|
|
33
|
+
* never produces a message, short enough to be useful while the operator is
|
|
34
|
+
* still looking at the page they just submitted from.
|
|
35
|
+
*
|
|
36
|
+
* It is NOT the whole guard against false positives: a scan queued behind
|
|
37
|
+
* another scan on the same probe is legitimately Pending for as long as that
|
|
38
|
+
* sweep takes (the claim endpoint hands out one at a time), so the caller
|
|
39
|
+
* excludes probes that currently have a scan In Progress. This threshold only
|
|
40
|
+
* decides how long an IDLE probe gets before its silence is worth reporting.
|
|
41
|
+
*/
|
|
42
|
+
export const UNCLAIMED_PENDING_MINUTES = 15;
|
|
43
|
+
/*
|
|
44
|
+
* The two cases below are genuinely different problems with different fixes,
|
|
45
|
+
* and telling them apart is the entire point of this message: a probe that is
|
|
46
|
+
* not connected is an infrastructure problem the operator can see and fix,
|
|
47
|
+
* whereas a probe that IS connected and still is not claiming scans means the
|
|
48
|
+
* probe is running but its discovery job is not — an old image, a wedged
|
|
49
|
+
* sweep, or a probe that cannot reach the probe-ingest route specifically.
|
|
50
|
+
*/
|
|
51
|
+
export function buildUnclaimedScanDiagnosis(probeState) {
|
|
52
|
+
const probeLabel = probeState.probeName
|
|
53
|
+
? `Probe "${truncateProbeName(probeState.probeName)}"`
|
|
54
|
+
: "The assigned probe";
|
|
55
|
+
if (!probeState.isProbeConnected) {
|
|
56
|
+
const lastSeen = probeState.lastAliveAt
|
|
57
|
+
? `It was last seen ${OneUptimeDate.fromNow(probeState.lastAliveAt)}.`
|
|
58
|
+
: "It has never connected.";
|
|
59
|
+
return (`Not started yet: ${probeLabel} is not connected to OneUptime, so it has not picked this scan up. ` +
|
|
60
|
+
`${lastSeen} The scan will run on its own as soon as the probe reconnects.`);
|
|
61
|
+
}
|
|
62
|
+
return (`Not started yet: ${probeLabel} is connected but has not picked this scan up for over ` +
|
|
63
|
+
`${UNCLAIMED_PENDING_MINUTES} minutes. Check that the probe is running a version that supports ` +
|
|
64
|
+
`network discovery, and that it can reach the probe-ingest endpoint. The scan will run on its own ` +
|
|
65
|
+
`once the probe starts claiming scans again.`);
|
|
66
|
+
}
|
|
67
|
+
/*
|
|
68
|
+
* statusMessage is a varchar(500) and this job writes through the full
|
|
69
|
+
* update pipeline, which does NOT clamp — an over-long value would throw and
|
|
70
|
+
* the diagnosis would be lost rather than truncated. The only unbounded part
|
|
71
|
+
* of the sentence is the probe's name (itself a ShortText column, so at most
|
|
72
|
+
* 100 characters), and it is cut here so the arithmetic holds for every
|
|
73
|
+
* possible name. See the test that asserts the worst case still fits.
|
|
74
|
+
*/
|
|
75
|
+
const MAX_PROBE_NAME_LENGTH = 60;
|
|
76
|
+
function truncateProbeName(name) {
|
|
77
|
+
if (name.length <= MAX_PROBE_NAME_LENGTH) {
|
|
78
|
+
return name;
|
|
79
|
+
}
|
|
80
|
+
return name.substring(0, MAX_PROBE_NAME_LENGTH) + "…";
|
|
81
|
+
}
|
|
82
|
+
/*
|
|
83
|
+
* Exported so the job and its tests agree on the ceiling they are checking
|
|
84
|
+
* against, rather than both hard-coding 500.
|
|
85
|
+
*/
|
|
86
|
+
export const MAX_SCAN_STATUS_MESSAGE_LENGTH = ColumnLength.LongText;
|
|
87
|
+
//# sourceMappingURL=UnclaimedScanDiagnosis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UnclaimedScanDiagnosis.js","sourceRoot":"","sources":["../../../../Utils/NetworkDiscovery/UnclaimedScanDiagnosis.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,kBAAkB,CAAC;AAC7C,OAAO,YAAY,MAAM,mCAAmC,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAW,EAAE,CAAC;AAepD;;;;;;;GAOG;AACH,MAAM,UAAU,2BAA2B,CACzC,UAAmC;IAEnC,MAAM,UAAU,GAAW,UAAU,CAAC,SAAS;QAC7C,CAAC,CAAC,UAAU,iBAAiB,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG;QACtD,CAAC,CAAC,oBAAoB,CAAC;IAEzB,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAW,UAAU,CAAC,WAAW;YAC7C,CAAC,CAAC,oBAAoB,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG;YACtE,CAAC,CAAC,yBAAyB,CAAC;QAE9B,OAAO,CACL,oBAAoB,UAAU,qEAAqE;YACnG,GAAG,QAAQ,gEAAgE,CAC5E,CAAC;IACJ,CAAC;IAED,OAAO,CACL,oBAAoB,UAAU,yDAAyD;QACvF,GAAG,yBAAyB,oEAAoE;QAChG,mGAAmG;QACnG,6CAA6C,CAC9C,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,qBAAqB,GAAW,EAAE,CAAC;AAEzC,SAAS,iBAAiB,CAAC,IAAY;IACrC,IAAI,IAAI,CAAC,MAAM,IAAI,qBAAqB,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,qBAAqB,CAAC,GAAG,GAAG,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAW,YAAY,CAAC,QAAQ,CAAC"}
|