@adobe/alloy 2.30.1-beta.20 → 2.30.1-beta.22
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/libEs5/components/Context/injectOneTimeAnalyticsReferrer.js +4 -1
- package/libEs5/components/Personalization/createFetchDataHandler.js +6 -1
- package/libEs5/components/Personalization/dom-actions/remapHeadOffers.js +5 -0
- package/libEs5/components/StreamingMedia/createMediaEventManager.js +1 -1
- package/libEs5/constants/libraryVersion.js +1 -1
- package/libEs5/core/createEvent.js +4 -0
- package/libEs5/core/edgeNetwork/injectSendEdgeNetworkRequest.js +23 -0
- package/libEs5/utils/clamp.js +25 -0
- package/libEs5/utils/filterObject.js +1 -1
- package/libEs5/utils/prepareConfigOverridesForEdge.js +4 -2
- package/libEs5/utils/request/createDataCollectionRequestPayload.js +3 -0
- package/libEs5/utils/request/createRequestParams.js +1 -0
- package/libEs5/utils/request/createRequestPayload.js +6 -1
- package/libEs5/utils/request/types.js +1 -0
- package/libEs6/components/Context/injectOneTimeAnalyticsReferrer.js +3 -1
- package/libEs6/components/Personalization/createFetchDataHandler.js +6 -1
- package/libEs6/components/Personalization/dom-actions/remapHeadOffers.js +6 -1
- package/libEs6/components/StreamingMedia/createMediaEventManager.js +1 -1
- package/libEs6/constants/libraryVersion.js +1 -1
- package/libEs6/core/createEvent.js +4 -0
- package/libEs6/core/edgeNetwork/injectSendEdgeNetworkRequest.js +23 -0
- package/libEs6/utils/clamp.js +22 -0
- package/libEs6/utils/filterObject.js +1 -1
- package/libEs6/utils/prepareConfigOverridesForEdge.js +4 -2
- package/libEs6/utils/request/createDataCollectionRequestPayload.js +3 -0
- package/libEs6/utils/request/createRequestParams.js +1 -0
- package/libEs6/utils/request/createRequestPayload.js +6 -1
- package/libEs6/utils/request/types.js +1 -0
- package/package.json +32 -33
- package/types/components/Context/injectOneTimeAnalyticsReferrer.d.ts.map +1 -1
- package/types/components/Personalization/createFetchDataHandler.d.ts.map +1 -1
- package/types/components/Personalization/dom-actions/remapHeadOffers.d.ts.map +1 -1
- package/types/core/createEvent.d.ts +1 -0
- package/types/core/createEvent.d.ts.map +1 -1
- package/types/core/edgeNetwork/injectSendEdgeNetworkRequest.d.ts.map +1 -1
- package/types/utils/clamp.d.ts +3 -0
- package/types/utils/clamp.d.ts.map +1 -0
- package/types/utils/prepareConfigOverridesForEdge.d.ts.map +1 -1
- package/types/utils/request/createDataCollectionRequestPayload.d.ts.map +1 -1
- package/types/utils/request/createRequestParams.d.ts.map +1 -1
- package/types/utils/request/createRequestPayload.d.ts.map +1 -1
- package/types/utils/request/types.d.ts +2 -0
- package/types/utils/request/types.d.ts.map +1 -1
|
@@ -12,12 +12,15 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
|
|
|
12
12
|
OF ANY KIND, either express or implied. See the License for the specific language
|
|
13
13
|
governing permissions and limitations under the License.
|
|
14
14
|
*/
|
|
15
|
+
|
|
16
|
+
// Because these events are originated by the SDK rather than user actions, don't change the referrer
|
|
17
|
+
const IGNORED_EVENT_TYPES = new Set(["decisioning.propositionFetch", "decisioning.propositionDisplay", "decisioning.propositionInteract"]);
|
|
15
18
|
var _default = window => {
|
|
16
19
|
let lastReferrerSent = null;
|
|
17
20
|
return event => {
|
|
18
21
|
const content = event.getContent();
|
|
19
22
|
const eventType = content.xdm?.eventType;
|
|
20
|
-
if (eventType
|
|
23
|
+
if (IGNORED_EVENT_TYPES.has(eventType)) {
|
|
21
24
|
return;
|
|
22
25
|
}
|
|
23
26
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
exports.default = void 0;
|
|
4
4
|
var _index = require("../../utils/index.js");
|
|
5
5
|
var _pageWideScope = require("../../constants/pageWideScope.js");
|
|
6
|
+
var _schema = require("../../constants/schema.js");
|
|
6
7
|
/*
|
|
7
8
|
Copyright 2023 Adobe. All rights reserved.
|
|
8
9
|
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -107,7 +108,11 @@ var _default = ({
|
|
|
107
108
|
// Render could take a long time especially if one of the renders
|
|
108
109
|
// is waiting for html to appear on the page. We show the containers
|
|
109
110
|
// immediately, and whatever renders quickly will not have flicker.
|
|
110
|
-
|
|
111
|
+
// However, skip showing containers if there's only one page proposition with a single REDIRECT_ITEM
|
|
112
|
+
const shouldSkipShowContainers = pagePropositions.length === 1 && pagePropositions[0].getItems().every(p => p.getSchema() === _schema.REDIRECT_ITEM);
|
|
113
|
+
if (!shouldSkipShowContainers) {
|
|
114
|
+
showContainers();
|
|
115
|
+
}
|
|
111
116
|
} else {
|
|
112
117
|
({
|
|
113
118
|
returnedPropositions,
|
|
@@ -39,6 +39,11 @@ var _default = action => {
|
|
|
39
39
|
content,
|
|
40
40
|
selector
|
|
41
41
|
} = result;
|
|
42
|
+
|
|
43
|
+
// Custom code actions have a "HEAD" selector, but are handled differently.
|
|
44
|
+
if (result.type === _initDomActionsModules.DOM_ACTION_CUSTOM_CODE) {
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
42
47
|
if ((0, _isBlankString.default)(content)) {
|
|
43
48
|
return result;
|
|
44
49
|
}
|
|
@@ -14,4 +14,4 @@ governing permissions and limitations under the License.
|
|
|
14
14
|
*/
|
|
15
15
|
// The __VERSION__ keyword will be replace at alloy build time with the package.json version.
|
|
16
16
|
// see babel-plugin-version
|
|
17
|
-
var _default = exports.default = "2.30.1-beta.
|
|
17
|
+
var _default = exports.default = "2.30.1-beta.22";
|
|
@@ -27,6 +27,7 @@ const getXdmPropositions = xdm => {
|
|
|
27
27
|
};
|
|
28
28
|
var _default = () => {
|
|
29
29
|
const content = {};
|
|
30
|
+
const createdAt = Date.now();
|
|
30
31
|
let userXdm;
|
|
31
32
|
let userData;
|
|
32
33
|
let documentMayUnload = false;
|
|
@@ -141,6 +142,9 @@ var _default = () => {
|
|
|
141
142
|
getDocumentMayUnload() {
|
|
142
143
|
return documentMayUnload;
|
|
143
144
|
},
|
|
145
|
+
getCreatedAt() {
|
|
146
|
+
return createdAt;
|
|
147
|
+
},
|
|
144
148
|
isEmpty() {
|
|
145
149
|
return (0, _index.isEmptyObject)(content) && (!userXdm || (0, _index.isEmptyObject)(userXdm)) && (!userData || (0, _index.isEmptyObject)(userData));
|
|
146
150
|
},
|
|
@@ -5,6 +5,7 @@ var _domain = require("../../constants/domain.js");
|
|
|
5
5
|
var _apiVersion = require("../../constants/apiVersion.js");
|
|
6
6
|
var _index = require("../../utils/index.js");
|
|
7
7
|
var _networkErrors = require("../../utils/networkErrors.js");
|
|
8
|
+
var _clamp = require("../../utils/clamp.js");
|
|
8
9
|
var _mergeLifecycleResponses = require("./mergeLifecycleResponses.js");
|
|
9
10
|
var _handleRequestFailure = require("./handleRequestFailure.js");
|
|
10
11
|
/*
|
|
@@ -22,6 +23,22 @@ governing permissions and limitations under the License.
|
|
|
22
23
|
/** @import { EdgeRequestExecutor } from './types.js' */
|
|
23
24
|
/** @import { ResponseCreator } from '../types.js' */
|
|
24
25
|
|
|
26
|
+
const MAX_QUEUE_TIME_MILLIS = 300000; // 5 minutes
|
|
27
|
+
|
|
28
|
+
const calculateQueueTimeMillis = payload => {
|
|
29
|
+
if (typeof payload.getEvents !== "function") {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const events = payload.getEvents();
|
|
33
|
+
if (events.length === 0) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// In practice, there should only be one event in the payload, in the future if this changes we'll need to
|
|
38
|
+
// evaluate what timestamp to use (earliest, average, latest), or move the queueTime to the event meta
|
|
39
|
+
const earliestCreatedAt = Math.min(...events.map(event => event.getCreatedAt()));
|
|
40
|
+
return (0, _clamp.default)(Date.now() - earliestCreatedAt, 0, MAX_QUEUE_TIME_MILLIS);
|
|
41
|
+
};
|
|
25
42
|
const isDemdexBlockedError = (error, request) => {
|
|
26
43
|
return request.getUseIdThirdPartyDomain() && (0, _networkErrors.isNetworkError)(error);
|
|
27
44
|
};
|
|
@@ -97,6 +114,12 @@ var _default = ({
|
|
|
97
114
|
const endpointDomain = hasDemdexFailed || !request.getUseIdThirdPartyDomain() ? edgeDomain : _domain.ID_THIRD_PARTY;
|
|
98
115
|
const url = buildEndpointUrl(endpointDomain, request);
|
|
99
116
|
const payload = request.getPayload();
|
|
117
|
+
const queueTimeMillis = calculateQueueTimeMillis(payload);
|
|
118
|
+
if (queueTimeMillis !== undefined) {
|
|
119
|
+
payload.mergeMeta({
|
|
120
|
+
queueTimeMillis
|
|
121
|
+
});
|
|
122
|
+
}
|
|
100
123
|
cookieTransfer.cookiesToPayload(payload, endpointDomain);
|
|
101
124
|
return sendNetworkRequest({
|
|
102
125
|
requestId: request.getId(),
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.default = void 0;
|
|
4
|
+
/*
|
|
5
|
+
Copyright 2025 Adobe. All rights reserved.
|
|
6
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
8
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
11
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
12
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
13
|
+
governing permissions and limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Clamps a value between a minimum and maximum value.
|
|
17
|
+
* @param {number} value - The value to clamp.
|
|
18
|
+
* @param {number} min - The minimum value.
|
|
19
|
+
* @param {number} max - The maximum value.
|
|
20
|
+
* @returns {number} The clamped value.
|
|
21
|
+
*/
|
|
22
|
+
var _default = (value, min, max) => {
|
|
23
|
+
return Math.max(min, Math.min(value, max));
|
|
24
|
+
};
|
|
25
|
+
exports.default = _default;
|
|
@@ -27,11 +27,13 @@ var _default = configuration => {
|
|
|
27
27
|
return null;
|
|
28
28
|
}
|
|
29
29
|
// remove entries that are empty strings or arrays
|
|
30
|
-
const configOverrides = (0, _filterObject.default)(configuration, value => {
|
|
30
|
+
const configOverrides = (0, _filterObject.default)(configuration, (value, key) => {
|
|
31
31
|
if ((0, _isNil.default)(value)) {
|
|
32
32
|
return false;
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
// We want to remove all the { enabled: true } values, but leave any other boolean values.
|
|
35
|
+
// Experience Edge will not accept { enabled: true } values as true is the default for "enabled".
|
|
36
|
+
if ((0, _isBoolean.default)(value) && (key !== "enabled" || value === false)) {
|
|
35
37
|
return true;
|
|
36
38
|
}
|
|
37
39
|
if ((0, _isNumber.default)(value)) {
|
|
@@ -34,6 +34,9 @@ var _default = () => {
|
|
|
34
34
|
content.events = content.events || [];
|
|
35
35
|
content.events.push(event);
|
|
36
36
|
},
|
|
37
|
+
getEvents: () => {
|
|
38
|
+
return content.events || [];
|
|
39
|
+
},
|
|
37
40
|
getDocumentMayUnload: () => {
|
|
38
41
|
return (content.events || []).some(event => event.getDocumentMayUnload());
|
|
39
42
|
}
|
|
@@ -44,6 +44,7 @@ var _default = ({
|
|
|
44
44
|
if (localConfigOverridesWithoutDatastreamId && !(0, _index.isEmptyObject)(localConfigOverridesWithoutDatastreamId)) {
|
|
45
45
|
payload.mergeConfigOverride(localConfigOverridesWithoutDatastreamId);
|
|
46
46
|
}
|
|
47
|
+
payload.finalizeConfigOverrides();
|
|
47
48
|
return requestParams;
|
|
48
49
|
};
|
|
49
50
|
exports.default = _default;
|
|
@@ -90,7 +90,12 @@ var _default = options => {
|
|
|
90
90
|
mergeMeta: (0, _index.createMerger)(content, "meta"),
|
|
91
91
|
mergeState: (0, _index.createMerger)(content, "meta.state"),
|
|
92
92
|
mergeQuery: (0, _index.createMerger)(content, "query"),
|
|
93
|
-
mergeConfigOverride: updates => mergeConfigOverrides(
|
|
93
|
+
mergeConfigOverride: updates => mergeConfigOverrides(updates),
|
|
94
|
+
finalizeConfigOverrides: () => {
|
|
95
|
+
if (content.meta?.configOverrides) {
|
|
96
|
+
content.meta.configOverrides = (0, _index.prepareConfigOverridesForEdge)(content.meta.configOverrides);
|
|
97
|
+
}
|
|
98
|
+
},
|
|
94
99
|
addIdentity,
|
|
95
100
|
hasIdentity,
|
|
96
101
|
toJSON() {
|
|
@@ -52,6 +52,7 @@ governing permissions and limitations under the License.
|
|
|
52
52
|
* @property {function(string, Identity): void} options.addIdentity
|
|
53
53
|
* @property {function(string): boolean} options.hasIdentity
|
|
54
54
|
* @property {function(object): void} addEvent
|
|
55
|
+
* @property {function(): Array} getEvents
|
|
55
56
|
* @property {function(): boolean} getDocumentMayUnload
|
|
56
57
|
* @property {function(): object} toJSON
|
|
57
58
|
*/
|
|
@@ -10,12 +10,14 @@ OF ANY KIND, either express or implied. See the License for the specific languag
|
|
|
10
10
|
governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
// Because these events are originated by the SDK rather than user actions, don't change the referrer
|
|
14
|
+
const IGNORED_EVENT_TYPES = new Set(["decisioning.propositionFetch", "decisioning.propositionDisplay", "decisioning.propositionInteract"]);
|
|
13
15
|
export default window => {
|
|
14
16
|
let lastReferrerSent = null;
|
|
15
17
|
return event => {
|
|
16
18
|
const content = event.getContent();
|
|
17
19
|
const eventType = content.xdm?.eventType;
|
|
18
|
-
if (eventType
|
|
20
|
+
if (IGNORED_EVENT_TYPES.has(eventType)) {
|
|
19
21
|
return;
|
|
20
22
|
}
|
|
21
23
|
|
|
@@ -11,6 +11,7 @@ governing permissions and limitations under the License.
|
|
|
11
11
|
*/
|
|
12
12
|
import { groupBy, isNonEmptyArray } from "../../utils/index.js";
|
|
13
13
|
import PAGE_WIDE_SCOPE from "../../constants/pageWideScope.js";
|
|
14
|
+
import { REDIRECT_ITEM } from "../../constants/schema.js";
|
|
14
15
|
const DECISIONS_HANDLE = "personalization:decisions";
|
|
15
16
|
export default ({
|
|
16
17
|
logger,
|
|
@@ -103,7 +104,11 @@ export default ({
|
|
|
103
104
|
// Render could take a long time especially if one of the renders
|
|
104
105
|
// is waiting for html to appear on the page. We show the containers
|
|
105
106
|
// immediately, and whatever renders quickly will not have flicker.
|
|
106
|
-
|
|
107
|
+
// However, skip showing containers if there's only one page proposition with a single REDIRECT_ITEM
|
|
108
|
+
const shouldSkipShowContainers = pagePropositions.length === 1 && pagePropositions[0].getItems().every(p => p.getSchema() === REDIRECT_ITEM);
|
|
109
|
+
if (!shouldSkipShowContainers) {
|
|
110
|
+
showContainers();
|
|
111
|
+
}
|
|
107
112
|
} else {
|
|
108
113
|
({
|
|
109
114
|
returnedPropositions,
|
|
@@ -21,7 +21,7 @@ import { is } from "./scripts.js";
|
|
|
21
21
|
import { createFragment, selectNodesWithEq } from "./dom/index.js";
|
|
22
22
|
import isBlankString from "../../../utils/isBlankString.js";
|
|
23
23
|
import { HEAD } from "../../../constants/tagName.js";
|
|
24
|
-
import { DOM_ACTION_APPEND_HTML } from "./initDomActionsModules.js";
|
|
24
|
+
import { DOM_ACTION_APPEND_HTML, DOM_ACTION_CUSTOM_CODE } from "./initDomActionsModules.js";
|
|
25
25
|
const HEAD_TAGS_SELECTOR = "SCRIPT,LINK,STYLE";
|
|
26
26
|
const filterHeadContent = content => {
|
|
27
27
|
const container = createFragment(content);
|
|
@@ -36,6 +36,11 @@ export default action => {
|
|
|
36
36
|
content,
|
|
37
37
|
selector
|
|
38
38
|
} = result;
|
|
39
|
+
|
|
40
|
+
// Custom code actions have a "HEAD" selector, but are handled differently.
|
|
41
|
+
if (result.type === DOM_ACTION_CUSTOM_CODE) {
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
39
44
|
if (isBlankString(content)) {
|
|
40
45
|
return result;
|
|
41
46
|
}
|
|
@@ -24,6 +24,7 @@ const getXdmPropositions = xdm => {
|
|
|
24
24
|
};
|
|
25
25
|
export default () => {
|
|
26
26
|
const content = {};
|
|
27
|
+
const createdAt = Date.now();
|
|
27
28
|
let userXdm;
|
|
28
29
|
let userData;
|
|
29
30
|
let documentMayUnload = false;
|
|
@@ -138,6 +139,9 @@ export default () => {
|
|
|
138
139
|
getDocumentMayUnload() {
|
|
139
140
|
return documentMayUnload;
|
|
140
141
|
},
|
|
142
|
+
getCreatedAt() {
|
|
143
|
+
return createdAt;
|
|
144
|
+
},
|
|
141
145
|
isEmpty() {
|
|
142
146
|
return isEmptyObject(content) && (!userXdm || isEmptyObject(userXdm)) && (!userData || isEmptyObject(userData));
|
|
143
147
|
},
|
|
@@ -17,8 +17,25 @@ import { ID_THIRD_PARTY as ID_THIRD_PARTY_DOMAIN } from "../../constants/domain.
|
|
|
17
17
|
import apiVersion from "../../constants/apiVersion.js";
|
|
18
18
|
import { createCallbackAggregator, noop } from "../../utils/index.js";
|
|
19
19
|
import { isNetworkError } from "../../utils/networkErrors.js";
|
|
20
|
+
import clamp from "../../utils/clamp.js";
|
|
20
21
|
import mergeLifecycleResponses from "./mergeLifecycleResponses.js";
|
|
21
22
|
import handleRequestFailure from "./handleRequestFailure.js";
|
|
23
|
+
const MAX_QUEUE_TIME_MILLIS = 300000; // 5 minutes
|
|
24
|
+
|
|
25
|
+
const calculateQueueTimeMillis = payload => {
|
|
26
|
+
if (typeof payload.getEvents !== "function") {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
const events = payload.getEvents();
|
|
30
|
+
if (events.length === 0) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// In practice, there should only be one event in the payload, in the future if this changes we'll need to
|
|
35
|
+
// evaluate what timestamp to use (earliest, average, latest), or move the queueTime to the event meta
|
|
36
|
+
const earliestCreatedAt = Math.min(...events.map(event => event.getCreatedAt()));
|
|
37
|
+
return clamp(Date.now() - earliestCreatedAt, 0, MAX_QUEUE_TIME_MILLIS);
|
|
38
|
+
};
|
|
22
39
|
const isDemdexBlockedError = (error, request) => {
|
|
23
40
|
return request.getUseIdThirdPartyDomain() && isNetworkError(error);
|
|
24
41
|
};
|
|
@@ -94,6 +111,12 @@ export default ({
|
|
|
94
111
|
const endpointDomain = hasDemdexFailed || !request.getUseIdThirdPartyDomain() ? edgeDomain : ID_THIRD_PARTY_DOMAIN;
|
|
95
112
|
const url = buildEndpointUrl(endpointDomain, request);
|
|
96
113
|
const payload = request.getPayload();
|
|
114
|
+
const queueTimeMillis = calculateQueueTimeMillis(payload);
|
|
115
|
+
if (queueTimeMillis !== undefined) {
|
|
116
|
+
payload.mergeMeta({
|
|
117
|
+
queueTimeMillis
|
|
118
|
+
});
|
|
119
|
+
}
|
|
97
120
|
cookieTransfer.cookiesToPayload(payload, endpointDomain);
|
|
98
121
|
return sendNetworkRequest({
|
|
99
122
|
requestId: request.getId(),
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
|
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Clamps a value between a minimum and maximum value.
|
|
15
|
+
* @param {number} value - The value to clamp.
|
|
16
|
+
* @param {number} min - The minimum value.
|
|
17
|
+
* @param {number} max - The maximum value.
|
|
18
|
+
* @returns {number} The clamped value.
|
|
19
|
+
*/
|
|
20
|
+
export default (value, min, max) => {
|
|
21
|
+
return Math.max(min, Math.min(value, max));
|
|
22
|
+
};
|
|
@@ -25,11 +25,13 @@ export default configuration => {
|
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
27
27
|
// remove entries that are empty strings or arrays
|
|
28
|
-
const configOverrides = filterObject(configuration, value => {
|
|
28
|
+
const configOverrides = filterObject(configuration, (value, key) => {
|
|
29
29
|
if (isNil(value)) {
|
|
30
30
|
return false;
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
// We want to remove all the { enabled: true } values, but leave any other boolean values.
|
|
33
|
+
// Experience Edge will not accept { enabled: true } values as true is the default for "enabled".
|
|
34
|
+
if (isBoolean(value) && (key !== "enabled" || value === false)) {
|
|
33
35
|
return true;
|
|
34
36
|
}
|
|
35
37
|
if (isNumber(value)) {
|
|
@@ -34,6 +34,9 @@ export default () => {
|
|
|
34
34
|
content.events = content.events || [];
|
|
35
35
|
content.events.push(event);
|
|
36
36
|
},
|
|
37
|
+
getEvents: () => {
|
|
38
|
+
return content.events || [];
|
|
39
|
+
},
|
|
37
40
|
getDocumentMayUnload: () => {
|
|
38
41
|
return (content.events || []).some(event => event.getDocumentMayUnload());
|
|
39
42
|
}
|
|
@@ -42,5 +42,6 @@ export default ({
|
|
|
42
42
|
if (localConfigOverridesWithoutDatastreamId && !isEmptyObject(localConfigOverridesWithoutDatastreamId)) {
|
|
43
43
|
payload.mergeConfigOverride(localConfigOverridesWithoutDatastreamId);
|
|
44
44
|
}
|
|
45
|
+
payload.finalizeConfigOverrides();
|
|
45
46
|
return requestParams;
|
|
46
47
|
};
|
|
@@ -88,7 +88,12 @@ export default options => {
|
|
|
88
88
|
mergeMeta: createMerger(content, "meta"),
|
|
89
89
|
mergeState: createMerger(content, "meta.state"),
|
|
90
90
|
mergeQuery: createMerger(content, "query"),
|
|
91
|
-
mergeConfigOverride: updates => mergeConfigOverrides(
|
|
91
|
+
mergeConfigOverride: updates => mergeConfigOverrides(updates),
|
|
92
|
+
finalizeConfigOverrides: () => {
|
|
93
|
+
if (content.meta?.configOverrides) {
|
|
94
|
+
content.meta.configOverrides = prepareConfigOverridesForEdge(content.meta.configOverrides);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
92
97
|
addIdentity,
|
|
93
98
|
hasIdentity,
|
|
94
99
|
toJSON() {
|
|
@@ -49,6 +49,7 @@ governing permissions and limitations under the License.
|
|
|
49
49
|
* @property {function(string, Identity): void} options.addIdentity
|
|
50
50
|
* @property {function(string): boolean} options.hasIdentity
|
|
51
51
|
* @property {function(object): void} addEvent
|
|
52
|
+
* @property {function(): Array} getEvents
|
|
52
53
|
* @property {function(): boolean} getDocumentMayUnload
|
|
53
54
|
* @property {function(): object} toJSON
|
|
54
55
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/alloy",
|
|
3
|
-
"version": "2.30.1-beta.
|
|
3
|
+
"version": "2.30.1-beta.22",
|
|
4
4
|
"description": "Adobe Experience Platform Web SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "libEs5/index.js",
|
|
@@ -21,36 +21,6 @@
|
|
|
21
21
|
"bin": {
|
|
22
22
|
"alloyBuilder": "scripts/alloyBuilder.js"
|
|
23
23
|
},
|
|
24
|
-
"scripts": {
|
|
25
|
-
"clean": "rimraf dist distTest libEs5 libEs6 types",
|
|
26
|
-
"lint": "eslint --cache --fix \"*.{js,cjs,mjs,jsx}\" \"{sandboxes/*/src,packages/*/src,test,scripts}/**/*.{js,cjs,mjs,jsx}\"",
|
|
27
|
-
"format": "prettier --write \"*.{html,js,cjs,mjs,jsx}\" \"{sandboxes/*/src,packages/*/src,test,scripts}/**/*.{html,js,cjs,mjs,jsx}\"",
|
|
28
|
-
"types": "tsc",
|
|
29
|
-
"test": "pnpm exec playwright install chromium && vitest run && pnpm run test:scripts",
|
|
30
|
-
"test:coverage": "rimraf coverage && pnpm exec playwright install chromium && vitest run --coverage",
|
|
31
|
-
"test:unit": "pnpm exec playwright install chromium && vitest run --project=unit",
|
|
32
|
-
"test:unit:debug": "pnpm exec playwright install chromium && vitest --no-file-parallelism --project=unit --browser=chromium --browser.provider=playwright --browser.headless=false",
|
|
33
|
-
"test:unit:watch": "pnpm exec playwright install chromium && vitest --project=unit",
|
|
34
|
-
"test:unit:coverage": "pnpm exec playwright install chromium && vitest run --coverage --project=unit",
|
|
35
|
-
"test:integration": "pnpm exec playwright install chromium && vitest run --project=integration",
|
|
36
|
-
"test:integration:debug": "pnpm exec playwright install chromium && vitest --no-file-parallelism --project=integration --browser=chromium --browser.provider=playwright --browser.headless=false",
|
|
37
|
-
"test:integration:watch": "pnpm exec playwright install chromium && vitest --project=integration",
|
|
38
|
-
"test:integration:coverage": "pnpm exec playwright install chromium && vitest run --coverage --project=integration",
|
|
39
|
-
"test:functional": "pnpm exec playwright install chromium && EDGE_BASE_PATH=\"ee-pre-prd\" ALLOY_ENV=\"int\" testcafe chromium",
|
|
40
|
-
"test:functional:custom": "node scripts/helpers/runFunctionalTests.js",
|
|
41
|
-
"test:functional:watch": "pnpm exec playwright install chromium && EDGE_BASE_PATH=\"ee-pre-prd\" ALLOY_ENV=\"int\" ./scripts/watchFunctionalTests.js --browsers chromium",
|
|
42
|
-
"test:functional:debug": "pnpm exec playwright install chromium && EDGE_BASE_PATH=\"ee-pre-prd\" ALLOY_ENV=\"int\" testcafe --inspect-brk chromium",
|
|
43
|
-
"test:functional:build:int": "rollup -c --environment BASE_CODE_MIN,STANDALONE,NPM_PACKAGE_LOCAL",
|
|
44
|
-
"test:functional:build:prod": "rollup -c --environment BASE_CODE_MIN,NPM_PACKAGE_PROD",
|
|
45
|
-
"test:scripts": "vitest run --config=./scripts/specs/vitest.config.js",
|
|
46
|
-
"dev": "concurrently --names build,sandbox \"rollup -c -w --environment SANDBOX_SERVICE_WORKER\" \"REACT_APP_NONCE=123 pnpm run --filter @adobe/alloy-sandbox-browser start\"",
|
|
47
|
-
"build": "pnpm run clean && rollup -c --environment BASE_CODE_MIN,STANDALONE,STANDALONE_MIN,SERVICE_WORKER,SERVICE_WORKER_MIN && echo \"Base Code:\" && cat distTest/baseCode.min.js",
|
|
48
|
-
"build:watch": "pnpm run clean && rollup -c --watch --environment BASE_CODE_MIN,STANDALONE",
|
|
49
|
-
"build:custom": "node scripts/alloyBuilder.js",
|
|
50
|
-
"prepare": "husky",
|
|
51
|
-
"prepack": "pnpm run clean && babel packages/core/src -d libEs5 --env-name npmEs5 && babel packages/core/src -d libEs6 --env-name npmEs6 && echo '{\"type\":\"commonjs\"}' > libEs5/package.json && echo '{\"type\":\"module\"}' > libEs6/package.json && pnpm run types",
|
|
52
|
-
"checkthattestfilesexist": "./scripts/checkThatTestFilesExist.js"
|
|
53
|
-
},
|
|
54
24
|
"lint-staged": {
|
|
55
25
|
"./*.{cjs,mjs,js,jsx}": [
|
|
56
26
|
"eslint --cache --fix"
|
|
@@ -92,6 +62,8 @@
|
|
|
92
62
|
"@adobe/alloy": "next",
|
|
93
63
|
"@babel/cli": "^7.28.3",
|
|
94
64
|
"@babel/plugin-transform-modules-commonjs": "^7.27.1",
|
|
65
|
+
"@changesets/changelog-github": "^0.5.2",
|
|
66
|
+
"@changesets/cli": "^2.29.8",
|
|
95
67
|
"@eslint/js": "^9.38.0",
|
|
96
68
|
"@octokit/rest": "^22.0.1",
|
|
97
69
|
"@types/node": "^24.9.1",
|
|
@@ -122,10 +94,37 @@
|
|
|
122
94
|
"testcafe": "^3.7.2",
|
|
123
95
|
"testcafe-browser-provider-playwright": "^1.1.0",
|
|
124
96
|
"typescript": "^5.9.3",
|
|
125
|
-
"url-exists-nodejs": "^0.2.4",
|
|
126
97
|
"vitest": "^4.0.6"
|
|
127
98
|
},
|
|
128
99
|
"optionalDependencies": {
|
|
129
100
|
"@rollup/rollup-linux-x64-gnu": "^4.52.5"
|
|
101
|
+
},
|
|
102
|
+
"scripts": {
|
|
103
|
+
"clean": "rimraf dist distTest libEs5 libEs6 types",
|
|
104
|
+
"lint": "eslint --cache --fix \"*.{js,cjs,mjs,jsx}\" \"{sandboxes/*/src,packages/*/src,test,scripts}/**/*.{js,cjs,mjs,jsx}\"",
|
|
105
|
+
"format": "prettier --write \"*.{html,js,cjs,mjs,jsx}\" \"{sandboxes/*/src,packages/*/src,test,scripts}/**/*.{html,js,cjs,mjs,jsx}\"",
|
|
106
|
+
"types": "tsc",
|
|
107
|
+
"test": "pnpm exec playwright install chromium && vitest run && pnpm run test:scripts",
|
|
108
|
+
"test:coverage": "rimraf coverage && pnpm exec playwright install chromium && vitest run --coverage",
|
|
109
|
+
"test:unit": "pnpm exec playwright install chromium && vitest run --project=unit",
|
|
110
|
+
"test:unit:debug": "pnpm exec playwright install chromium && vitest --no-file-parallelism --project=unit --browser=chromium --browser.provider=playwright --browser.headless=false",
|
|
111
|
+
"test:unit:watch": "pnpm exec playwright install chromium && vitest --project=unit",
|
|
112
|
+
"test:unit:coverage": "pnpm exec playwright install chromium && vitest run --coverage --project=unit",
|
|
113
|
+
"test:integration": "pnpm exec playwright install chromium && vitest run --project=integration",
|
|
114
|
+
"test:integration:debug": "pnpm exec playwright install chromium && vitest --no-file-parallelism --project=integration --browser=chromium --browser.provider=playwright --browser.headless=false",
|
|
115
|
+
"test:integration:watch": "pnpm exec playwright install chromium && vitest --project=integration",
|
|
116
|
+
"test:integration:coverage": "pnpm exec playwright install chromium && vitest run --coverage --project=integration",
|
|
117
|
+
"test:functional": "pnpm exec playwright install chromium && EDGE_BASE_PATH=\"ee-pre-prd\" ALLOY_ENV=\"int\" testcafe chromium",
|
|
118
|
+
"test:functional:custom": "node scripts/helpers/runFunctionalTests.js",
|
|
119
|
+
"test:functional:watch": "pnpm exec playwright install chromium && EDGE_BASE_PATH=\"ee-pre-prd\" ALLOY_ENV=\"int\" ./scripts/watchFunctionalTests.js --browsers chromium",
|
|
120
|
+
"test:functional:debug": "pnpm exec playwright install chromium && EDGE_BASE_PATH=\"ee-pre-prd\" ALLOY_ENV=\"int\" testcafe --inspect-brk chromium",
|
|
121
|
+
"test:functional:build:int": "rollup -c --environment BASE_CODE_MIN,STANDALONE,NPM_PACKAGE_LOCAL",
|
|
122
|
+
"test:functional:build:prod": "rollup -c --environment BASE_CODE_MIN,NPM_PACKAGE_PROD",
|
|
123
|
+
"test:scripts": "vitest run --config=./scripts/specs/vitest.config.js",
|
|
124
|
+
"dev": "concurrently --names build,sandbox \"rollup -c -w --environment SANDBOX_SERVICE_WORKER\" \"REACT_APP_NONCE=123 pnpm run --filter @adobe/alloy-sandbox-browser start\"",
|
|
125
|
+
"build": "pnpm run clean && rollup -c --environment BASE_CODE_MIN,STANDALONE,STANDALONE_MIN,SERVICE_WORKER,SERVICE_WORKER_MIN && echo \"Base Code:\" && cat distTest/baseCode.min.js",
|
|
126
|
+
"build:watch": "pnpm run clean && rollup -c --watch --environment BASE_CODE_MIN,STANDALONE",
|
|
127
|
+
"build:custom": "node scripts/alloyBuilder.js",
|
|
128
|
+
"checkthattestfilesexist": "./scripts/checkThatTestFilesExist.js"
|
|
130
129
|
}
|
|
131
|
-
}
|
|
130
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injectOneTimeAnalyticsReferrer.d.ts","sourceRoot":"","sources":["../../../packages/core/src/components/Context/injectOneTimeAnalyticsReferrer.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"injectOneTimeAnalyticsReferrer.d.ts","sourceRoot":"","sources":["../../../packages/core/src/components/Context/injectOneTimeAnalyticsReferrer.js"],"names":[],"mappings":"AAmBe,yCAGL,UAAK,UAsCd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createFetchDataHandler.d.ts","sourceRoot":"","sources":["../../../packages/core/src/components/Personalization/createFetchDataHandler.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createFetchDataHandler.d.ts","sourceRoot":"","sources":["../../../packages/core/src/components/Personalization/createFetchDataHandler.js"],"names":[],"mappings":"AAiBe;;;;;;;;;;KAWL;;;;;;CAMP,UAkHF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remapHeadOffers.d.ts","sourceRoot":"","sources":["../../../../packages/core/src/components/Personalization/dom-actions/remapHeadOffers.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"remapHeadOffers.d.ts","sourceRoot":"","sources":["../../../../packages/core/src/components/Personalization/dom-actions/remapHeadOffers.js"],"names":[],"mappings":"AAoCe,4CA0Bd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createEvent.d.ts","sourceRoot":"","sources":["../../packages/core/src/core/createEvent.js"],"names":[],"mappings":"AAgCe
|
|
1
|
+
{"version":3,"file":"createEvent.d.ts","sourceRoot":"","sources":["../../packages/core/src/core/createEvent.js"],"names":[],"mappings":"AAgCe;;;;;;;;;;;;;;;;;;EAmKd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injectSendEdgeNetworkRequest.d.ts","sourceRoot":"","sources":["../../../packages/core/src/core/edgeNetwork/injectSendEdgeNetworkRequest.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"injectSendEdgeNetworkRequest.d.ts","sourceRoot":"","sources":["../../../packages/core/src/core/edgeNetwork/injectSendEdgeNetworkRequest.js"],"names":[],"mappings":"AA8De,oLAZZ;IAAkF,MAAM,EAAhF;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAC;IAChD,SAAS,EAAzB,MAAM;IACU,cAAc,EAA9B,MAAM;IACqC,kBAAkB,EAA7D,CAAS,IAAM,EAAN,MAAM,KAAG,OAAO,KAAQ;IACR,cAAc,EAAvC,eAAe;IACiB,wBAAwB,EAAxD,CAAS,IAAM,EAAN,MAAM,KAAG,IAAI;IACgB,eAAe,EAArD,MAAY,MAAM,GAAC,SAAS;IACA,iCAAiC,EAA7D,MAAY,MAAM;CAG1B,GAAU,mBAAmB,CAuH/B;;qCAtKoC,aAAa;yCADT,YAAY"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clamp.d.ts","sourceRoot":"","sources":["../../packages/core/src/utils/clamp.js"],"names":[],"mappings":"AAmBe,iCALJ,MAAM,OACN,MAAM,OACN,MAAM,GACJ,MAAM,CAIlB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepareConfigOverridesForEdge.d.ts","sourceRoot":"","sources":["../../packages/core/src/utils/prepareConfigOverridesForEdge.js"],"names":[],"mappings":"AAsBe,
|
|
1
|
+
{"version":3,"file":"prepareConfigOverridesForEdge.d.ts","sourceRoot":"","sources":["../../packages/core/src/utils/prepareConfigOverridesForEdge.js"],"names":[],"mappings":"AAsBe,mDA8Bd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDataCollectionRequestPayload.d.ts","sourceRoot":"","sources":["../../../packages/core/src/utils/request/createDataCollectionRequestPayload.js"],"names":[],"mappings":"AAuBe,6BAFF,4BAA4B,
|
|
1
|
+
{"version":3,"file":"createDataCollectionRequestPayload.d.ts","sourceRoot":"","sources":["../../../packages/core/src/utils/request/createDataCollectionRequestPayload.js"],"names":[],"mappings":"AAuBe,6BAFF,4BAA4B,CAyBxC;;kDAlCiD,YAAY"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createRequestParams.d.ts","sourceRoot":"","sources":["../../../packages/core/src/utils/request/createRequestParams.js"],"names":[],"mappings":"AAuBe,oFALZ;IAAyB,oBAAoB,EAArC,QAAQ;IACS,qBAAqB,EAAtC,QAAQ;IACe,OAAO,EAA9B,cAAc;CACtB,GAAU;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"createRequestParams.d.ts","sourceRoot":"","sources":["../../../packages/core/src/utils/request/createRequestParams.js"],"names":[],"mappings":"AAuBe,oFALZ;IAAyB,oBAAoB,EAArC,QAAQ;IACS,qBAAqB,EAAtC,QAAQ;IACe,OAAO,EAA9B,cAAc;CACtB,GAAU;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAA;CAAE,CAwBrE;;uBA/BY;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,OAAS;CAAE;;yBAE5C,CAAS,IAAQ,EAAR,QAAQ,KAAG,IAAI"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createRequestPayload.d.ts","sourceRoot":"","sources":["../../../packages/core/src/utils/request/createRequestPayload.js"],"names":[],"mappings":"AAgFe,mCANZ;IAAwB,OAAO;IACmB,WAAW,EAArD,CAAS,IAAM,EAAN,MAAM,EAAE,IAAQ,EAAR,QAAQ,KAAG,IAAI;IACI,WAAW,EAA/C,CAAS,IAAM,EAAN,MAAM,KAAI,OAAO;CAElC,GAAU,cAAc,
|
|
1
|
+
{"version":3,"file":"createRequestPayload.d.ts","sourceRoot":"","sources":["../../../packages/core/src/utils/request/createRequestPayload.js"],"names":[],"mappings":"AAgFe,mCANZ;IAAwB,OAAO;IACmB,WAAW,EAArD,CAAS,IAAM,EAAN,MAAM,EAAE,IAAQ,EAAR,QAAQ,KAAG,IAAI;IACI,WAAW,EAA/C,CAAS,IAAM,EAAN,MAAM,KAAI,OAAO;CAElC,GAAU,cAAc,CA0B1B;;8BA5F6C,YAAY;oCAAZ,YAAY"}
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
* @property {function(string, Identity): void} options.addIdentity
|
|
36
36
|
* @property {function(string): boolean} options.hasIdentity
|
|
37
37
|
* @property {function(object): void} addEvent
|
|
38
|
+
* @property {function(): Array} getEvents
|
|
38
39
|
* @property {function(): boolean} getDocumentMayUnload
|
|
39
40
|
* @property {function(): object} toJSON
|
|
40
41
|
*/
|
|
@@ -82,6 +83,7 @@ export type DataCollectionRequestPayload = {
|
|
|
82
83
|
addIdentity: (arg0: string, arg1: Identity) => void;
|
|
83
84
|
hasIdentity: (arg0: string) => boolean;
|
|
84
85
|
addEvent: (arg0: object) => void;
|
|
86
|
+
getEvents: () => any[];
|
|
85
87
|
getDocumentMayUnload: () => boolean;
|
|
86
88
|
toJSON: () => object;
|
|
87
89
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../packages/core/src/utils/request/types.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;GAaG;AAEH;;;;;;;;;;;GAWG;AAEH
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../packages/core/src/utils/request/types.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;GAaG;AAEH;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AAEH,uBAAwB;;;;;WA7CV,MAAY,MAAM;gBAClB,MAAY,cAAc;eAC1B,CAAS,IAAgC,EAAhC;QAAC,qBAAqB,EAAE,OAAO,CAAA;KAAC,KAAG,MAAM;6BAClD,MAAY,MAAM,GAAC,SAAS;;oBAE5B,MAAY,MAAM,GAAC,SAAS;;;;;;;;;eAU5B,CAAS,IAAM,EAAN,MAAM,KAAG,IAAI;gBACtB,CAAS,IAAM,EAAN,MAAM,KAAG,IAAI;gBACtB,CAAS,IAAM,EAAN,MAAM,KAAG,IAAI;yBACtB,CAAS,IAAM,EAAN,MAAM,KAAG,IAAI;iBACtB,CAAS,IAAM,EAAN,MAAM,EAAE,IAAQ,EAAR,QAAQ,KAAG,IAAI;iBAChC,CAAS,IAAM,EAAN,MAAM,KAAG,OAAO;YACzB,MAAY,MAAM;;;;;;eAOlB,CAAS,IAAM,EAAN,MAAM,KAAG,IAAI;gBACtB,CAAS,IAAM,EAAN,MAAM,KAAG,IAAI;gBACtB,CAAS,IAAM,EAAN,MAAM,KAAG,IAAI;yBACtB,CAAS,IAAM,EAAN,MAAM,KAAG,IAAI;iBACtB,CAAS,IAAM,EAAN,MAAM,EAAE,IAAQ,EAAR,QAAQ,KAAG,IAAI;iBAChC,CAAS,IAAM,EAAN,MAAM,KAAG,OAAO;cACzB,CAAS,IAAM,EAAN,MAAM,KAAG,IAAI;eACtB,WAAiB;0BACjB,MAAY,OAAO;YACnB,MAAY,MAAM;;;QAKlB,MAAM"}
|