@guidelytech/shared 0.10.0 → 0.11.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.
- package/dist/chunk-TGIUEYXM.js +1937 -0
- package/dist/chunk-TGIUEYXM.js.map +1 -0
- package/dist/index.cjs +1645 -85
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +763 -3956
- package/dist/index.d.ts +763 -3956
- package/dist/index.js +532 -62
- package/dist/index.js.map +1 -1
- package/dist/runtime-BM5cztmJ.d.cts +5234 -0
- package/dist/runtime-BM5cztmJ.d.ts +5234 -0
- package/dist/runtime.cjs +1212 -6
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.cts +2 -511
- package/dist/runtime.d.ts +2 -511
- package/dist/runtime.js +157 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -21,9 +21,22 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
ADVANCE_ON: () => ADVANCE_ON,
|
|
24
|
+
AGENT_METADATA_MAX_BYTES: () => AGENT_METADATA_MAX_BYTES,
|
|
25
|
+
AGENT_METADATA_MAX_KEYS: () => AGENT_METADATA_MAX_KEYS,
|
|
26
|
+
AGENT_OUTCOMES: () => AGENT_OUTCOMES,
|
|
27
|
+
AGENT_TOOL_CALLS_PER_TURN: () => AGENT_TOOL_CALLS_PER_TURN,
|
|
28
|
+
AGENT_TOOL_STATUSES: () => AGENT_TOOL_STATUSES,
|
|
29
|
+
AGENT_TURNS_PER_BATCH: () => AGENT_TURNS_PER_BATCH,
|
|
30
|
+
AGENT_TURN_MAX_TEXT: () => AGENT_TURN_MAX_TEXT,
|
|
31
|
+
AGENT_TURN_ROLES: () => AGENT_TURN_ROLES,
|
|
24
32
|
ANNOTATION_COLORS: () => ANNOTATION_COLORS,
|
|
33
|
+
APP_LIFECYCLE_EVENTS: () => APP_LIFECYCLE_EVENTS,
|
|
25
34
|
ARTICLE_VISIBILITIES: () => ARTICLE_VISIBILITIES,
|
|
26
35
|
AUTOCAPTURE_EVENTS: () => AUTOCAPTURE_EVENTS,
|
|
36
|
+
AgentEventsRequestSchema: () => AgentEventsRequestSchema,
|
|
37
|
+
AgentMetadataSchema: () => AgentMetadataSchema,
|
|
38
|
+
AgentToolCallSchema: () => AgentToolCallSchema,
|
|
39
|
+
AgentTurnInputSchema: () => AgentTurnInputSchema,
|
|
27
40
|
AppearanceSchema: () => AppearanceSchema,
|
|
28
41
|
AuthoringPickSchema: () => AuthoringPickSchema,
|
|
29
42
|
AutocaptureSettingsSchema: () => AutocaptureSettingsSchema,
|
|
@@ -31,9 +44,11 @@ __export(index_exports, {
|
|
|
31
44
|
ButtonSchema: () => ButtonSchema,
|
|
32
45
|
CAPTURE_PARAM: () => CAPTURE_PARAM,
|
|
33
46
|
CAPTURE_SCREENSHOT_MAX_BYTES: () => CAPTURE_SCREENSHOT_MAX_BYTES,
|
|
47
|
+
COMMON_LOCALES: () => COMMON_LOCALES,
|
|
34
48
|
COMPLAINT_EVENTS: () => COMPLAINT_EVENTS,
|
|
35
49
|
COMPLAINT_FIELD_TYPES: () => COMPLAINT_FIELD_TYPES,
|
|
36
50
|
COMPLAINT_STATUSES: () => COMPLAINT_STATUSES,
|
|
51
|
+
CONTROL_VARIANT_ID: () => CONTROL_VARIANT_ID,
|
|
37
52
|
CaptureStepSchema: () => CaptureStepSchema,
|
|
38
53
|
CapturedElementSchema: () => CapturedElementSchema,
|
|
39
54
|
ChecklistConfigSchema: () => ChecklistConfigSchema,
|
|
@@ -42,28 +57,54 @@ __export(index_exports, {
|
|
|
42
57
|
ConversationLookupSchema: () => ConversationLookupSchema,
|
|
43
58
|
ConversationRatingSchema: () => ConversationRatingSchema,
|
|
44
59
|
DEFAULT_CAPTURE_SETTINGS: () => DEFAULT_CAPTURE_SETTINGS,
|
|
60
|
+
DEFAULT_FEATURE_ATTRIBUTE: () => DEFAULT_FEATURE_ATTRIBUTE,
|
|
61
|
+
DEFAULT_LOCALE: () => DEFAULT_LOCALE,
|
|
45
62
|
DEFAULT_PLATFORMS: () => DEFAULT_PLATFORMS,
|
|
46
63
|
EMBED_IFRAME_ATTRS: () => EMBED_IFRAME_ATTRS,
|
|
47
64
|
EVENT_NAMES: () => EVENT_NAMES,
|
|
48
65
|
ErrorTrackingSettingsSchema: () => ErrorTrackingSettingsSchema,
|
|
49
66
|
EventBatchSchema: () => EventBatchSchema,
|
|
67
|
+
FEATURE_ATTRIBUTE_PATTERN: () => FEATURE_ATTRIBUTE_PATTERN,
|
|
68
|
+
FEATURE_RULE_LIMITS: () => FEATURE_RULE_LIMITS,
|
|
69
|
+
FEEDBACK_EVENTS: () => FEEDBACK_EVENTS,
|
|
70
|
+
FEEDBACK_PRIORITIES: () => FEEDBACK_PRIORITIES,
|
|
71
|
+
FEEDBACK_PRIORITY_LABEL: () => FEEDBACK_PRIORITY_LABEL,
|
|
72
|
+
FEEDBACK_PRIORITY_WEIGHT: () => FEEDBACK_PRIORITY_WEIGHT,
|
|
73
|
+
FEEDBACK_STATUSES: () => FEEDBACK_STATUSES,
|
|
74
|
+
FEEDBACK_STATUS_LABEL: () => FEEDBACK_STATUS_LABEL,
|
|
50
75
|
FILE_LINK_CLASS: () => FILE_LINK_CLASS,
|
|
76
|
+
FeedbackCommentSchema: () => FeedbackCommentSchema,
|
|
77
|
+
FeedbackFollowSchema: () => FeedbackFollowSchema,
|
|
78
|
+
FeedbackListRequestSchema: () => FeedbackListRequestSchema,
|
|
79
|
+
FeedbackSimilarSchema: () => FeedbackSimilarSchema,
|
|
80
|
+
FeedbackUpdatesReadSchema: () => FeedbackUpdatesReadSchema,
|
|
81
|
+
FeedbackVisitorSchema: () => FeedbackVisitorSchema,
|
|
82
|
+
FeedbackVoteSchema: () => FeedbackVoteSchema,
|
|
51
83
|
FileComplaintSchema: () => FileComplaintSchema,
|
|
52
84
|
FrequencySchema: () => FrequencySchema,
|
|
53
85
|
GUIDELY_ID_ATTRIBUTE: () => GUIDELY_ID_ATTRIBUTE,
|
|
86
|
+
GUIDE_EXPERIMENT_GOALS: () => GUIDE_EXPERIMENT_GOALS,
|
|
87
|
+
GUIDE_EXPERIMENT_GOAL_LABELS: () => GUIDE_EXPERIMENT_GOAL_LABELS,
|
|
88
|
+
GUIDE_EXPERIMENT_STATUSES: () => GUIDE_EXPERIMENT_STATUSES,
|
|
54
89
|
GUIDE_KINDS: () => GUIDE_KINDS,
|
|
55
90
|
GUIDE_LIFECYCLE_EVENTS: () => GUIDE_LIFECYCLE_EVENTS,
|
|
56
91
|
GUIDE_STATUSES: () => GUIDE_STATUSES,
|
|
57
92
|
GUIDE_TEMPLATES: () => GUIDE_TEMPLATES,
|
|
58
93
|
GUIDE_VISIBILITIES: () => GUIDE_VISIBILITIES,
|
|
59
94
|
GuideConfigSchema: () => GuideConfigSchema,
|
|
95
|
+
GuideLocalizationSchema: () => GuideLocalizationSchema,
|
|
96
|
+
GuideScheduleSchema: () => GuideScheduleSchema,
|
|
60
97
|
GuideStateUpdateSchema: () => GuideStateUpdateSchema,
|
|
98
|
+
GuideThrottlingSchema: () => GuideThrottlingSchema,
|
|
61
99
|
HEATMAP_VIEWPORTS: () => HEATMAP_VIEWPORTS,
|
|
62
100
|
HOWTO_ACTIONS: () => HOWTO_ACTIONS,
|
|
63
101
|
HOWTO_STEP_KINDS: () => HOWTO_STEP_KINDS,
|
|
64
102
|
HowToAnnotationSchema: () => HowToAnnotationSchema,
|
|
65
103
|
IdentifyRequestSchema: () => IdentifyRequestSchema,
|
|
104
|
+
LOCALE_PATTERN: () => LOCALE_PATTERN,
|
|
66
105
|
LOGGED_IN_AUDIENCE: () => LOGGED_IN_AUDIENCE,
|
|
106
|
+
LocaleSchema: () => LocaleSchema,
|
|
107
|
+
LocalizationSettingsSchema: () => LocalizationSettingsSchema,
|
|
67
108
|
MAX_ANNOTATIONS: () => MAX_ANNOTATIONS,
|
|
68
109
|
MAX_COLLECTION_DEPTH: () => MAX_COLLECTION_DEPTH,
|
|
69
110
|
MAX_COMPLAINT_ANSWER_LENGTH: () => MAX_COMPLAINT_ANSWER_LENGTH,
|
|
@@ -71,6 +112,11 @@ __export(index_exports, {
|
|
|
71
112
|
MAX_COMPLAINT_CHOICES: () => MAX_COMPLAINT_CHOICES,
|
|
72
113
|
MAX_COMPLAINT_FIELDS: () => MAX_COMPLAINT_FIELDS,
|
|
73
114
|
MAX_COMPLAINT_LENGTH: () => MAX_COMPLAINT_LENGTH,
|
|
115
|
+
MAX_CUSTOM_CSS: () => MAX_CUSTOM_CSS,
|
|
116
|
+
MAX_FEEDBACK_COMMENT: () => MAX_FEEDBACK_COMMENT,
|
|
117
|
+
MAX_FEEDBACK_DESCRIPTION: () => MAX_FEEDBACK_DESCRIPTION,
|
|
118
|
+
MAX_FEEDBACK_NOTE: () => MAX_FEEDBACK_NOTE,
|
|
119
|
+
MAX_FEEDBACK_TITLE: () => MAX_FEEDBACK_TITLE,
|
|
74
120
|
MAX_MESSAGE_LENGTH: () => MAX_MESSAGE_LENGTH,
|
|
75
121
|
MAX_PROPERTY_BYTES: () => MAX_PROPERTY_BYTES,
|
|
76
122
|
MAX_STACK_FRAMES: () => MAX_STACK_FRAMES,
|
|
@@ -84,8 +130,10 @@ __export(index_exports, {
|
|
|
84
130
|
MESSAGE_AUTHORS: () => MESSAGE_AUTHORS,
|
|
85
131
|
MessengerPageRequestSchema: () => MessengerPageRequestSchema,
|
|
86
132
|
NETWORK_PLUGIN: () => NETWORK_PLUGIN,
|
|
133
|
+
NOISY_DATA_ATTR: () => NOISY_DATA_ATTR,
|
|
87
134
|
NormalizedPointSchema: () => NormalizedPointSchema,
|
|
88
135
|
NormalizedRectSchema: () => NormalizedRectSchema,
|
|
136
|
+
PAGE_RULE_LIMITS: () => PAGE_RULE_LIMITS,
|
|
89
137
|
PATH_ID_PATTERN: () => PATH_ID_PATTERN,
|
|
90
138
|
PDF_BLOCK_CLASS: () => PDF_BLOCK_CLASS,
|
|
91
139
|
PDF_MAX_PAGES: () => PDF_MAX_PAGES,
|
|
@@ -95,6 +143,8 @@ __export(index_exports, {
|
|
|
95
143
|
PostMessageSchema: () => PostMessageSchema,
|
|
96
144
|
ProjectThemeSchema: () => ProjectThemeSchema,
|
|
97
145
|
PublishedGuideSchema: () => PublishedGuideSchema,
|
|
146
|
+
RC_MODULE_IDS: () => RC_MODULE_IDS,
|
|
147
|
+
RC_MODULE_LABELS: () => RC_MODULE_LABELS,
|
|
98
148
|
REPLAY_MAX_COMPRESSED_BYTES: () => REPLAY_MAX_COMPRESSED_BYTES,
|
|
99
149
|
REPLAY_MAX_RAW_BYTES: () => REPLAY_MAX_RAW_BYTES,
|
|
100
150
|
REPLY_TIMES: () => REPLY_TIMES,
|
|
@@ -104,6 +154,7 @@ __export(index_exports, {
|
|
|
104
154
|
ReplaySettingsSchema: () => ReplaySettingsSchema,
|
|
105
155
|
RuleGroupSchema: () => RuleGroupSchema,
|
|
106
156
|
RuleSchema: () => RuleSchema,
|
|
157
|
+
SCOUT_AGENT_ID: () => SCOUT_AGENT_ID,
|
|
107
158
|
SCRIPT_STUB: () => SCRIPT_STUB,
|
|
108
159
|
SCRIPT_STUB_METHODS: () => SCRIPT_STUB_METHODS,
|
|
109
160
|
SDK_API_VERSION: () => SDK_API_VERSION,
|
|
@@ -115,30 +166,46 @@ __export(index_exports, {
|
|
|
115
166
|
SHARED_VERSION: () => SHARED_VERSION,
|
|
116
167
|
SHOW_ME_CLASS: () => SHOW_ME_CLASS,
|
|
117
168
|
SHOW_ME_HREF_PREFIX: () => SHOW_ME_HREF_PREFIX,
|
|
169
|
+
SNAPSHOT_ATTRS: () => SNAPSHOT_ATTRS,
|
|
170
|
+
SNAPSHOT_LIMITS: () => SNAPSHOT_LIMITS,
|
|
118
171
|
SOURCEMAP_MAX_FILES_PER_UPLOAD: () => SOURCEMAP_MAX_FILES_PER_UPLOAD,
|
|
119
172
|
SOURCEMAP_MAX_FILE_BYTES: () => SOURCEMAP_MAX_FILE_BYTES,
|
|
120
173
|
STATUS_LEVELS: () => STATUS_LEVELS,
|
|
121
174
|
STEP_TYPES: () => STEP_TYPES,
|
|
122
175
|
SURVEY_QUESTION_TYPES: () => SURVEY_QUESTION_TYPES,
|
|
176
|
+
SdkAgentEventsSchema: () => SdkAgentEventsSchema,
|
|
123
177
|
SdkEventSchema: () => SdkEventSchema,
|
|
124
178
|
SelectorStrategySchema: () => SelectorStrategySchema,
|
|
179
|
+
SelectorSyntaxError: () => SelectorSyntaxError,
|
|
125
180
|
StartConversationSchema: () => StartConversationSchema,
|
|
126
181
|
StepBranchSchema: () => StepBranchSchema,
|
|
127
182
|
StepSchema: () => StepSchema,
|
|
183
|
+
SubmitFeedbackSchema: () => SubmitFeedbackSchema,
|
|
128
184
|
SurveyConfigSchema: () => SurveyConfigSchema,
|
|
129
185
|
SurveyQuestionSchema: () => SurveyQuestionSchema,
|
|
130
186
|
SurveyResponseRequestSchema: () => SurveyResponseRequestSchema,
|
|
187
|
+
TAG_PROPERTY_LIMITS: () => TAG_PROPERTY_LIMITS,
|
|
131
188
|
TRIGGER_TYPES: () => TRIGGER_TYPES,
|
|
132
189
|
TargetSchema: () => TargetSchema,
|
|
133
190
|
TriggerSchema: () => TriggerSchema,
|
|
134
191
|
VIDEO_ATTRS: () => VIDEO_ATTRS,
|
|
192
|
+
WCAG_AA_LARGE: () => WCAG_AA_LARGE,
|
|
193
|
+
WCAG_AA_TEXT: () => WCAG_AA_TEXT,
|
|
135
194
|
WS_MAX_MESSAGES_PER_SOCKET: () => WS_MAX_MESSAGES_PER_SOCKET,
|
|
136
195
|
WS_MAX_MESSAGE_BYTES: () => WS_MAX_MESSAGE_BYTES,
|
|
196
|
+
applyGuideTranslations: () => applyGuideTranslations,
|
|
197
|
+
articleTextEntries: () => articleTextEntries,
|
|
198
|
+
assignGuideVariant: () => assignGuideVariant,
|
|
199
|
+
baseLanguage: () => baseLanguage,
|
|
137
200
|
clamp: () => clamp,
|
|
138
201
|
cleanLabel: () => cleanLabel,
|
|
139
202
|
compare: () => compare,
|
|
140
203
|
compareVersions: () => compareVersions,
|
|
141
204
|
complaintReference: () => complaintReference,
|
|
205
|
+
compoundMatches: () => compoundMatches,
|
|
206
|
+
contrastIssues: () => contrastIssues,
|
|
207
|
+
contrastRatio: () => contrastRatio,
|
|
208
|
+
cssSelectorError: () => cssSelectorError,
|
|
142
209
|
defaultGuideConfig: () => defaultGuideConfig,
|
|
143
210
|
defaultStep: () => defaultStep,
|
|
144
211
|
describeCaptureStep: () => describeCaptureStep,
|
|
@@ -146,12 +213,21 @@ __export(index_exports, {
|
|
|
146
213
|
emptyRuleGroup: () => emptyRuleGroup,
|
|
147
214
|
evaluateRule: () => evaluateRule,
|
|
148
215
|
evaluateRules: () => evaluateRules,
|
|
216
|
+
evenWeights: () => evenWeights,
|
|
217
|
+
experimentBucketRules: () => experimentBucketRules,
|
|
218
|
+
experimentSalt: () => experimentSalt,
|
|
219
|
+
featureCssSelectors: () => featureCssSelectors,
|
|
220
|
+
featureRuleError: () => featureRuleError,
|
|
221
|
+
featureRuleMatchesClick: () => featureRuleMatchesClick,
|
|
222
|
+
feedbackReference: () => feedbackReference,
|
|
149
223
|
fingerprintError: () => fingerprintError,
|
|
150
224
|
firstNameFromTraits: () => firstNameFromTraits,
|
|
151
225
|
fnv1a: () => fnv1a,
|
|
152
226
|
foldPathIds: () => foldPathIds,
|
|
153
227
|
getPath: () => getPath,
|
|
228
|
+
guideLocales: () => guideLocales,
|
|
154
229
|
guidePlatforms: () => guidePlatforms,
|
|
230
|
+
guideTextEntries: () => guideTextEntries,
|
|
155
231
|
guidelyIdFromSelector: () => guidelyIdFromSelector,
|
|
156
232
|
hasVideoMedia: () => hasVideoMedia,
|
|
157
233
|
isAllowedEmbedSrc: () => isAllowedEmbedSrc,
|
|
@@ -164,6 +240,12 @@ __export(index_exports, {
|
|
|
164
240
|
isRuleGroup: () => isRuleGroup,
|
|
165
241
|
isSafeMediaUrl: () => isSafeMediaUrl,
|
|
166
242
|
isVideoContentType: () => isVideoContentType,
|
|
243
|
+
localeName: () => localeName,
|
|
244
|
+
localizeAnnouncement: () => localizeAnnouncement,
|
|
245
|
+
localizeArticle: () => localizeArticle,
|
|
246
|
+
localizeGuide: () => localizeGuide,
|
|
247
|
+
localizeResourceCenter: () => localizeResourceCenter,
|
|
248
|
+
matchCssSelector: () => matchCssSelector,
|
|
167
249
|
matchUrlPattern: () => matchUrlPattern,
|
|
168
250
|
matchesAudiences: () => matchesAudiences,
|
|
169
251
|
matchesHelpQuery: () => matchesHelpQuery,
|
|
@@ -171,16 +253,37 @@ __export(index_exports, {
|
|
|
171
253
|
mediaMaxBytes: () => mediaMaxBytes,
|
|
172
254
|
normalizeErrorMessage: () => normalizeErrorMessage,
|
|
173
255
|
normalizeFrameFile: () => normalizeFrameFile,
|
|
256
|
+
normalizeLocale: () => normalizeLocale,
|
|
257
|
+
normalizeSnapshot: () => normalizeSnapshot,
|
|
258
|
+
orderedModules: () => orderedModules,
|
|
174
259
|
pageLabel: () => pageLabel,
|
|
175
260
|
pageName: () => pageName,
|
|
261
|
+
pagePattern: () => pagePattern,
|
|
262
|
+
pageRuleError: () => pageRuleError,
|
|
263
|
+
pageRuleMatches: () => pageRuleMatches,
|
|
264
|
+
pageRulesMatch: () => pageRulesMatch,
|
|
176
265
|
pageTerms: () => pageTerms,
|
|
266
|
+
parseCssSelector: () => parseCssSelector,
|
|
267
|
+
parseCsvRows: () => parseCsvRows,
|
|
268
|
+
parseHexColor: () => parseHexColor,
|
|
177
269
|
parseStack: () => parseStack,
|
|
270
|
+
parseTranslationCsv: () => parseTranslationCsv,
|
|
271
|
+
parseXliff: () => parseXliff,
|
|
272
|
+
propertyAttributeAllowed: () => propertyAttributeAllowed,
|
|
273
|
+
queryConditionRegex: () => queryConditionRegex,
|
|
178
274
|
randomId: () => randomId,
|
|
275
|
+
readableTextOn: () => readableTextOn,
|
|
276
|
+
relativeLuminance: () => relativeLuminance,
|
|
179
277
|
resolveCaptureSettings: () => resolveCaptureSettings,
|
|
278
|
+
resolveLocale: () => resolveLocale,
|
|
279
|
+
resourceCenterLocales: () => resourceCenterLocales,
|
|
180
280
|
resourceCenterSections: () => resourceCenterSections,
|
|
281
|
+
resourceCenterTextEntries: () => resourceCenterTextEntries,
|
|
181
282
|
rolloutBucket: () => rolloutBucket,
|
|
182
283
|
safeRegExp: () => safeRegExp,
|
|
284
|
+
sanitizeCustomCss: () => sanitizeCustomCss,
|
|
183
285
|
sanitizeProperties: () => sanitizeProperties,
|
|
286
|
+
scopeCustomCss: () => scopeCustomCss,
|
|
184
287
|
screenPath: () => screenPath,
|
|
185
288
|
scriptSnippet: () => scriptSnippet,
|
|
186
289
|
servedArticleAudiences: () => servedArticleAudiences,
|
|
@@ -188,14 +291,25 @@ __export(index_exports, {
|
|
|
188
291
|
showMeKeyFromHref: () => showMeKeyFromHref,
|
|
189
292
|
showMeKeys: () => showMeKeys,
|
|
190
293
|
slugify: () => slugify,
|
|
294
|
+
snapshotFromSelector: () => snapshotFromSelector,
|
|
295
|
+
stableStringify: () => stableStringify,
|
|
191
296
|
stripOrigin: () => stripOrigin,
|
|
192
297
|
supportsPlatform: () => supportsPlatform,
|
|
193
298
|
templateConfig: () => templateConfig,
|
|
194
299
|
toEmbedUrl: () => toEmbedUrl,
|
|
300
|
+
toTranslationCsv: () => toTranslationCsv,
|
|
301
|
+
toXliff: () => toXliff,
|
|
302
|
+
translationCoverage: () => translationCoverage,
|
|
303
|
+
unreadAnnouncements: () => unreadAnnouncements,
|
|
195
304
|
validateGuideConfig: () => validateGuideConfig,
|
|
305
|
+
variantProblems: () => variantProblems,
|
|
306
|
+
variantRanges: () => variantRanges,
|
|
307
|
+
visibleAnnouncements: () => visibleAnnouncements,
|
|
196
308
|
visibleArticleIds: () => visibleArticleIds,
|
|
197
309
|
visibleButtons: () => visibleButtons,
|
|
198
310
|
visitorAudiences: () => visitorAudiences,
|
|
311
|
+
visitorLocales: () => visitorLocales,
|
|
312
|
+
withExperimentBucket: () => withExperimentBucket,
|
|
199
313
|
withVisibility: () => withVisibility
|
|
200
314
|
});
|
|
201
315
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -390,17 +504,21 @@ var RULE_FIELDS = [
|
|
|
390
504
|
"datetime.dayOfWeek",
|
|
391
505
|
"datetime.hour",
|
|
392
506
|
"rollout.percentage",
|
|
507
|
+
/** Guide A/B tests: the visitor's 0-99 bucket for the salt in `key` (see guide-experiments.ts). */
|
|
508
|
+
"experiment.bucket",
|
|
393
509
|
"environment",
|
|
394
510
|
"locale",
|
|
395
511
|
"app.platform",
|
|
396
512
|
"app.screen",
|
|
397
|
-
"app.version"
|
|
513
|
+
"app.version",
|
|
514
|
+
"page.views",
|
|
515
|
+
"feature.clicks"
|
|
398
516
|
];
|
|
399
517
|
function isRuleGroup(r) {
|
|
400
518
|
return r.rules !== void 0;
|
|
401
519
|
}
|
|
402
|
-
function emptyRuleGroup(
|
|
403
|
-
return { id, op: "and", rules: [] };
|
|
520
|
+
function emptyRuleGroup(id2 = "root") {
|
|
521
|
+
return { id: id2, op: "and", rules: [] };
|
|
404
522
|
}
|
|
405
523
|
function has(set, v) {
|
|
406
524
|
if (!set) return false;
|
|
@@ -454,6 +572,8 @@ function resolveField(rule, ctx) {
|
|
|
454
572
|
return ctx.now.getHours();
|
|
455
573
|
case "rollout.percentage":
|
|
456
574
|
return rolloutBucket(ctx.userId || ctx.anonymousId, ctx.rolloutSalt || "guidely");
|
|
575
|
+
case "experiment.bucket":
|
|
576
|
+
return rule.key ? rolloutBucket(ctx.userId || ctx.anonymousId, rule.key) : void 0;
|
|
457
577
|
case "environment":
|
|
458
578
|
return ctx.environment;
|
|
459
579
|
case "locale":
|
|
@@ -464,6 +584,9 @@ function resolveField(rule, ctx) {
|
|
|
464
584
|
return ctx.screen;
|
|
465
585
|
case "app.version":
|
|
466
586
|
return ctx.appVersion;
|
|
587
|
+
case "page.views":
|
|
588
|
+
case "feature.clicks":
|
|
589
|
+
return rule.key ? ctx.tagUsage?.[rule.key] ?? 0 : 0;
|
|
467
590
|
default:
|
|
468
591
|
return void 0;
|
|
469
592
|
}
|
|
@@ -563,7 +686,7 @@ function evaluateRules(group, ctx) {
|
|
|
563
686
|
const value = group.op === "and" ? results.every(Boolean) : results.some(Boolean);
|
|
564
687
|
return group.negate ? !value : value;
|
|
565
688
|
}
|
|
566
|
-
var SERVER_ASSISTED_FIELDS = ["audience.member", "guide.completed", "guide.dismissed", "guide.seen", "checklist.completed"];
|
|
689
|
+
var SERVER_ASSISTED_FIELDS = ["audience.member", "guide.completed", "guide.dismissed", "guide.seen", "checklist.completed", "page.views", "feature.clicks"];
|
|
567
690
|
var GUIDE_VISIBILITIES = ["everyone", "identified", "anonymous"];
|
|
568
691
|
function withVisibility(targeting, visibility) {
|
|
569
692
|
if (!visibility || visibility === "everyone") return targeting;
|
|
@@ -595,6 +718,57 @@ var RuleGroupSchema = import_zod.z.lazy(
|
|
|
595
718
|
|
|
596
719
|
// src/guide.ts
|
|
597
720
|
var import_zod2 = require("zod");
|
|
721
|
+
|
|
722
|
+
// src/contrast.ts
|
|
723
|
+
var WCAG_AA_TEXT = 4.5;
|
|
724
|
+
var WCAG_AA_LARGE = 3;
|
|
725
|
+
function channel(c) {
|
|
726
|
+
const s = c / 255;
|
|
727
|
+
return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
|
|
728
|
+
}
|
|
729
|
+
function parseHexColor(hex) {
|
|
730
|
+
if (!hex) return null;
|
|
731
|
+
const m = hex.trim().match(/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i);
|
|
732
|
+
if (!m) return null;
|
|
733
|
+
const h = m[1].length === 3 ? m[1].split("").map((c) => c + c).join("") : m[1];
|
|
734
|
+
return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];
|
|
735
|
+
}
|
|
736
|
+
function relativeLuminance(hex) {
|
|
737
|
+
const rgb = parseHexColor(hex);
|
|
738
|
+
if (!rgb) return null;
|
|
739
|
+
return 0.2126 * channel(rgb[0]) + 0.7152 * channel(rgb[1]) + 0.0722 * channel(rgb[2]);
|
|
740
|
+
}
|
|
741
|
+
function contrastRatio(a, b) {
|
|
742
|
+
const la = relativeLuminance(a);
|
|
743
|
+
const lb = relativeLuminance(b);
|
|
744
|
+
if (la === null || lb === null) return null;
|
|
745
|
+
const [hi, lo] = la > lb ? [la, lb] : [lb, la];
|
|
746
|
+
return Math.round((hi + 0.05) / (lo + 0.05) * 100) / 100;
|
|
747
|
+
}
|
|
748
|
+
function readableTextOn(background) {
|
|
749
|
+
const white = contrastRatio(background, "#ffffff") ?? 0;
|
|
750
|
+
const dark = contrastRatio(background, "#111827") ?? 0;
|
|
751
|
+
return white >= dark ? "#ffffff" : "#111827";
|
|
752
|
+
}
|
|
753
|
+
function contrastIssues(colors) {
|
|
754
|
+
const issues = [];
|
|
755
|
+
const { primaryColor, backgroundColor, textColor } = colors;
|
|
756
|
+
if (textColor && backgroundColor) {
|
|
757
|
+
const r = contrastRatio(textColor, backgroundColor);
|
|
758
|
+
if (r !== null && r < WCAG_AA_TEXT) issues.push({ pair: "text", ratio: r, required: WCAG_AA_TEXT, message: `Text on the background has a contrast of ${r}:1; WCAG AA needs ${WCAG_AA_TEXT}:1.` });
|
|
759
|
+
}
|
|
760
|
+
if (primaryColor) {
|
|
761
|
+
const label = contrastRatio(primaryColor, readableTextOn(primaryColor));
|
|
762
|
+
if (label !== null && label < WCAG_AA_TEXT) issues.push({ pair: "button", ratio: label, required: WCAG_AA_TEXT, message: `Button labels on the primary colour have a contrast of ${label}:1; WCAG AA needs ${WCAG_AA_TEXT}:1.` });
|
|
763
|
+
if (backgroundColor) {
|
|
764
|
+
const link = contrastRatio(primaryColor, backgroundColor);
|
|
765
|
+
if (link !== null && link < WCAG_AA_LARGE) issues.push({ pair: "link", ratio: link, required: WCAG_AA_LARGE, message: `The primary colour on the background (links, outlined buttons) has a contrast of ${link}:1; WCAG AA needs ${WCAG_AA_LARGE}:1.` });
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
return issues;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
// src/guide.ts
|
|
598
772
|
var GUIDE_KINDS = ["flow", "modal", "tooltip", "banner", "checklist", "survey", "announcement"];
|
|
599
773
|
var GUIDE_STATUSES = ["draft", "published", "paused", "archived"];
|
|
600
774
|
var STEP_TYPES = ["modal", "tooltip", "popover", "spotlight", "hotspot", "banner", "slideout", "checklist", "custom", "survey"];
|
|
@@ -643,6 +817,8 @@ var StepSchema = import_zod2.z.object({
|
|
|
643
817
|
/** Sanitized HTML body (links, images, lists, formatting). */
|
|
644
818
|
body: import_zod2.z.string().max(2e4).default(""),
|
|
645
819
|
imageUrl: import_zod2.z.string().url().max(2e3).optional().or(import_zod2.z.literal("")),
|
|
820
|
+
/** Alternative text for `imageUrl` (screen readers); empty = decorative. */
|
|
821
|
+
imageAlt: import_zod2.z.string().max(300).optional(),
|
|
646
822
|
buttons: import_zod2.z.array(ButtonSchema).max(6).default([]),
|
|
647
823
|
target: TargetSchema.optional(),
|
|
648
824
|
placement: import_zod2.z.enum(PLACEMENTS).default("auto"),
|
|
@@ -669,7 +845,12 @@ var StepSchema = import_zod2.z.object({
|
|
|
669
845
|
/** Hotspot pulse dot settings. */
|
|
670
846
|
hotspot: import_zod2.z.object({ size: import_zod2.z.number().int().min(8).max(40).default(14), pulse: import_zod2.z.boolean().default(true), openOn: import_zod2.z.enum(["click", "hover"]).default("click") }).optional(),
|
|
671
847
|
/** Custom step: arbitrary sanitized HTML with no chrome. */
|
|
672
|
-
customHtml: import_zod2.z.string().max(5e4).optional()
|
|
848
|
+
customHtml: import_zod2.z.string().max(5e4).optional(),
|
|
849
|
+
/**
|
|
850
|
+
* Code block (custom steps only): JavaScript run on the web when the step shows, only while the
|
|
851
|
+
* workspace allows code blocks (an admin setting, off by default). Mobile SDKs never receive it.
|
|
852
|
+
*/
|
|
853
|
+
code: import_zod2.z.string().max(2e4).optional()
|
|
673
854
|
});
|
|
674
855
|
var TRIGGER_TYPES = ["page_load", "url_match", "event", "element_click", "element_visible", "manual", "delay", "after_guide", "segment_enter"];
|
|
675
856
|
var TriggerSchema = import_zod2.z.object({
|
|
@@ -691,7 +872,9 @@ var FrequencySchema = import_zod2.z.object({
|
|
|
691
872
|
/** Guide ids that must not be active at the same time. */
|
|
692
873
|
mutuallyExclusiveWith: import_zod2.z.array(import_zod2.z.string()).max(50).default([]),
|
|
693
874
|
/** Re-show if dismissed (otherwise dismissal counts as completion for frequency). */
|
|
694
|
-
reshowAfterDismiss: import_zod2.z.boolean().default(false)
|
|
875
|
+
reshowAfterDismiss: import_zod2.z.boolean().default(false),
|
|
876
|
+
/** Bypass the project's guide throttling (always eligible as far as throttling goes). */
|
|
877
|
+
ignoreThrottling: import_zod2.z.boolean().optional()
|
|
695
878
|
});
|
|
696
879
|
var AppearanceSchema = import_zod2.z.object({
|
|
697
880
|
theme: import_zod2.z.enum(["light", "dark", "auto"]).default("auto"),
|
|
@@ -703,7 +886,9 @@ var AppearanceSchema = import_zod2.z.object({
|
|
|
703
886
|
overlayOpacity: import_zod2.z.number().min(0).max(1).optional(),
|
|
704
887
|
zIndex: import_zod2.z.number().int().min(1).max(2147483647).optional(),
|
|
705
888
|
preset: import_zod2.z.string().max(50).optional(),
|
|
706
|
-
animation: import_zod2.z.enum(["fade", "slide", "none"]).default("fade")
|
|
889
|
+
animation: import_zod2.z.enum(["fade", "slide", "none"]).default("fade"),
|
|
890
|
+
/** Custom CSS scoped to this guide's container (sanitized; see custom-css.ts). Web only. */
|
|
891
|
+
customCss: import_zod2.z.string().max(2e4).optional()
|
|
707
892
|
});
|
|
708
893
|
var ChecklistTaskSchema = import_zod2.z.object({
|
|
709
894
|
id: import_zod2.z.string().min(1),
|
|
@@ -750,6 +935,26 @@ var SurveyConfigSchema = import_zod2.z.object({
|
|
|
750
935
|
startAt: import_zod2.z.string().datetime().optional(),
|
|
751
936
|
endAt: import_zod2.z.string().datetime().optional()
|
|
752
937
|
});
|
|
938
|
+
var GuideScheduleSchema = import_zod2.z.object({
|
|
939
|
+
startAt: import_zod2.z.string().datetime().optional(),
|
|
940
|
+
endAt: import_zod2.z.string().datetime().optional(),
|
|
941
|
+
timezone: import_zod2.z.string().max(64).optional()
|
|
942
|
+
});
|
|
943
|
+
var LOCALE_PATTERN = /^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8}){0,2}$/;
|
|
944
|
+
var LocaleSchema = import_zod2.z.string().regex(LOCALE_PATTERN, "Use a language code such as fr or pt-BR").max(20);
|
|
945
|
+
var GuideLocalizationSchema = import_zod2.z.object({
|
|
946
|
+
translations: import_zod2.z.record(LocaleSchema, import_zod2.z.record(import_zod2.z.string().max(200), import_zod2.z.string().max(5e4))).default({})
|
|
947
|
+
});
|
|
948
|
+
var LocalizationSettingsSchema = import_zod2.z.object({
|
|
949
|
+
defaultLocale: LocaleSchema.default("en"),
|
|
950
|
+
locales: import_zod2.z.array(LocaleSchema).max(50).default([])
|
|
951
|
+
});
|
|
952
|
+
var GuideThrottlingSchema = import_zod2.z.object({
|
|
953
|
+
enabled: import_zod2.z.boolean().default(false),
|
|
954
|
+
maxGuides: import_zod2.z.number().int().min(1).max(50).default(1),
|
|
955
|
+
windowHours: import_zod2.z.number().int().min(1).max(720).default(24),
|
|
956
|
+
minGapMinutes: import_zod2.z.number().int().min(0).max(10080).default(0)
|
|
957
|
+
});
|
|
753
958
|
var GuideConfigSchema = import_zod2.z.object({
|
|
754
959
|
steps: import_zod2.z.array(StepSchema).max(50).default([]),
|
|
755
960
|
/** Everyone, only identified (logged-in) users, or only anonymous visitors; applied on top of `targeting`. */
|
|
@@ -763,7 +968,11 @@ var GuideConfigSchema = import_zod2.z.object({
|
|
|
763
968
|
/** Restrict guide to url pattern(s) (applied before trigger). On mobile these match the screen path `/<Screen>`. */
|
|
764
969
|
urlPatterns: import_zod2.z.array(import_zod2.z.string().max(500)).max(20).default([]),
|
|
765
970
|
/** Platforms that receive this guide. Guides created before mobile support are web-only. */
|
|
766
|
-
platforms: import_zod2.z.array(import_zod2.z.enum(PLATFORMS)).max(PLATFORMS.length).default(["web"])
|
|
971
|
+
platforms: import_zod2.z.array(import_zod2.z.enum(PLATFORMS)).max(PLATFORMS.length).default(["web"]),
|
|
972
|
+
/** Start / end window for any guide kind (surveys also honour `survey.startAt` / `endAt`). */
|
|
973
|
+
schedule: GuideScheduleSchema.optional(),
|
|
974
|
+
/** Translations (see localization.ts). */
|
|
975
|
+
localization: GuideLocalizationSchema.optional()
|
|
767
976
|
});
|
|
768
977
|
function defaultGuideConfig(kind) {
|
|
769
978
|
return GuideConfigSchema.parse({
|
|
@@ -797,7 +1006,7 @@ function defaultStep(type, overrides = {}) {
|
|
|
797
1006
|
function visibleButtons(step, canGoBack) {
|
|
798
1007
|
return canGoBack ? step.buttons : step.buttons.filter((b) => b.action !== "back");
|
|
799
1008
|
}
|
|
800
|
-
function validateGuideConfig(kind, config) {
|
|
1009
|
+
function validateGuideConfig(kind, config, theme) {
|
|
801
1010
|
const issues = [];
|
|
802
1011
|
if (kind === "checklist") {
|
|
803
1012
|
if (!config.checklist || config.checklist.tasks.length === 0) issues.push({ level: "error", message: "Checklist needs at least one task." });
|
|
@@ -834,6 +1043,15 @@ function validateGuideConfig(kind, config) {
|
|
|
834
1043
|
if (config.trigger.type === "element_click" && !config.trigger.value) issues.push({ level: "error", message: "Element click trigger needs a selector." });
|
|
835
1044
|
if (config.trigger.type === "url_match" && !config.trigger.value) issues.push({ level: "error", message: "URL trigger needs a pattern." });
|
|
836
1045
|
if (config.frequency.mode === "interval" && !config.frequency.intervalHours) issues.push({ level: "error", message: "Interval frequency needs an interval in hours." });
|
|
1046
|
+
const sched = config.schedule;
|
|
1047
|
+
if (sched?.startAt && sched.endAt && Date.parse(sched.endAt) <= Date.parse(sched.startAt)) issues.push({ level: "error", message: "The schedule ends before it starts." });
|
|
1048
|
+
if (sched?.endAt && Date.parse(sched.endAt) < Date.now()) issues.push({ level: "warning", message: "The schedule has already ended, so nobody will see this guide." });
|
|
1049
|
+
config.steps.forEach((step, i) => {
|
|
1050
|
+
if (step.code && step.type !== "custom") issues.push({ level: "error", stepId: step.id, message: `Step ${i + 1}: code blocks can only run in custom steps.` });
|
|
1051
|
+
if (step.code && mobile) issues.push({ level: "warning", stepId: step.id, message: `Step ${i + 1} runs a code block; mobile apps skip it.` });
|
|
1052
|
+
});
|
|
1053
|
+
const colors = { primaryColor: config.appearance.primaryColor ?? theme?.primaryColor, backgroundColor: config.appearance.backgroundColor ?? theme?.backgroundColor, textColor: config.appearance.textColor ?? theme?.textColor };
|
|
1054
|
+
for (const c of contrastIssues(colors)) issues.push({ level: "warning", message: `Low contrast: ${c.message}` });
|
|
837
1055
|
return issues;
|
|
838
1056
|
}
|
|
839
1057
|
var ProjectThemeSchema = import_zod2.z.object({
|
|
@@ -843,7 +1061,9 @@ var ProjectThemeSchema = import_zod2.z.object({
|
|
|
843
1061
|
borderRadius: import_zod2.z.number().int().min(0).max(32).default(12),
|
|
844
1062
|
fontFamily: import_zod2.z.string().max(200).default("Inter, system-ui, -apple-system, sans-serif"),
|
|
845
1063
|
logoUrl: import_zod2.z.string().max(2e3).optional(),
|
|
846
|
-
brandName: import_zod2.z.string().max(100).optional()
|
|
1064
|
+
brandName: import_zod2.z.string().max(100).optional(),
|
|
1065
|
+
/** Custom CSS applied to every guide's container (sanitized and scoped like guide CSS). Web only. */
|
|
1066
|
+
customCss: import_zod2.z.string().max(2e4).optional()
|
|
847
1067
|
});
|
|
848
1068
|
|
|
849
1069
|
// src/events.ts
|
|
@@ -859,8 +1079,8 @@ function sanitizeProperties(props) {
|
|
|
859
1079
|
for (const [k, v] of Object.entries(props)) {
|
|
860
1080
|
if (SENSITIVE_PROPERTY_PATTERN.test(k)) continue;
|
|
861
1081
|
if (typeof v === "function" || typeof v === "symbol") continue;
|
|
862
|
-
const
|
|
863
|
-
size += k.length + (
|
|
1082
|
+
const str2 = typeof v === "string" ? v : JSON.stringify(v ?? null);
|
|
1083
|
+
size += k.length + (str2?.length ?? 0);
|
|
864
1084
|
if (size > MAX_PROPERTY_BYTES) break;
|
|
865
1085
|
out[k.slice(0, 100)] = typeof v === "string" ? v.slice(0, 1e3) : v;
|
|
866
1086
|
}
|
|
@@ -940,9 +1160,15 @@ var EVENT_NAMES = [
|
|
|
940
1160
|
"exception",
|
|
941
1161
|
"heatmap",
|
|
942
1162
|
// Feature flags: a user was bucketed into an experiment variation (properties: experimentKey, variationId, flagKey).
|
|
943
|
-
"experiment_viewed"
|
|
1163
|
+
"experiment_viewed",
|
|
1164
|
+
// Mobile app lifecycle (mobile/SPEC.md "Product analytics"): installs, updates, opens and backgrounding.
|
|
1165
|
+
"app_install",
|
|
1166
|
+
"app_update",
|
|
1167
|
+
"app_open",
|
|
1168
|
+
"app_background"
|
|
944
1169
|
];
|
|
945
|
-
var AUTOCAPTURE_EVENTS = ["page_view", "page_leave", "click", "rage_click", "exception", "heatmap"];
|
|
1170
|
+
var AUTOCAPTURE_EVENTS = ["page_view", "page_leave", "click", "rage_click", "exception", "heatmap", "app_install", "app_update", "app_open", "app_background"];
|
|
1171
|
+
var APP_LIFECYCLE_EVENTS = ["app_install", "app_update", "app_open", "app_background"];
|
|
946
1172
|
var GUIDE_LIFECYCLE_EVENTS = ["guide_viewed", "guide_started", "step_viewed", "step_completed", "guide_completed", "guide_skipped", "guide_dismissed", "guide_abandoned"];
|
|
947
1173
|
var SdkEventSchema = import_zod3.z.object({
|
|
948
1174
|
eventId: import_zod3.z.string().min(8).max(64),
|
|
@@ -1010,7 +1236,9 @@ var AuthoringPickSchema = import_zod4.z.object({
|
|
|
1010
1236
|
selectors: import_zod4.z.array(import_zod4.z.object({ kind: import_zod4.z.string(), value: import_zod4.z.string().max(1e3), label: import_zod4.z.string().max(200).optional() })).max(10),
|
|
1011
1237
|
textSnapshot: import_zod4.z.string().max(200).optional(),
|
|
1012
1238
|
url: import_zod4.z.string().max(2e3).optional(),
|
|
1013
|
-
rect: import_zod4.z.object({ x: import_zod4.z.number(), y: import_zod4.z.number(), width: import_zod4.z.number(), height: import_zod4.z.number() }).optional()
|
|
1239
|
+
rect: import_zod4.z.object({ x: import_zod4.z.number(), y: import_zod4.z.number(), width: import_zod4.z.number(), height: import_zod4.z.number() }).optional(),
|
|
1240
|
+
/** Compact snapshot of the picked element (tag mode: feature rules are proposed from it). */
|
|
1241
|
+
elementSnapshot: import_zod4.z.record(import_zod4.z.unknown()).optional()
|
|
1014
1242
|
});
|
|
1015
1243
|
var PublishedGuideSchema = import_zod4.z.object({
|
|
1016
1244
|
id: import_zod4.z.string(),
|
|
@@ -1088,22 +1316,153 @@ var FileComplaintSchema = import_zod6.z.object({
|
|
|
1088
1316
|
}).optional().nullable()
|
|
1089
1317
|
});
|
|
1090
1318
|
|
|
1091
|
-
// src/
|
|
1319
|
+
// src/agents.ts
|
|
1092
1320
|
var import_zod7 = require("zod");
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
var
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1321
|
+
|
|
1322
|
+
// src/agents-limits.ts
|
|
1323
|
+
var AGENT_TURN_ROLES = ["user", "assistant", "tool", "system"];
|
|
1324
|
+
var AGENT_OUTCOMES = ["success", "failure", "escalated", "abandoned"];
|
|
1325
|
+
var AGENT_TOOL_STATUSES = ["ok", "error"];
|
|
1326
|
+
var AGENT_TURN_MAX_TEXT = 2e4;
|
|
1327
|
+
var AGENT_TURNS_PER_BATCH = 100;
|
|
1328
|
+
var AGENT_TOOL_CALLS_PER_TURN = 50;
|
|
1329
|
+
var AGENT_METADATA_MAX_KEYS = 30;
|
|
1330
|
+
var AGENT_METADATA_MAX_BYTES = 4096;
|
|
1331
|
+
var SCOUT_AGENT_ID = "scout";
|
|
1332
|
+
|
|
1333
|
+
// src/agents.ts
|
|
1334
|
+
var ENVIRONMENTS = ["development", "staging", "production"];
|
|
1335
|
+
var AgentToolCallSchema = import_zod7.z.object({
|
|
1336
|
+
name: import_zod7.z.string().trim().min(1).max(100),
|
|
1337
|
+
status: import_zod7.z.enum(AGENT_TOOL_STATUSES).optional(),
|
|
1338
|
+
latencyMs: import_zod7.z.number().int().min(0).max(36e5).optional()
|
|
1339
|
+
}).strip();
|
|
1340
|
+
var AgentMetadataSchema = import_zod7.z.record(import_zod7.z.string().max(100), import_zod7.z.unknown()).transform((m) => {
|
|
1341
|
+
const out = {};
|
|
1342
|
+
let size = 0;
|
|
1343
|
+
for (const [k, v] of Object.entries(m)) {
|
|
1344
|
+
const key = k.trim();
|
|
1345
|
+
if (!key || key.startsWith("$") || SENSITIVE_PROPERTY_PATTERN.test(key)) continue;
|
|
1346
|
+
if (!(typeof v === "string" || typeof v === "boolean" || v === null || typeof v === "number" && Number.isFinite(v))) continue;
|
|
1347
|
+
const value = typeof v === "string" ? v.slice(0, 500) : v;
|
|
1348
|
+
size += key.length + String(value).length;
|
|
1349
|
+
if (size > AGENT_METADATA_MAX_BYTES || Object.keys(out).length >= AGENT_METADATA_MAX_KEYS) break;
|
|
1350
|
+
out[key] = value;
|
|
1351
|
+
}
|
|
1352
|
+
return out;
|
|
1353
|
+
});
|
|
1354
|
+
var id = (max) => import_zod7.z.string().trim().min(1).max(max);
|
|
1355
|
+
var optionalId = (max) => import_zod7.z.string().trim().max(max).optional().nullable().transform((v) => v || null);
|
|
1356
|
+
var AgentTurnInputSchema = import_zod7.z.object({
|
|
1357
|
+
type: import_zod7.z.literal("agent.conversation").optional(),
|
|
1358
|
+
conversationId: id(128),
|
|
1359
|
+
agentId: id(64).refine((v) => v.toLowerCase() !== SCOUT_AGENT_ID, { message: `"${SCOUT_AGENT_ID}" is reserved for Guidely's built-in Scout agent` }),
|
|
1360
|
+
agentName: import_zod7.z.string().trim().max(100).optional(),
|
|
1361
|
+
turnId: import_zod7.z.string().trim().min(1).max(128).optional(),
|
|
1362
|
+
role: import_zod7.z.enum(AGENT_TURN_ROLES),
|
|
1363
|
+
text: import_zod7.z.string().max(AGENT_TURN_MAX_TEXT).default(""),
|
|
1364
|
+
toolCalls: import_zod7.z.array(AgentToolCallSchema).max(AGENT_TOOL_CALLS_PER_TURN).default([]),
|
|
1365
|
+
latencyMs: import_zod7.z.number().int().min(0).max(36e5).optional(),
|
|
1366
|
+
outcome: import_zod7.z.enum(AGENT_OUTCOMES).optional(),
|
|
1367
|
+
taskSuccess: import_zod7.z.boolean().optional(),
|
|
1368
|
+
occurredAt: import_zod7.z.string().datetime({ offset: true }).optional(),
|
|
1369
|
+
userId: optionalId(256),
|
|
1370
|
+
anonymousId: optionalId(128),
|
|
1371
|
+
accountId: optionalId(256),
|
|
1372
|
+
sessionId: optionalId(128),
|
|
1373
|
+
metadata: AgentMetadataSchema.default({})
|
|
1374
|
+
});
|
|
1375
|
+
var turns = import_zod7.z.array(AgentTurnInputSchema).min(1).max(AGENT_TURNS_PER_BATCH);
|
|
1376
|
+
var sdkInfo = import_zod7.z.object({ name: import_zod7.z.string().max(60), version: import_zod7.z.string().max(30) }).optional();
|
|
1377
|
+
var SdkAgentEventsSchema = import_zod7.z.object({ turns, sdk: sdkInfo });
|
|
1378
|
+
var AgentEventsRequestSchema = import_zod7.z.preprocess(
|
|
1379
|
+
(v) => {
|
|
1380
|
+
if (Array.isArray(v)) return { turns: v };
|
|
1381
|
+
if (v && typeof v === "object" && !("turns" in v)) {
|
|
1382
|
+
const { environment, ...turn } = v;
|
|
1383
|
+
return { turns: [turn], environment };
|
|
1384
|
+
}
|
|
1385
|
+
return v;
|
|
1386
|
+
},
|
|
1387
|
+
import_zod7.z.object({ turns, environment: import_zod7.z.enum(ENVIRONMENTS).default("production"), sdk: sdkInfo })
|
|
1388
|
+
);
|
|
1389
|
+
|
|
1390
|
+
// src/feedback.ts
|
|
1391
|
+
var import_zod8 = require("zod");
|
|
1392
|
+
|
|
1393
|
+
// src/feedback-limits.ts
|
|
1394
|
+
var FEEDBACK_STATUSES = ["new", "under_review", "planned", "in_progress", "released", "declined"];
|
|
1395
|
+
var FEEDBACK_STATUS_LABEL = {
|
|
1396
|
+
new: "New",
|
|
1397
|
+
under_review: "Under review",
|
|
1398
|
+
planned: "Planned",
|
|
1399
|
+
in_progress: "In progress",
|
|
1400
|
+
released: "Released",
|
|
1401
|
+
declined: "Declined"
|
|
1402
|
+
};
|
|
1403
|
+
var FEEDBACK_PRIORITIES = ["nice_to_have", "important", "critical"];
|
|
1404
|
+
var FEEDBACK_PRIORITY_LABEL = { nice_to_have: "Nice to have", important: "Important", critical: "Critical" };
|
|
1405
|
+
var FEEDBACK_PRIORITY_WEIGHT = { nice_to_have: 1, important: 2, critical: 3 };
|
|
1406
|
+
var FEEDBACK_EVENTS = ["request.created", "request.status_changed", "request.voted"];
|
|
1407
|
+
var MAX_FEEDBACK_TITLE = 140;
|
|
1408
|
+
var MAX_FEEDBACK_DESCRIPTION = 4e3;
|
|
1409
|
+
var MAX_FEEDBACK_COMMENT = 2e3;
|
|
1410
|
+
var MAX_FEEDBACK_NOTE = 500;
|
|
1411
|
+
var feedbackReference = (number) => `#${number}`;
|
|
1412
|
+
|
|
1413
|
+
// src/feedback.ts
|
|
1414
|
+
var visitor = {
|
|
1415
|
+
anonymousId: import_zod8.z.string().min(1).max(128),
|
|
1416
|
+
userId: import_zod8.z.string().max(256).optional().nullable()
|
|
1417
|
+
};
|
|
1418
|
+
var FeedbackListRequestSchema = import_zod8.z.object({
|
|
1419
|
+
...visitor,
|
|
1420
|
+
q: import_zod8.z.string().trim().max(200).optional(),
|
|
1421
|
+
sort: import_zod8.z.enum(["top", "new", "trending"]).default("top"),
|
|
1422
|
+
status: import_zod8.z.enum(FEEDBACK_STATUSES).optional(),
|
|
1423
|
+
/** "open" = not released or declined. */
|
|
1424
|
+
filter: import_zod8.z.enum(["open", "all", "mine", "following"]).default("open"),
|
|
1425
|
+
productArea: import_zod8.z.string().trim().max(60).optional(),
|
|
1426
|
+
page: import_zod8.z.number().int().min(1).max(100).default(1)
|
|
1427
|
+
});
|
|
1428
|
+
var FeedbackVisitorSchema = import_zod8.z.object(visitor);
|
|
1429
|
+
var SubmitFeedbackSchema = import_zod8.z.object({
|
|
1430
|
+
...visitor,
|
|
1431
|
+
title: import_zod8.z.string().trim().min(3, "Give your idea a short title").max(MAX_FEEDBACK_TITLE),
|
|
1432
|
+
description: import_zod8.z.string().trim().max(MAX_FEEDBACK_DESCRIPTION).default(""),
|
|
1433
|
+
productArea: import_zod8.z.string().trim().max(60).optional().nullable(),
|
|
1434
|
+
priority: import_zod8.z.enum(FEEDBACK_PRIORITIES).default("nice_to_have"),
|
|
1435
|
+
/** Filed from this Scout conversation (Scout offered it). */
|
|
1436
|
+
conversationId: import_zod8.z.string().min(1).max(64).optional().nullable(),
|
|
1437
|
+
pageUrl: import_zod8.z.string().max(2e3).optional()
|
|
1438
|
+
});
|
|
1439
|
+
var FeedbackVoteSchema = import_zod8.z.object({
|
|
1440
|
+
...visitor,
|
|
1441
|
+
priority: import_zod8.z.enum(FEEDBACK_PRIORITIES).default("nice_to_have"),
|
|
1442
|
+
note: import_zod8.z.string().trim().max(MAX_FEEDBACK_NOTE).optional(),
|
|
1443
|
+
conversationId: import_zod8.z.string().min(1).max(64).optional().nullable()
|
|
1444
|
+
});
|
|
1445
|
+
var FeedbackFollowSchema = import_zod8.z.object({ ...visitor, follow: import_zod8.z.boolean() });
|
|
1446
|
+
var FeedbackCommentSchema = import_zod8.z.object({ ...visitor, body: import_zod8.z.string().trim().min(1).max(MAX_FEEDBACK_COMMENT) });
|
|
1447
|
+
var FeedbackSimilarSchema = import_zod8.z.object({ ...visitor, title: import_zod8.z.string().trim().min(3).max(MAX_FEEDBACK_TITLE) });
|
|
1448
|
+
var FeedbackUpdatesReadSchema = import_zod8.z.object({ ...visitor, ids: import_zod8.z.array(import_zod8.z.string().min(1).max(64)).max(100).optional() });
|
|
1449
|
+
|
|
1450
|
+
// src/capture.ts
|
|
1451
|
+
var import_zod9 = require("zod");
|
|
1452
|
+
var AutocaptureSettingsSchema = import_zod9.z.object({ pageviews: import_zod9.z.boolean(), pageLeave: import_zod9.z.boolean(), clicks: import_zod9.z.boolean(), rageClicks: import_zod9.z.boolean(), heatmaps: import_zod9.z.boolean(), mouseMovement: import_zod9.z.boolean(), appLifecycle: import_zod9.z.boolean() }).partial();
|
|
1453
|
+
var ErrorTrackingSettingsSchema = import_zod9.z.object({ enabled: import_zod9.z.boolean() }).partial();
|
|
1454
|
+
var ReplaySettingsSchema = import_zod9.z.object({
|
|
1455
|
+
enabled: import_zod9.z.boolean(),
|
|
1456
|
+
sampleRate: import_zod9.z.number().int().min(0).max(100),
|
|
1457
|
+
recordConsole: import_zod9.z.boolean(),
|
|
1458
|
+
recordNetwork: import_zod9.z.boolean(),
|
|
1459
|
+
recordNetworkPayloads: import_zod9.z.boolean(),
|
|
1460
|
+
maskAllText: import_zod9.z.boolean(),
|
|
1461
|
+
blockSelectors: import_zod9.z.array(import_zod9.z.string().min(1).max(200)).max(50),
|
|
1462
|
+
retentionDays: import_zod9.z.number().int().min(1).max(365)
|
|
1104
1463
|
}).partial();
|
|
1105
1464
|
var DEFAULT_CAPTURE_SETTINGS = {
|
|
1106
|
-
autocapture: { pageviews: true, pageLeave: true, clicks: true, rageClicks: true, heatmaps: true, mouseMovement: true },
|
|
1465
|
+
autocapture: { pageviews: true, pageLeave: true, clicks: true, rageClicks: true, heatmaps: true, mouseMovement: true, appLifecycle: true },
|
|
1107
1466
|
errorTracking: { enabled: true },
|
|
1108
1467
|
replay: { enabled: false, sampleRate: 100, recordConsole: true, recordNetwork: true, recordNetworkPayloads: false, maskAllText: false, blockSelectors: [], retentionDays: 30 }
|
|
1109
1468
|
};
|
|
@@ -1121,18 +1480,18 @@ function resolveCaptureSettings(settings) {
|
|
|
1121
1480
|
};
|
|
1122
1481
|
}
|
|
1123
1482
|
var HEATMAP_VIEWPORTS = { mobile: [0, 767], tablet: [768, 1279], desktop: [1280, 1e5] };
|
|
1124
|
-
var ReplayChunkSchema =
|
|
1125
|
-
sessionId:
|
|
1126
|
-
windowId:
|
|
1127
|
-
seq:
|
|
1128
|
-
anonymousId:
|
|
1129
|
-
userId:
|
|
1483
|
+
var ReplayChunkSchema = import_zod9.z.object({
|
|
1484
|
+
sessionId: import_zod9.z.string().min(1).max(128),
|
|
1485
|
+
windowId: import_zod9.z.string().min(1).max(64),
|
|
1486
|
+
seq: import_zod9.z.number().int().min(0).max(1e6),
|
|
1487
|
+
anonymousId: import_zod9.z.string().min(1).max(128),
|
|
1488
|
+
userId: import_zod9.z.string().max(256).optional().nullable(),
|
|
1130
1489
|
/** rrweb `eventWithTime` objects, in order. */
|
|
1131
|
-
events:
|
|
1132
|
-
url:
|
|
1133
|
-
device:
|
|
1134
|
-
viewport:
|
|
1135
|
-
sdk:
|
|
1490
|
+
events: import_zod9.z.array(import_zod9.z.object({ type: import_zod9.z.number().int(), timestamp: import_zod9.z.number() }).passthrough()).min(1).max(5e4),
|
|
1491
|
+
url: import_zod9.z.string().max(2e3).optional(),
|
|
1492
|
+
device: import_zod9.z.object({ type: import_zod9.z.string().max(20), browser: import_zod9.z.string().max(40).optional(), os: import_zod9.z.string().max(40).optional() }).optional(),
|
|
1493
|
+
viewport: import_zod9.z.object({ width: import_zod9.z.number().int().min(0).max(1e5), height: import_zod9.z.number().int().min(0).max(1e5) }).optional(),
|
|
1494
|
+
sdk: import_zod9.z.object({ name: import_zod9.z.string().max(60), version: import_zod9.z.string().max(30) }).optional()
|
|
1136
1495
|
});
|
|
1137
1496
|
var REPLAY_MAX_COMPRESSED_BYTES = 2 * 1024 * 1024;
|
|
1138
1497
|
var REPLAY_MAX_RAW_BYTES = 16 * 1024 * 1024;
|
|
@@ -1316,8 +1675,8 @@ var GUIDE_TEMPLATES = [
|
|
|
1316
1675
|
}
|
|
1317
1676
|
}
|
|
1318
1677
|
];
|
|
1319
|
-
function templateConfig(
|
|
1320
|
-
const t = GUIDE_TEMPLATES.find((x) => x.id ===
|
|
1678
|
+
function templateConfig(id2) {
|
|
1679
|
+
const t = GUIDE_TEMPLATES.find((x) => x.id === id2);
|
|
1321
1680
|
if (!t) return null;
|
|
1322
1681
|
return { template: t, config: GuideConfigSchema.parse(t.config) };
|
|
1323
1682
|
}
|
|
@@ -1377,19 +1736,19 @@ function parseStart(v) {
|
|
|
1377
1736
|
if (!m || !m[0]) return 0;
|
|
1378
1737
|
return Math.min(Number(m[1] ?? 0) * 3600 + Number(m[2] ?? 0) * 60 + Number(m[3] ?? 0), 86400);
|
|
1379
1738
|
}
|
|
1380
|
-
function youtube(
|
|
1381
|
-
if (!YOUTUBE_ID.test(
|
|
1739
|
+
function youtube(id2, start) {
|
|
1740
|
+
if (!YOUTUBE_ID.test(id2)) return null;
|
|
1382
1741
|
return {
|
|
1383
1742
|
provider: "youtube",
|
|
1384
|
-
src: `https://www.youtube-nocookie.com/embed/${
|
|
1385
|
-
watchUrl: `https://www.youtube.com/watch?v=${
|
|
1743
|
+
src: `https://www.youtube-nocookie.com/embed/${id2}${start ? `?start=${start}` : ""}`,
|
|
1744
|
+
watchUrl: `https://www.youtube.com/watch?v=${id2}${start ? `&t=${start}s` : ""}`,
|
|
1386
1745
|
title: "YouTube video"
|
|
1387
1746
|
};
|
|
1388
1747
|
}
|
|
1389
|
-
function vimeo(
|
|
1390
|
-
if (!VIMEO_ID.test(
|
|
1748
|
+
function vimeo(id2, hash) {
|
|
1749
|
+
if (!VIMEO_ID.test(id2) || hash !== null && !VIMEO_HASH.test(hash)) return null;
|
|
1391
1750
|
const h = hash ? hash.toLowerCase() : null;
|
|
1392
|
-
return { provider: "vimeo", src: `https://player.vimeo.com/video/${
|
|
1751
|
+
return { provider: "vimeo", src: `https://player.vimeo.com/video/${id2}${h ? `?h=${h}` : ""}`, watchUrl: `https://vimeo.com/${id2}${h ? `/${h}` : ""}`, title: "Vimeo video" };
|
|
1393
1752
|
}
|
|
1394
1753
|
function toEmbedUrl(input) {
|
|
1395
1754
|
const u = parseUrl(input);
|
|
@@ -1415,16 +1774,16 @@ function toEmbedUrl(input) {
|
|
|
1415
1774
|
return parts[0] === "video" && parts.length === 2 ? vimeo(parts[1], u.searchParams.get("h")) : null;
|
|
1416
1775
|
case "loom.com":
|
|
1417
1776
|
if ((parts[0] === "share" || parts[0] === "embed") && parts.length === 2 && LOOM_ID.test(parts[1])) {
|
|
1418
|
-
const
|
|
1419
|
-
return { provider: "loom", src: `https://www.loom.com/embed/${
|
|
1777
|
+
const id2 = parts[1].toLowerCase();
|
|
1778
|
+
return { provider: "loom", src: `https://www.loom.com/embed/${id2}`, watchUrl: `https://www.loom.com/share/${id2}`, title: "Loom video" };
|
|
1420
1779
|
}
|
|
1421
1780
|
return null;
|
|
1422
1781
|
default: {
|
|
1423
|
-
let
|
|
1424
|
-
if (host === "fast.wistia.net" || host === "fast.wistia.com")
|
|
1425
|
-
else if (host === "wi.st" || host === "wistia.com" || /^[a-z0-9-]+\.wistia\.com$/.test(host))
|
|
1426
|
-
if (!
|
|
1427
|
-
return { provider: "wistia", src: `https://fast.wistia.net/embed/iframe/${
|
|
1782
|
+
let id2;
|
|
1783
|
+
if (host === "fast.wistia.net" || host === "fast.wistia.com") id2 = parts[0] === "embed" && parts[1] === "iframe" && parts.length === 3 ? parts[2] : void 0;
|
|
1784
|
+
else if (host === "wi.st" || host === "wistia.com" || /^[a-z0-9-]+\.wistia\.com$/.test(host)) id2 = parts[0] === "medias" && parts.length === 2 ? parts[1] : void 0;
|
|
1785
|
+
if (!id2 || !WISTIA_ID.test(id2)) return null;
|
|
1786
|
+
return { provider: "wistia", src: `https://fast.wistia.net/embed/iframe/${id2}`, watchUrl: `https://fast.wistia.net/embed/iframe/${id2}`, title: "Wistia video" };
|
|
1428
1787
|
}
|
|
1429
1788
|
}
|
|
1430
1789
|
}
|
|
@@ -1455,7 +1814,7 @@ var MAX_COLLECTION_DEPTH = 3;
|
|
|
1455
1814
|
function matchesAudiences(required, member) {
|
|
1456
1815
|
if (!required || required.length === 0) return true;
|
|
1457
1816
|
if (!member) return false;
|
|
1458
|
-
const has2 = member instanceof Set ? (
|
|
1817
|
+
const has2 = member instanceof Set ? (id2) => member.has(id2) : (id2) => member.includes(id2);
|
|
1459
1818
|
return required.some(has2);
|
|
1460
1819
|
}
|
|
1461
1820
|
function resourceCenterSections(collections, articles, member) {
|
|
@@ -1509,7 +1868,7 @@ function servedArticleAudiences(audienceIds, visibility) {
|
|
|
1509
1868
|
return visibility === "identified" && audienceIds.length === 0 ? [LOGGED_IN_AUDIENCE] : [...audienceIds];
|
|
1510
1869
|
}
|
|
1511
1870
|
function visitorAudiences(audienceIds, identified) {
|
|
1512
|
-
const ids = audienceIds.filter((
|
|
1871
|
+
const ids = audienceIds.filter((id2) => id2 !== LOGGED_IN_AUDIENCE);
|
|
1513
1872
|
return identified ? [...ids, LOGGED_IN_AUDIENCE] : ids;
|
|
1514
1873
|
}
|
|
1515
1874
|
function visibleArticleIds(collections, articles, member) {
|
|
@@ -1545,9 +1904,35 @@ function matchesHelpQuery(text, query) {
|
|
|
1545
1904
|
const have = words(hay);
|
|
1546
1905
|
return terms.every((t) => have.some((w) => w.startsWith(t) || t.length > 3 && t.endsWith("s") && w.startsWith(t.slice(0, -1))));
|
|
1547
1906
|
}
|
|
1907
|
+
var RC_MODULE_IDS = ["announcements", "search", "checklists", "guides", "articles", "links", "faqs"];
|
|
1908
|
+
var RC_MODULE_LABELS = {
|
|
1909
|
+
announcements: "What's new",
|
|
1910
|
+
search: "Search",
|
|
1911
|
+
checklists: "Checklists",
|
|
1912
|
+
guides: "Guides & tours",
|
|
1913
|
+
articles: "Articles",
|
|
1914
|
+
links: "Links",
|
|
1915
|
+
faqs: "FAQs"
|
|
1916
|
+
};
|
|
1917
|
+
function orderedModules(modules) {
|
|
1918
|
+
const known = (modules ?? []).filter((m, i, all) => RC_MODULE_IDS.includes(m.id) && all.findIndex((x) => x.id === m.id) === i);
|
|
1919
|
+
const missing = RC_MODULE_IDS.filter((id2) => !known.some((m) => m.id === id2)).map((id2) => ({ id: id2, enabled: true }));
|
|
1920
|
+
return [...known, ...missing];
|
|
1921
|
+
}
|
|
1922
|
+
function visibleAnnouncements(items, member, now = Date.now()) {
|
|
1923
|
+
return (items ?? []).filter((a) => {
|
|
1924
|
+
const t = Date.parse(a.publishedAt);
|
|
1925
|
+
return !Number.isNaN(t) && t <= now && matchesAudiences(a.audienceIds, member);
|
|
1926
|
+
}).sort((a, b) => Date.parse(b.publishedAt) - Date.parse(a.publishedAt));
|
|
1927
|
+
}
|
|
1928
|
+
function unreadAnnouncements(items, lastSeenAt) {
|
|
1929
|
+
const seen = lastSeenAt ? Date.parse(lastSeenAt) : NaN;
|
|
1930
|
+
if (Number.isNaN(seen)) return items.length;
|
|
1931
|
+
return items.filter((a) => Date.parse(a.publishedAt) > seen).length;
|
|
1932
|
+
}
|
|
1548
1933
|
|
|
1549
1934
|
// src/howto.ts
|
|
1550
|
-
var
|
|
1935
|
+
var import_zod10 = require("zod");
|
|
1551
1936
|
|
|
1552
1937
|
// src/howto-limits.ts
|
|
1553
1938
|
var CAPTURE_PARAM = "guidely_capture";
|
|
@@ -1556,36 +1941,36 @@ var CAPTURE_SCREENSHOT_MAX_BYTES = 8 * 1024 * 1024;
|
|
|
1556
1941
|
// src/howto.ts
|
|
1557
1942
|
var HOWTO_STEP_KINDS = ["action", "text", "heading", "tip", "alert"];
|
|
1558
1943
|
var HOWTO_ACTIONS = ["click", "type", "select", "navigate"];
|
|
1559
|
-
var NormalizedRectSchema =
|
|
1560
|
-
x:
|
|
1561
|
-
y:
|
|
1562
|
-
width:
|
|
1563
|
-
height:
|
|
1944
|
+
var NormalizedRectSchema = import_zod10.z.object({
|
|
1945
|
+
x: import_zod10.z.number().min(0).max(1),
|
|
1946
|
+
y: import_zod10.z.number().min(0).max(1),
|
|
1947
|
+
width: import_zod10.z.number().min(0).max(1),
|
|
1948
|
+
height: import_zod10.z.number().min(0).max(1)
|
|
1564
1949
|
});
|
|
1565
|
-
var CapturedElementSchema =
|
|
1950
|
+
var CapturedElementSchema = import_zod10.z.object({
|
|
1566
1951
|
/** Visible name: aria-label, associated label, text, placeholder, alt or title. */
|
|
1567
|
-
label:
|
|
1952
|
+
label: import_zod10.z.string().max(200).default(""),
|
|
1568
1953
|
/** button, link, tab, menuitem, checkbox, radio, field, dropdown, option, element… */
|
|
1569
|
-
role:
|
|
1570
|
-
tag:
|
|
1954
|
+
role: import_zod10.z.string().max(40).default("element"),
|
|
1955
|
+
tag: import_zod10.z.string().max(40).default("")
|
|
1571
1956
|
});
|
|
1572
|
-
var CaptureStepSchema =
|
|
1957
|
+
var CaptureStepSchema = import_zod10.z.object({
|
|
1573
1958
|
/** Random id from the SDK; a retried upload with the same id is stored once. */
|
|
1574
|
-
clientId:
|
|
1575
|
-
action:
|
|
1576
|
-
url:
|
|
1577
|
-
pageTitle:
|
|
1959
|
+
clientId: import_zod10.z.string().min(1).max(64),
|
|
1960
|
+
action: import_zod10.z.enum(HOWTO_ACTIONS),
|
|
1961
|
+
url: import_zod10.z.string().max(2e3),
|
|
1962
|
+
pageTitle: import_zod10.z.string().max(300).default(""),
|
|
1578
1963
|
element: CapturedElementSchema.optional(),
|
|
1579
1964
|
/** Typed text or chosen option; absent when it was sensitive (`valueRedacted`). */
|
|
1580
|
-
value:
|
|
1581
|
-
valueRedacted:
|
|
1965
|
+
value: import_zod10.z.string().max(200).optional(),
|
|
1966
|
+
valueRedacted: import_zod10.z.boolean().default(false),
|
|
1582
1967
|
/** Selectors for the element, so the step can later become an interactive tour step. */
|
|
1583
|
-
selectors:
|
|
1968
|
+
selectors: import_zod10.z.array(SelectorStrategySchema).max(10).default([]),
|
|
1584
1969
|
/** Where the element sits in the screenshot. */
|
|
1585
1970
|
highlight: NormalizedRectSchema.optional(),
|
|
1586
1971
|
/** Number of regions the SDK blurred in the screenshot before upload. */
|
|
1587
|
-
redactions:
|
|
1588
|
-
occurredAt:
|
|
1972
|
+
redactions: import_zod10.z.number().int().min(0).max(1e3).default(0),
|
|
1973
|
+
occurredAt: import_zod10.z.string().datetime().optional()
|
|
1589
1974
|
});
|
|
1590
1975
|
function quoted(s) {
|
|
1591
1976
|
const t = (s ?? "").replace(/\s+/g, " ").trim();
|
|
@@ -1656,12 +2041,12 @@ function hostAndPath(url) {
|
|
|
1656
2041
|
return url.slice(0, 80);
|
|
1657
2042
|
}
|
|
1658
2043
|
}
|
|
1659
|
-
var NormalizedPointSchema =
|
|
2044
|
+
var NormalizedPointSchema = import_zod10.z.object({ x: import_zod10.z.number().min(0).max(1), y: import_zod10.z.number().min(0).max(1) });
|
|
1660
2045
|
var ANNOTATION_COLORS = ["brand", "red", "amber", "green", "black", "white"];
|
|
1661
|
-
var HowToAnnotationSchema =
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
2046
|
+
var HowToAnnotationSchema = import_zod10.z.discriminatedUnion("type", [
|
|
2047
|
+
import_zod10.z.object({ id: import_zod10.z.string().min(1).max(32), type: import_zod10.z.literal("arrow"), from: NormalizedPointSchema, to: NormalizedPointSchema, color: import_zod10.z.enum(ANNOTATION_COLORS).default("brand") }),
|
|
2048
|
+
import_zod10.z.object({ id: import_zod10.z.string().min(1).max(32), type: import_zod10.z.literal("text"), at: NormalizedPointSchema, text: import_zod10.z.string().trim().min(1).max(120), color: import_zod10.z.enum(ANNOTATION_COLORS).default("brand") }),
|
|
2049
|
+
import_zod10.z.object({ id: import_zod10.z.string().min(1).max(32), type: import_zod10.z.literal("box"), rect: NormalizedRectSchema, color: import_zod10.z.enum(ANNOTATION_COLORS).default("brand") })
|
|
1665
2050
|
]);
|
|
1666
2051
|
var MAX_ANNOTATIONS = 30;
|
|
1667
2052
|
|
|
@@ -1689,12 +2074,556 @@ function pageLabel(path) {
|
|
|
1689
2074
|
}
|
|
1690
2075
|
function firstNameFromTraits(traits) {
|
|
1691
2076
|
if (!traits) return null;
|
|
1692
|
-
const
|
|
1693
|
-
const first =
|
|
2077
|
+
const pick2 = (v) => typeof v === "string" ? v.trim() : "";
|
|
2078
|
+
const first = pick2(traits.firstName) || pick2(traits.first_name) || pick2(traits.firstname) || pick2(traits.name).split(/\s+/)[0] || "";
|
|
1694
2079
|
if (!first || first.length > 40 || first.includes("@") || !/\p{L}/u.test(first)) return null;
|
|
1695
2080
|
return first;
|
|
1696
2081
|
}
|
|
1697
2082
|
|
|
2083
|
+
// src/tagging.ts
|
|
2084
|
+
var SNAPSHOT_LIMITS = { classes: 8, className: 60, attrs: 6, attrValue: 100, ancestors: 5, hosts: 3, tag: 40, id: 80 };
|
|
2085
|
+
var SNAPSHOT_ATTRS = ["role", "name", "type", "aria-label", "title", "alt", "for", "href"];
|
|
2086
|
+
var NOISY_DATA_ATTR = /^data-(state|v-|react|radix|headlessui|svelte|orientation|highlighted|focus|key|index|side|align|disabled|selected|active|open|rbd|dnd|sveltekit|guidely-(mask|ignore|block))/i;
|
|
2087
|
+
var DEFAULT_FEATURE_ATTRIBUTE = "data-guidely-feature";
|
|
2088
|
+
var FEATURE_ATTRIBUTE_PATTERN = /^data-[a-z0-9][a-z0-9_.-]{0,60}$/;
|
|
2089
|
+
function str(v, max) {
|
|
2090
|
+
return typeof v === "string" && v ? v.slice(0, max) : void 0;
|
|
2091
|
+
}
|
|
2092
|
+
function cleanNode(raw) {
|
|
2093
|
+
if (!raw || typeof raw !== "object") return null;
|
|
2094
|
+
const r = raw;
|
|
2095
|
+
const t = str(r.t, SNAPSHOT_LIMITS.tag)?.toLowerCase();
|
|
2096
|
+
if (!t || !/^[a-z][a-z0-9-]*$/.test(t)) return null;
|
|
2097
|
+
const node = { t };
|
|
2098
|
+
const id2 = str(r.id, SNAPSHOT_LIMITS.id);
|
|
2099
|
+
if (id2) node.id = id2;
|
|
2100
|
+
if (Array.isArray(r.c)) {
|
|
2101
|
+
const c = r.c.filter((x) => typeof x === "string" && !!x && x.length <= SNAPSHOT_LIMITS.className && !/\s/.test(x)).slice(0, SNAPSHOT_LIMITS.classes);
|
|
2102
|
+
if (c.length) node.c = c;
|
|
2103
|
+
}
|
|
2104
|
+
if (r.a && typeof r.a === "object" && !Array.isArray(r.a)) {
|
|
2105
|
+
const a = {};
|
|
2106
|
+
for (const [k, v] of Object.entries(r.a)) {
|
|
2107
|
+
if (Object.keys(a).length >= SNAPSHOT_LIMITS.attrs) break;
|
|
2108
|
+
const key = k.toLowerCase();
|
|
2109
|
+
if (typeof v !== "string" || !(key.startsWith("data-") || SNAPSHOT_ATTRS.includes(key)) || key === "value" || key.length > 60) continue;
|
|
2110
|
+
a[key] = v.slice(0, SNAPSHOT_LIMITS.attrValue);
|
|
2111
|
+
}
|
|
2112
|
+
if (Object.keys(a).length) node.a = a;
|
|
2113
|
+
}
|
|
2114
|
+
if (typeof r.n === "number" && Number.isInteger(r.n) && r.n >= 1 && r.n <= 1e4) node.n = r.n;
|
|
2115
|
+
return node;
|
|
2116
|
+
}
|
|
2117
|
+
function normalizeSnapshot(raw) {
|
|
2118
|
+
const el = cleanNode(raw);
|
|
2119
|
+
if (!el) return null;
|
|
2120
|
+
const r = raw;
|
|
2121
|
+
const out = el;
|
|
2122
|
+
if (Array.isArray(r.p)) {
|
|
2123
|
+
const p = r.p.slice(0, SNAPSHOT_LIMITS.ancestors).map(cleanNode);
|
|
2124
|
+
const cut = p.indexOf(null);
|
|
2125
|
+
const list = cut === -1 ? p : p.slice(0, cut);
|
|
2126
|
+
if (list.length) out.p = list;
|
|
2127
|
+
}
|
|
2128
|
+
if (Array.isArray(r.h)) {
|
|
2129
|
+
const h = r.h.slice(0, SNAPSHOT_LIMITS.hosts).map(cleanNode).filter((x) => !!x);
|
|
2130
|
+
if (h.length) out.h = h;
|
|
2131
|
+
}
|
|
2132
|
+
return out;
|
|
2133
|
+
}
|
|
2134
|
+
function stableStringify(v) {
|
|
2135
|
+
if (Array.isArray(v)) return `[${v.map(stableStringify).join(",")}]`;
|
|
2136
|
+
if (v && typeof v === "object") {
|
|
2137
|
+
const o = v;
|
|
2138
|
+
return `{${Object.keys(o).filter((k) => o[k] !== void 0).sort().map((k) => `${JSON.stringify(k)}:${stableStringify(o[k])}`).join(",")}}`;
|
|
2139
|
+
}
|
|
2140
|
+
return JSON.stringify(v ?? null);
|
|
2141
|
+
}
|
|
2142
|
+
var SelectorSyntaxError = class extends Error {
|
|
2143
|
+
};
|
|
2144
|
+
var IDENT_START = /[A-Za-z_\u00a0-\uffff-]/;
|
|
2145
|
+
var IDENT_CHAR = /[A-Za-z0-9_\u00a0-\uffff-]/;
|
|
2146
|
+
function parseCssSelector(input) {
|
|
2147
|
+
const s = input.trim();
|
|
2148
|
+
if (!s) throw new SelectorSyntaxError("Empty selector");
|
|
2149
|
+
if (s.length > 1e3) throw new SelectorSyntaxError("Selector is too long");
|
|
2150
|
+
let i = 0;
|
|
2151
|
+
const peek = () => s[i];
|
|
2152
|
+
const eof = () => i >= s.length;
|
|
2153
|
+
const fail = (msg) => {
|
|
2154
|
+
throw new SelectorSyntaxError(`${msg} at position ${i + 1}`);
|
|
2155
|
+
};
|
|
2156
|
+
const ws = () => {
|
|
2157
|
+
let any = false;
|
|
2158
|
+
while (!eof() && /\s/.test(s[i])) {
|
|
2159
|
+
i++;
|
|
2160
|
+
any = true;
|
|
2161
|
+
}
|
|
2162
|
+
return any;
|
|
2163
|
+
};
|
|
2164
|
+
const escape = () => {
|
|
2165
|
+
i++;
|
|
2166
|
+
const hex = /^[0-9a-fA-F]{1,6}/.exec(s.slice(i));
|
|
2167
|
+
if (hex) {
|
|
2168
|
+
i += hex[0].length;
|
|
2169
|
+
if (s[i] === " ") i++;
|
|
2170
|
+
return String.fromCodePoint(parseInt(hex[0], 16));
|
|
2171
|
+
}
|
|
2172
|
+
if (eof()) fail("Unfinished escape");
|
|
2173
|
+
return s[i++];
|
|
2174
|
+
};
|
|
2175
|
+
const ident = () => {
|
|
2176
|
+
let out = "";
|
|
2177
|
+
if (s[i] === "\\") out += escape();
|
|
2178
|
+
else if (!eof() && IDENT_START.test(s[i])) out += s[i++];
|
|
2179
|
+
else fail("Expected a name");
|
|
2180
|
+
while (!eof()) {
|
|
2181
|
+
if (s[i] === "\\") out += escape();
|
|
2182
|
+
else if (IDENT_CHAR.test(s[i])) out += s[i++];
|
|
2183
|
+
else break;
|
|
2184
|
+
}
|
|
2185
|
+
return out;
|
|
2186
|
+
};
|
|
2187
|
+
const quoted2 = () => {
|
|
2188
|
+
const q = s[i++];
|
|
2189
|
+
let out = "";
|
|
2190
|
+
while (!eof() && s[i] !== q) {
|
|
2191
|
+
if (s[i] === "\\") out += escape();
|
|
2192
|
+
else out += s[i++];
|
|
2193
|
+
}
|
|
2194
|
+
if (eof()) fail("Unterminated string");
|
|
2195
|
+
i++;
|
|
2196
|
+
return out;
|
|
2197
|
+
};
|
|
2198
|
+
const compound = () => {
|
|
2199
|
+
const c = { classes: [], attrs: [] };
|
|
2200
|
+
let any = false;
|
|
2201
|
+
if (peek() === "*") {
|
|
2202
|
+
i++;
|
|
2203
|
+
any = true;
|
|
2204
|
+
} else if (!eof() && (IDENT_START.test(peek()) || peek() === "\\")) {
|
|
2205
|
+
c.tag = ident().toLowerCase();
|
|
2206
|
+
any = true;
|
|
2207
|
+
}
|
|
2208
|
+
for (; ; ) {
|
|
2209
|
+
const ch = peek();
|
|
2210
|
+
if (ch === "#") {
|
|
2211
|
+
i++;
|
|
2212
|
+
c.id = ident();
|
|
2213
|
+
} else if (ch === ".") {
|
|
2214
|
+
i++;
|
|
2215
|
+
c.classes.push(ident());
|
|
2216
|
+
} else if (ch === "[") {
|
|
2217
|
+
i++;
|
|
2218
|
+
ws();
|
|
2219
|
+
const name = ident().toLowerCase();
|
|
2220
|
+
ws();
|
|
2221
|
+
let op = "exists";
|
|
2222
|
+
let value;
|
|
2223
|
+
let insensitive = false;
|
|
2224
|
+
if (peek() !== "]") {
|
|
2225
|
+
const m = /^(=|\^=|\$=|\*=|~=|\|=)/.exec(s.slice(i));
|
|
2226
|
+
if (!m) fail("Unsupported attribute operator");
|
|
2227
|
+
op = m[1];
|
|
2228
|
+
i += m[1].length;
|
|
2229
|
+
ws();
|
|
2230
|
+
value = peek() === '"' || peek() === "'" ? quoted2() : ident();
|
|
2231
|
+
ws();
|
|
2232
|
+
if (peek() === "i" || peek() === "I") {
|
|
2233
|
+
i++;
|
|
2234
|
+
insensitive = true;
|
|
2235
|
+
ws();
|
|
2236
|
+
} else if (peek() === "s" || peek() === "S") {
|
|
2237
|
+
i++;
|
|
2238
|
+
ws();
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
if (peek() !== "]") fail("Expected ]");
|
|
2242
|
+
i++;
|
|
2243
|
+
c.attrs.push({ name, op, ...value !== void 0 ? { value } : {}, ...insensitive ? { insensitive } : {} });
|
|
2244
|
+
} else if (ch === ":") {
|
|
2245
|
+
i++;
|
|
2246
|
+
if (peek() === ":") fail("Pseudo-elements are not supported");
|
|
2247
|
+
const name = ident().toLowerCase();
|
|
2248
|
+
if (name === "first-of-type") c.nth = { a: 0, b: 1 };
|
|
2249
|
+
else if (name === "nth-of-type") {
|
|
2250
|
+
if (peek() !== "(") fail("Expected (");
|
|
2251
|
+
i++;
|
|
2252
|
+
ws();
|
|
2253
|
+
const m = /^(odd|even|\d+)/i.exec(s.slice(i));
|
|
2254
|
+
if (!m) fail("Only :nth-of-type(n), odd or even are supported");
|
|
2255
|
+
i += m[0].length;
|
|
2256
|
+
ws();
|
|
2257
|
+
if (peek() !== ")") fail("Expected )");
|
|
2258
|
+
i++;
|
|
2259
|
+
const v = m[0].toLowerCase();
|
|
2260
|
+
c.nth = v === "odd" ? { a: 2, b: 1 } : v === "even" ? { a: 2, b: 0 } : { a: 0, b: Number(v) };
|
|
2261
|
+
} else fail(`Unsupported pseudo-class :${name}`);
|
|
2262
|
+
} else break;
|
|
2263
|
+
any = true;
|
|
2264
|
+
}
|
|
2265
|
+
return any ? c : null;
|
|
2266
|
+
};
|
|
2267
|
+
const list = [];
|
|
2268
|
+
for (; ; ) {
|
|
2269
|
+
ws();
|
|
2270
|
+
const sel = { compounds: [], combinators: [] };
|
|
2271
|
+
const first = compound();
|
|
2272
|
+
if (!first) fail("Expected a selector");
|
|
2273
|
+
sel.compounds.push(first);
|
|
2274
|
+
for (; ; ) {
|
|
2275
|
+
const hadWs = ws();
|
|
2276
|
+
if (eof() || peek() === ",") break;
|
|
2277
|
+
let comb = " ";
|
|
2278
|
+
if (s.startsWith(">>>", i)) {
|
|
2279
|
+
comb = ">>>";
|
|
2280
|
+
i += 3;
|
|
2281
|
+
ws();
|
|
2282
|
+
} else if (peek() === ">") {
|
|
2283
|
+
comb = ">";
|
|
2284
|
+
i++;
|
|
2285
|
+
ws();
|
|
2286
|
+
} else if (peek() === "+" || peek() === "~") fail("Sibling combinators are not supported");
|
|
2287
|
+
else if (!hadWs) fail("Unexpected character");
|
|
2288
|
+
const next = compound();
|
|
2289
|
+
if (!next) fail("Expected a selector after the combinator");
|
|
2290
|
+
sel.compounds.push(next);
|
|
2291
|
+
sel.combinators.push(comb);
|
|
2292
|
+
}
|
|
2293
|
+
list.push(sel);
|
|
2294
|
+
if (eof()) break;
|
|
2295
|
+
i++;
|
|
2296
|
+
}
|
|
2297
|
+
return list;
|
|
2298
|
+
}
|
|
2299
|
+
function cssSelectorError(selector) {
|
|
2300
|
+
try {
|
|
2301
|
+
parseCssSelector(selector);
|
|
2302
|
+
return null;
|
|
2303
|
+
} catch (e) {
|
|
2304
|
+
return e instanceof Error ? e.message : "Invalid selector";
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
function attrMatches(test, node) {
|
|
2308
|
+
let actual;
|
|
2309
|
+
if (test.name === "id") actual = node.id;
|
|
2310
|
+
else if (test.name === "class") actual = node.c?.join(" ");
|
|
2311
|
+
else actual = node.a?.[test.name];
|
|
2312
|
+
if (actual === void 0) return false;
|
|
2313
|
+
if (test.op === "exists") return true;
|
|
2314
|
+
let v = test.value ?? "";
|
|
2315
|
+
if (test.insensitive) {
|
|
2316
|
+
actual = actual.toLowerCase();
|
|
2317
|
+
v = v.toLowerCase();
|
|
2318
|
+
}
|
|
2319
|
+
switch (test.op) {
|
|
2320
|
+
case "=":
|
|
2321
|
+
return actual === v;
|
|
2322
|
+
case "^=":
|
|
2323
|
+
return !!v && actual.startsWith(v);
|
|
2324
|
+
case "$=":
|
|
2325
|
+
return !!v && actual.endsWith(v);
|
|
2326
|
+
case "*=":
|
|
2327
|
+
return !!v && actual.includes(v);
|
|
2328
|
+
case "~=":
|
|
2329
|
+
return !!v && actual.split(/\s+/).includes(v);
|
|
2330
|
+
case "|=":
|
|
2331
|
+
return actual === v || actual.startsWith(`${v}-`);
|
|
2332
|
+
default:
|
|
2333
|
+
return false;
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
function compoundMatches(c, node) {
|
|
2337
|
+
if (c.tag && c.tag !== node.t) return false;
|
|
2338
|
+
if (c.id !== void 0 && node.id !== c.id) return false;
|
|
2339
|
+
for (const cls of c.classes) if (!node.c?.includes(cls)) return false;
|
|
2340
|
+
for (const a of c.attrs) if (!attrMatches(a, node)) return false;
|
|
2341
|
+
if (c.nth) {
|
|
2342
|
+
if (!node.n) return false;
|
|
2343
|
+
const { a, b } = c.nth;
|
|
2344
|
+
if (a === 0 ? node.n !== b : (node.n - b) % a !== 0 || (node.n - b) / a < 0) return false;
|
|
2345
|
+
}
|
|
2346
|
+
return true;
|
|
2347
|
+
}
|
|
2348
|
+
function chainMatches(compounds, combinators, nodes, ci = compounds.length - 1, ni = 0) {
|
|
2349
|
+
if (!compoundMatches(compounds[ci], nodes[ni])) return false;
|
|
2350
|
+
if (ci === 0) return true;
|
|
2351
|
+
const comb = combinators[ci - 1];
|
|
2352
|
+
if (comb === ">") return ni + 1 < nodes.length && chainMatches(compounds, combinators, nodes, ci - 1, ni + 1);
|
|
2353
|
+
for (let k = ni + 1; k < nodes.length; k++) if (chainMatches(compounds, combinators, nodes, ci - 1, k)) return true;
|
|
2354
|
+
return false;
|
|
2355
|
+
}
|
|
2356
|
+
function complexMatches(sel, snap) {
|
|
2357
|
+
const segments = [{ compounds: [sel.compounds[0]], combinators: [] }];
|
|
2358
|
+
sel.combinators.forEach((comb, k) => {
|
|
2359
|
+
const next = sel.compounds[k + 1];
|
|
2360
|
+
if (comb === ">>>") segments.push({ compounds: [next], combinators: [] });
|
|
2361
|
+
else {
|
|
2362
|
+
const seg = segments[segments.length - 1];
|
|
2363
|
+
seg.compounds.push(next);
|
|
2364
|
+
seg.combinators.push(comb);
|
|
2365
|
+
}
|
|
2366
|
+
});
|
|
2367
|
+
const last = segments.pop();
|
|
2368
|
+
const nodes = [snap, ...snap.p ?? []];
|
|
2369
|
+
if (!chainMatches(last.compounds, last.combinators, nodes)) return false;
|
|
2370
|
+
const hosts = snap.h ?? [];
|
|
2371
|
+
let from = 0;
|
|
2372
|
+
for (let k = segments.length - 1; k >= 0; k--) {
|
|
2373
|
+
const target = segments[k].compounds[segments[k].compounds.length - 1];
|
|
2374
|
+
let found = -1;
|
|
2375
|
+
for (let j = from; j < hosts.length; j++) {
|
|
2376
|
+
if (compoundMatches(target, hosts[j])) {
|
|
2377
|
+
found = j;
|
|
2378
|
+
break;
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
if (found === -1) return false;
|
|
2382
|
+
from = found + 1;
|
|
2383
|
+
}
|
|
2384
|
+
return true;
|
|
2385
|
+
}
|
|
2386
|
+
var parsedCache = /* @__PURE__ */ new Map();
|
|
2387
|
+
function matchCssSelector(selector, snap) {
|
|
2388
|
+
let list;
|
|
2389
|
+
if (typeof selector === "string") {
|
|
2390
|
+
if (!parsedCache.has(selector)) {
|
|
2391
|
+
if (parsedCache.size > 500) parsedCache.clear();
|
|
2392
|
+
try {
|
|
2393
|
+
parsedCache.set(selector, parseCssSelector(selector));
|
|
2394
|
+
} catch {
|
|
2395
|
+
parsedCache.set(selector, null);
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
list = parsedCache.get(selector);
|
|
2399
|
+
} else list = selector;
|
|
2400
|
+
return !!list && list.some((sel) => complexMatches(sel, snap));
|
|
2401
|
+
}
|
|
2402
|
+
function nodeOfCompound(c) {
|
|
2403
|
+
const node = { t: c.tag ?? "*" };
|
|
2404
|
+
if (c.id) node.id = c.id;
|
|
2405
|
+
if (c.classes.length) node.c = c.classes.slice(0, SNAPSHOT_LIMITS.classes);
|
|
2406
|
+
const a = {};
|
|
2407
|
+
for (const t of c.attrs) if (t.op === "=" && t.value !== void 0) a[t.name] = t.value;
|
|
2408
|
+
if (Object.keys(a).length) node.a = a;
|
|
2409
|
+
if (c.nth && c.nth.a === 0) node.n = c.nth.b;
|
|
2410
|
+
return node;
|
|
2411
|
+
}
|
|
2412
|
+
function snapshotFromSelector(selector, tag) {
|
|
2413
|
+
let list;
|
|
2414
|
+
try {
|
|
2415
|
+
list = parseCssSelector(selector);
|
|
2416
|
+
} catch {
|
|
2417
|
+
return null;
|
|
2418
|
+
}
|
|
2419
|
+
if (list.length !== 1) return null;
|
|
2420
|
+
const sel = list[0];
|
|
2421
|
+
const segments = [[sel.compounds[0]]];
|
|
2422
|
+
sel.combinators.forEach((comb, k) => {
|
|
2423
|
+
if (comb === ">>>") segments.push([sel.compounds[k + 1]]);
|
|
2424
|
+
else segments[segments.length - 1].push(sel.compounds[k + 1]);
|
|
2425
|
+
});
|
|
2426
|
+
const own = segments.pop();
|
|
2427
|
+
const el = nodeOfCompound(own[own.length - 1]);
|
|
2428
|
+
if (el.t === "*" && tag && /^[a-z][a-z0-9-]*$/i.test(tag)) el.t = tag.toLowerCase();
|
|
2429
|
+
const snap = el;
|
|
2430
|
+
const p = own.slice(0, -1).reverse().map(nodeOfCompound);
|
|
2431
|
+
if (p.length) snap.p = p.slice(0, SNAPSHOT_LIMITS.ancestors);
|
|
2432
|
+
const h = segments.reverse().map((seg) => nodeOfCompound(seg[seg.length - 1]));
|
|
2433
|
+
if (h.length) snap.h = h.slice(0, SNAPSHOT_LIMITS.hosts);
|
|
2434
|
+
return snap;
|
|
2435
|
+
}
|
|
2436
|
+
var PAGE_RULE_LIMITS = { rules: 20, value: 500, query: 5 };
|
|
2437
|
+
var escapeRe = (s) => s.replace(/[.+?^${}()|[\]\\*]/g, "\\$&");
|
|
2438
|
+
function globToRegex(pattern) {
|
|
2439
|
+
let out = "";
|
|
2440
|
+
for (let k = 0; k < pattern.length; k++) {
|
|
2441
|
+
const ch = pattern[k];
|
|
2442
|
+
if (ch === "*") {
|
|
2443
|
+
if (pattern[k + 1] === "*") {
|
|
2444
|
+
out += ".*";
|
|
2445
|
+
k++;
|
|
2446
|
+
} else out += "[^/]*";
|
|
2447
|
+
} else if (ch === ":" && (k === 0 || pattern[k - 1] === "/") && /[A-Za-z_]/.test(pattern[k + 1] ?? "")) {
|
|
2448
|
+
let j = k + 1;
|
|
2449
|
+
while (j < pattern.length && /[\w]/.test(pattern[j])) j++;
|
|
2450
|
+
out += "[^/]+";
|
|
2451
|
+
k = j - 1;
|
|
2452
|
+
} else out += escapeRe(ch);
|
|
2453
|
+
}
|
|
2454
|
+
return out;
|
|
2455
|
+
}
|
|
2456
|
+
function pagePattern(raw) {
|
|
2457
|
+
let p = raw.trim();
|
|
2458
|
+
const query = [];
|
|
2459
|
+
const hash = p.indexOf("#");
|
|
2460
|
+
if (hash !== -1) p = p.slice(0, hash);
|
|
2461
|
+
const q = p.indexOf("?");
|
|
2462
|
+
if (q !== -1) {
|
|
2463
|
+
for (const part of p.slice(q + 1).split("&")) {
|
|
2464
|
+
if (!part) continue;
|
|
2465
|
+
const eq = part.indexOf("=");
|
|
2466
|
+
const name = decodeSafe(eq === -1 ? part : part.slice(0, eq));
|
|
2467
|
+
const value = eq === -1 ? void 0 : decodeSafe(part.slice(eq + 1));
|
|
2468
|
+
if (!name) continue;
|
|
2469
|
+
query.push(value === void 0 || value === "*" ? { name, op: "exists" } : { name, op: "equals", value });
|
|
2470
|
+
}
|
|
2471
|
+
p = p.slice(0, q);
|
|
2472
|
+
}
|
|
2473
|
+
let target = "path";
|
|
2474
|
+
if (p.startsWith("//*")) p = p.slice(3);
|
|
2475
|
+
let prefix = "";
|
|
2476
|
+
const abs = /^(https?:)?\/\/([^/]+)(.*)$/i.exec(p);
|
|
2477
|
+
if (abs) {
|
|
2478
|
+
target = "url";
|
|
2479
|
+
prefix = `https?://${globToRegex(abs[2].toLowerCase())}`;
|
|
2480
|
+
p = abs[3] || "/";
|
|
2481
|
+
}
|
|
2482
|
+
if (!p.startsWith("/")) p = `/${p}`;
|
|
2483
|
+
const body = p.length > 1 && p.endsWith("/") ? p.slice(0, -1) : p;
|
|
2484
|
+
const src = body === "/" ? "/?" : `${globToRegex(body)}/?`;
|
|
2485
|
+
return { source: `^${prefix}${src}$`, target, query: query.slice(0, PAGE_RULE_LIMITS.query) };
|
|
2486
|
+
}
|
|
2487
|
+
function decodeSafe(s) {
|
|
2488
|
+
try {
|
|
2489
|
+
return decodeURIComponent(s.replace(/\+/g, " "));
|
|
2490
|
+
} catch {
|
|
2491
|
+
return s;
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
function queryConditionRegex(c) {
|
|
2495
|
+
const name = escapeRe(c.name);
|
|
2496
|
+
switch (c.op) {
|
|
2497
|
+
case "equals":
|
|
2498
|
+
return `[?&]${name}=${escapeRe(encodeLoose(c.value ?? ""))}(&|#|$)`;
|
|
2499
|
+
case "contains":
|
|
2500
|
+
return `[?&]${name}=[^&#]*${escapeRe(encodeLoose(c.value ?? ""))}`;
|
|
2501
|
+
default:
|
|
2502
|
+
return `[?&]${name}(=|&|#|$)`;
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
function encodeLoose(v) {
|
|
2506
|
+
return encodeURIComponent(v).replace(/%2F/gi, "/").replace(/%3A/gi, ":").replace(/%2C/gi, ",").replace(/%40/gi, "@");
|
|
2507
|
+
}
|
|
2508
|
+
function pathOnly(ctx) {
|
|
2509
|
+
if (ctx.path) return ctx.path.split("?")[0] || "/";
|
|
2510
|
+
if (!ctx.url) return null;
|
|
2511
|
+
try {
|
|
2512
|
+
return new URL(ctx.url, "http://x.invalid").pathname;
|
|
2513
|
+
} catch {
|
|
2514
|
+
return null;
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
function regexOrNull(source) {
|
|
2518
|
+
try {
|
|
2519
|
+
return new RegExp(source, "i");
|
|
2520
|
+
} catch {
|
|
2521
|
+
return null;
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
function pageRuleMatches(rule, ctx) {
|
|
2525
|
+
const path = pathOnly(ctx);
|
|
2526
|
+
if (rule.type === "title") {
|
|
2527
|
+
const t = (ctx.title ?? "").toLowerCase();
|
|
2528
|
+
const v = rule.value.toLowerCase();
|
|
2529
|
+
return !!t && (rule.op === "contains" ? t.includes(v) : t === v);
|
|
2530
|
+
}
|
|
2531
|
+
if (rule.type === "regex") {
|
|
2532
|
+
const re2 = regexOrNull(rule.value);
|
|
2533
|
+
return !!re2 && path !== null && re2.test(path);
|
|
2534
|
+
}
|
|
2535
|
+
const pat = pagePattern(rule.value);
|
|
2536
|
+
const re = regexOrNull(pat.source);
|
|
2537
|
+
if (!re) return false;
|
|
2538
|
+
let subject = path;
|
|
2539
|
+
if (pat.target === "url") {
|
|
2540
|
+
if (!ctx.url) return false;
|
|
2541
|
+
subject = ctx.url.split(/[?#]/)[0];
|
|
2542
|
+
}
|
|
2543
|
+
if (subject === null || !re.test(subject)) return false;
|
|
2544
|
+
const conds = [...pat.query, ...rule.query ?? []];
|
|
2545
|
+
for (const c of conds) {
|
|
2546
|
+
const hit = !!ctx.url && new RegExp(queryConditionRegex(c), "i").test(ctx.url);
|
|
2547
|
+
if (c.op === "absent" ? hit : !hit) return false;
|
|
2548
|
+
}
|
|
2549
|
+
return true;
|
|
2550
|
+
}
|
|
2551
|
+
function pageRulesMatch(rules, ctx) {
|
|
2552
|
+
const include = rules.filter((r) => !r.exclude);
|
|
2553
|
+
if (!include.length || !include.some((r) => pageRuleMatches(r, ctx))) return false;
|
|
2554
|
+
return !rules.some((r) => r.exclude && pageRuleMatches(r, ctx));
|
|
2555
|
+
}
|
|
2556
|
+
function pageRuleError(rule) {
|
|
2557
|
+
const v = rule.value?.trim();
|
|
2558
|
+
if (!v) return "A rule needs a value";
|
|
2559
|
+
if (v.length > PAGE_RULE_LIMITS.value) return "The rule is too long";
|
|
2560
|
+
if (rule.type === "regex") {
|
|
2561
|
+
if (!regexOrNull(v)) return `"${v}" is not a valid regular expression`;
|
|
2562
|
+
if (/\(\?[<=!]/.test(v) || /\\[1-9]/.test(v)) return "Look-arounds and back-references are not supported";
|
|
2563
|
+
}
|
|
2564
|
+
if (rule.type === "url" && !regexOrNull(pagePattern(v).source)) return `"${v}" is not a valid URL rule`;
|
|
2565
|
+
for (const q of rule.query ?? []) if (!/^[A-Za-z0-9_.\-[\]]{1,60}$/.test(q.name)) return `"${q.name}" is not a query parameter name`;
|
|
2566
|
+
return null;
|
|
2567
|
+
}
|
|
2568
|
+
var FEATURE_RULE_LIMITS = { rules: 20, value: 1e3 };
|
|
2569
|
+
function globMatch(pattern, value) {
|
|
2570
|
+
const re = new RegExp(`^${pattern.split("*").map(escapeRe).join(".*")}$`, "s");
|
|
2571
|
+
return re.test(value);
|
|
2572
|
+
}
|
|
2573
|
+
function featureRuleMatchesClick(rule, click, css) {
|
|
2574
|
+
if (!rule.selector && !rule.text && !rule.tag && !rule.href) return false;
|
|
2575
|
+
if (rule.selector) {
|
|
2576
|
+
const sel = click.selector ?? "";
|
|
2577
|
+
const v = rule.selector.value;
|
|
2578
|
+
const ok = rule.selector.op === "css" ? css(v) : rule.selector.op === "exact" ? sel === v : rule.selector.op === "prefix" ? sel.startsWith(v) : rule.selector.op === "contains" ? sel.includes(v) : globMatch(v, sel);
|
|
2579
|
+
if (!ok) return false;
|
|
2580
|
+
}
|
|
2581
|
+
if (rule.text) {
|
|
2582
|
+
const t = (click.text ?? "").toLowerCase();
|
|
2583
|
+
const v = rule.text.value.toLowerCase();
|
|
2584
|
+
if (rule.text.op === "contains" ? !t.includes(v) : t !== v) return false;
|
|
2585
|
+
}
|
|
2586
|
+
if (rule.tag && (click.tag ?? "").toLowerCase() !== rule.tag.toLowerCase()) return false;
|
|
2587
|
+
if (rule.href) {
|
|
2588
|
+
const h = click.href ?? "";
|
|
2589
|
+
const v = rule.href.value;
|
|
2590
|
+
if (rule.href.op === "equals" ? h !== v : rule.href.op === "prefix" ? !h.startsWith(v) : !h.includes(v)) return false;
|
|
2591
|
+
}
|
|
2592
|
+
if (rule.platform && (click.platform ?? "web") !== rule.platform) return false;
|
|
2593
|
+
return true;
|
|
2594
|
+
}
|
|
2595
|
+
function featureRuleError(rule) {
|
|
2596
|
+
if (!rule.selector && !rule.text && !rule.tag && !rule.href) return "A feature rule needs a selector, text, tag or link condition";
|
|
2597
|
+
if (rule.selector) {
|
|
2598
|
+
const v = rule.selector.value?.trim();
|
|
2599
|
+
if (!v) return "The selector is empty";
|
|
2600
|
+
if (v.length > FEATURE_RULE_LIMITS.value) return "The selector is too long";
|
|
2601
|
+
if (rule.selector.op === "css") {
|
|
2602
|
+
const err = cssSelectorError(v);
|
|
2603
|
+
if (err) return `Unsupported CSS selector: ${err}`;
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
if (rule.text && !rule.text.value.trim()) return "The text condition is empty";
|
|
2607
|
+
if (rule.href && !rule.href.value.trim()) return "The link condition is empty";
|
|
2608
|
+
if (rule.tag && !/^[a-z][a-z0-9-]{0,40}$/i.test(rule.tag)) return "The tag is not an element name";
|
|
2609
|
+
if (rule.page?.pattern) return pageRuleError({ type: "url", value: rule.page.pattern });
|
|
2610
|
+
return null;
|
|
2611
|
+
}
|
|
2612
|
+
function featureCssSelectors(rules) {
|
|
2613
|
+
const out = [];
|
|
2614
|
+
for (const r of rules) {
|
|
2615
|
+
if (r.exclude || !r.selector) continue;
|
|
2616
|
+
if ((r.selector.op === "css" || r.selector.op === "exact") && !cssSelectorError(r.selector.value)) out.push(r.selector.value);
|
|
2617
|
+
}
|
|
2618
|
+
return out;
|
|
2619
|
+
}
|
|
2620
|
+
var TAG_PROPERTY_LIMITS = { perTag: 10, total: 50, value: 100 };
|
|
2621
|
+
function propertyAttributeAllowed(name) {
|
|
2622
|
+
const n = name.toLowerCase();
|
|
2623
|
+
if (n === "value" || n.startsWith("on") || n === "style" || n === "srcdoc") return false;
|
|
2624
|
+
return /^[a-z][a-z0-9_:.-]{0,60}$/.test(n);
|
|
2625
|
+
}
|
|
2626
|
+
|
|
1698
2627
|
// src/snippet.ts
|
|
1699
2628
|
var SCRIPT_STUB_METHODS = [
|
|
1700
2629
|
"identify",
|
|
@@ -1704,6 +2633,7 @@ var SCRIPT_STUB_METHODS = [
|
|
|
1704
2633
|
"setAccount",
|
|
1705
2634
|
"updateTraits",
|
|
1706
2635
|
"setConsent",
|
|
2636
|
+
"setLocale",
|
|
1707
2637
|
"startGuide",
|
|
1708
2638
|
"stopGuide",
|
|
1709
2639
|
"dismissGuide",
|
|
@@ -1716,7 +2646,10 @@ var SCRIPT_STUB_METHODS = [
|
|
|
1716
2646
|
"closeChecklist",
|
|
1717
2647
|
"completeChecklistTask",
|
|
1718
2648
|
"openComplaint",
|
|
2649
|
+
"openIdeas",
|
|
1719
2650
|
"captureException",
|
|
2651
|
+
"agentConversation",
|
|
2652
|
+
"trackAgentTurn",
|
|
1720
2653
|
"on"
|
|
1721
2654
|
];
|
|
1722
2655
|
var SCRIPT_STUB = `!function(w){if(w.Guidely)return;var g=w.Guidely={_q:[]},c=g._c={};function q(o,k){o[k]=function(){g._q.push([o===c?1:0,k,[].slice.call(arguments)])}}q(g,"init");"${SCRIPT_STUB_METHODS.join(" ")}".split(" ").forEach(function(k){q(c,k)});c.isFeatureEnabled=function(k,f){return!!f};c.getFeatureValue=function(k,f){return f};g.get=function(){return c}}(window);`;
|
|
@@ -1728,15 +2661,541 @@ function scriptSnippet(scriptUrl, initOptions) {
|
|
|
1728
2661
|
<script src="${scriptUrl}" async></script>`;
|
|
1729
2662
|
}
|
|
1730
2663
|
|
|
2664
|
+
// src/localization.ts
|
|
2665
|
+
var DEFAULT_LOCALE = "en";
|
|
2666
|
+
var COMMON_LOCALES = [
|
|
2667
|
+
{ code: "en", name: "English" },
|
|
2668
|
+
{ code: "en-GB", name: "English (UK)" },
|
|
2669
|
+
{ code: "fr", name: "French" },
|
|
2670
|
+
{ code: "fr-CA", name: "French (Canada)" },
|
|
2671
|
+
{ code: "de", name: "German" },
|
|
2672
|
+
{ code: "es", name: "Spanish" },
|
|
2673
|
+
{ code: "es-MX", name: "Spanish (Mexico)" },
|
|
2674
|
+
{ code: "it", name: "Italian" },
|
|
2675
|
+
{ code: "pt", name: "Portuguese" },
|
|
2676
|
+
{ code: "pt-BR", name: "Portuguese (Brazil)" },
|
|
2677
|
+
{ code: "nl", name: "Dutch" },
|
|
2678
|
+
{ code: "sv", name: "Swedish" },
|
|
2679
|
+
{ code: "da", name: "Danish" },
|
|
2680
|
+
{ code: "nb", name: "Norwegian" },
|
|
2681
|
+
{ code: "fi", name: "Finnish" },
|
|
2682
|
+
{ code: "pl", name: "Polish" },
|
|
2683
|
+
{ code: "cs", name: "Czech" },
|
|
2684
|
+
{ code: "tr", name: "Turkish" },
|
|
2685
|
+
{ code: "ru", name: "Russian" },
|
|
2686
|
+
{ code: "uk", name: "Ukrainian" },
|
|
2687
|
+
{ code: "ar", name: "Arabic" },
|
|
2688
|
+
{ code: "he", name: "Hebrew" },
|
|
2689
|
+
{ code: "hi", name: "Hindi" },
|
|
2690
|
+
{ code: "ja", name: "Japanese" },
|
|
2691
|
+
{ code: "ko", name: "Korean" },
|
|
2692
|
+
{ code: "zh-Hans", name: "Chinese (Simplified)" },
|
|
2693
|
+
{ code: "zh-Hant", name: "Chinese (Traditional)" },
|
|
2694
|
+
{ code: "id", name: "Indonesian" },
|
|
2695
|
+
{ code: "th", name: "Thai" },
|
|
2696
|
+
{ code: "vi", name: "Vietnamese" }
|
|
2697
|
+
];
|
|
2698
|
+
function localeName(code) {
|
|
2699
|
+
const exact = COMMON_LOCALES.find((l) => l.code.toLowerCase() === code.toLowerCase());
|
|
2700
|
+
if (exact) return exact.name;
|
|
2701
|
+
const base = COMMON_LOCALES.find((l) => l.code.toLowerCase() === baseLanguage(code));
|
|
2702
|
+
return base ? `${base.name} (${code})` : code;
|
|
2703
|
+
}
|
|
2704
|
+
function normalizeLocale(input) {
|
|
2705
|
+
if (typeof input !== "string") return "";
|
|
2706
|
+
const parts = input.trim().replace(/_/g, "-").split("-").filter(Boolean);
|
|
2707
|
+
if (!parts.length || !/^[a-zA-Z]{2,3}$/.test(parts[0])) return "";
|
|
2708
|
+
return parts.slice(0, 3).map((p, i) => i === 0 ? p.toLowerCase() : p.length === 4 ? p[0].toUpperCase() + p.slice(1).toLowerCase() : p.length === 2 ? p.toUpperCase() : p).join("-");
|
|
2709
|
+
}
|
|
2710
|
+
function baseLanguage(locale) {
|
|
2711
|
+
return normalizeLocale(locale).split("-")[0] ?? "";
|
|
2712
|
+
}
|
|
2713
|
+
function resolveLocale(requested, available, defaultLocale = DEFAULT_LOCALE) {
|
|
2714
|
+
const def = normalizeLocale(defaultLocale) || DEFAULT_LOCALE;
|
|
2715
|
+
const avail = available.map(normalizeLocale).filter(Boolean);
|
|
2716
|
+
const all = [def, ...avail.filter((a) => a.toLowerCase() !== def.toLowerCase())];
|
|
2717
|
+
for (const raw of requested) {
|
|
2718
|
+
const want = normalizeLocale(raw);
|
|
2719
|
+
if (!want) continue;
|
|
2720
|
+
const exact = all.find((a) => a.toLowerCase() === want.toLowerCase());
|
|
2721
|
+
if (exact) return exact;
|
|
2722
|
+
const base = baseLanguage(want);
|
|
2723
|
+
const sameBase = all.find((a) => a.toLowerCase() === base) ?? all.find((a) => baseLanguage(a) === base);
|
|
2724
|
+
if (sameBase) return sameBase;
|
|
2725
|
+
}
|
|
2726
|
+
return def;
|
|
2727
|
+
}
|
|
2728
|
+
function visitorLocales(explicit, traits, platform = []) {
|
|
2729
|
+
const out = [];
|
|
2730
|
+
const push = (v) => {
|
|
2731
|
+
const n = normalizeLocale(v);
|
|
2732
|
+
if (n && !out.includes(n)) out.push(n);
|
|
2733
|
+
};
|
|
2734
|
+
push(explicit);
|
|
2735
|
+
push(traits?.language);
|
|
2736
|
+
push(traits?.locale);
|
|
2737
|
+
for (const p of platform) push(p);
|
|
2738
|
+
return out;
|
|
2739
|
+
}
|
|
2740
|
+
function guideTextEntries(config) {
|
|
2741
|
+
const out = [];
|
|
2742
|
+
const add = (key, source, kind, label) => {
|
|
2743
|
+
if (source && source.trim()) out.push({ key, source, kind, label });
|
|
2744
|
+
};
|
|
2745
|
+
config.steps.forEach((s, i) => {
|
|
2746
|
+
const at = `Step ${i + 1}`;
|
|
2747
|
+
add(`steps.${s.id}.title`, s.title, "text", `${at} \xB7 Title`);
|
|
2748
|
+
add(`steps.${s.id}.body`, s.body, "html", `${at} \xB7 Body`);
|
|
2749
|
+
add(`steps.${s.id}.customHtml`, s.customHtml, "html", `${at} \xB7 Custom HTML`);
|
|
2750
|
+
add(`steps.${s.id}.imageAlt`, s.imageAlt, "text", `${at} \xB7 Image description`);
|
|
2751
|
+
s.buttons.forEach((b) => add(`steps.${s.id}.buttons.${b.id}.label`, b.label, "text", `${at} \xB7 Button \u201C${b.label}\u201D`));
|
|
2752
|
+
});
|
|
2753
|
+
const c = config.checklist;
|
|
2754
|
+
if (c) {
|
|
2755
|
+
add("checklist.launcherLabel", c.launcherLabel, "text", "Checklist \xB7 Launcher label");
|
|
2756
|
+
add("checklist.completionTitle", c.completionTitle, "text", "Checklist \xB7 Completion title");
|
|
2757
|
+
add("checklist.completionBody", c.completionBody, "html", "Checklist \xB7 Completion message");
|
|
2758
|
+
c.tasks.forEach((t, i) => {
|
|
2759
|
+
add(`checklist.tasks.${t.id}.title`, t.title, "text", `Task ${i + 1} \xB7 Title`);
|
|
2760
|
+
add(`checklist.tasks.${t.id}.description`, t.description, "html", `Task ${i + 1} \xB7 Description`);
|
|
2761
|
+
});
|
|
2762
|
+
}
|
|
2763
|
+
const sv = config.survey;
|
|
2764
|
+
if (sv) {
|
|
2765
|
+
sv.questions.forEach((q, i) => {
|
|
2766
|
+
const at = `Question ${i + 1}`;
|
|
2767
|
+
add(`survey.questions.${q.id}.title`, q.title, "text", `${at} \xB7 Question`);
|
|
2768
|
+
add(`survey.questions.${q.id}.description`, q.description, "text", `${at} \xB7 Description`);
|
|
2769
|
+
add(`survey.questions.${q.id}.placeholder`, q.placeholder, "text", `${at} \xB7 Placeholder`);
|
|
2770
|
+
add(`survey.questions.${q.id}.lowLabel`, q.lowLabel, "text", `${at} \xB7 Low label`);
|
|
2771
|
+
add(`survey.questions.${q.id}.highLabel`, q.highLabel, "text", `${at} \xB7 High label`);
|
|
2772
|
+
q.options.forEach((o) => add(`survey.questions.${q.id}.options.${o.id}.label`, o.label, "text", `${at} \xB7 Option \u201C${o.label}\u201D`));
|
|
2773
|
+
});
|
|
2774
|
+
add("survey.thankYouTitle", sv.thankYouTitle, "text", "Survey \xB7 Thank-you title");
|
|
2775
|
+
add("survey.thankYouBody", sv.thankYouBody, "html", "Survey \xB7 Thank-you message");
|
|
2776
|
+
}
|
|
2777
|
+
return out;
|
|
2778
|
+
}
|
|
2779
|
+
function guideLocales(config) {
|
|
2780
|
+
const t = config.localization?.translations ?? {};
|
|
2781
|
+
return Object.keys(t).filter((l) => Object.values(t[l] ?? {}).some((v) => typeof v === "string" && v.trim() !== ""));
|
|
2782
|
+
}
|
|
2783
|
+
function pick(map, key, fallback) {
|
|
2784
|
+
const v = map?.[key];
|
|
2785
|
+
return typeof v === "string" && v.trim() !== "" ? v : fallback;
|
|
2786
|
+
}
|
|
2787
|
+
function applyGuideTranslations(config, map) {
|
|
2788
|
+
if (!map || !Object.keys(map).length) return config;
|
|
2789
|
+
return {
|
|
2790
|
+
...config,
|
|
2791
|
+
steps: config.steps.map((s) => ({
|
|
2792
|
+
...s,
|
|
2793
|
+
title: pick(map, `steps.${s.id}.title`, s.title),
|
|
2794
|
+
body: pick(map, `steps.${s.id}.body`, s.body),
|
|
2795
|
+
customHtml: pick(map, `steps.${s.id}.customHtml`, s.customHtml),
|
|
2796
|
+
imageAlt: pick(map, `steps.${s.id}.imageAlt`, s.imageAlt),
|
|
2797
|
+
buttons: s.buttons.map((b) => ({ ...b, label: pick(map, `steps.${s.id}.buttons.${b.id}.label`, b.label) }))
|
|
2798
|
+
})),
|
|
2799
|
+
checklist: config.checklist ? {
|
|
2800
|
+
...config.checklist,
|
|
2801
|
+
launcherLabel: pick(map, "checklist.launcherLabel", config.checklist.launcherLabel),
|
|
2802
|
+
completionTitle: pick(map, "checklist.completionTitle", config.checklist.completionTitle),
|
|
2803
|
+
completionBody: pick(map, "checklist.completionBody", config.checklist.completionBody),
|
|
2804
|
+
tasks: config.checklist.tasks.map((t) => ({ ...t, title: pick(map, `checklist.tasks.${t.id}.title`, t.title), description: pick(map, `checklist.tasks.${t.id}.description`, t.description) }))
|
|
2805
|
+
} : config.checklist,
|
|
2806
|
+
survey: config.survey ? {
|
|
2807
|
+
...config.survey,
|
|
2808
|
+
thankYouTitle: pick(map, "survey.thankYouTitle", config.survey.thankYouTitle),
|
|
2809
|
+
thankYouBody: pick(map, "survey.thankYouBody", config.survey.thankYouBody),
|
|
2810
|
+
questions: config.survey.questions.map((q) => ({
|
|
2811
|
+
...q,
|
|
2812
|
+
title: pick(map, `survey.questions.${q.id}.title`, q.title),
|
|
2813
|
+
description: pick(map, `survey.questions.${q.id}.description`, q.description),
|
|
2814
|
+
placeholder: pick(map, `survey.questions.${q.id}.placeholder`, q.placeholder),
|
|
2815
|
+
lowLabel: pick(map, `survey.questions.${q.id}.lowLabel`, q.lowLabel),
|
|
2816
|
+
highLabel: pick(map, `survey.questions.${q.id}.highLabel`, q.highLabel),
|
|
2817
|
+
options: q.options.map((o) => ({ ...o, label: pick(map, `survey.questions.${q.id}.options.${o.id}.label`, o.label) }))
|
|
2818
|
+
}))
|
|
2819
|
+
} : config.survey
|
|
2820
|
+
};
|
|
2821
|
+
}
|
|
2822
|
+
function localizeGuide(guide, requested, defaultLocale = DEFAULT_LOCALE) {
|
|
2823
|
+
const translations = guide.config.localization?.translations ?? {};
|
|
2824
|
+
const locale = resolveLocale(requested, guideLocales(guide.config), defaultLocale);
|
|
2825
|
+
const key = Object.keys(translations).find((l) => normalizeLocale(l).toLowerCase() === locale.toLowerCase());
|
|
2826
|
+
if (!key) return { ...guide, locale };
|
|
2827
|
+
return { ...guide, locale, config: applyGuideTranslations(guide.config, translations[key]) };
|
|
2828
|
+
}
|
|
2829
|
+
function translationCoverage(entries, map, locale) {
|
|
2830
|
+
const keys = new Set(entries.map((e) => e.key));
|
|
2831
|
+
const missing = entries.filter((e) => !pick(map, e.key, void 0)).map((e) => e.key);
|
|
2832
|
+
const stale = Object.keys(map ?? {}).filter((k) => !keys.has(k) && (map?.[k] ?? "").trim() !== "");
|
|
2833
|
+
return { locale, total: entries.length, translated: entries.length - missing.length, missing, stale };
|
|
2834
|
+
}
|
|
2835
|
+
function resourceCenterTextEntries(rc) {
|
|
2836
|
+
const out = [];
|
|
2837
|
+
const add = (key, source, kind, label) => {
|
|
2838
|
+
if (source && source.trim()) out.push({ key, source, kind, label });
|
|
2839
|
+
};
|
|
2840
|
+
add("title", rc.title, "text", "Title");
|
|
2841
|
+
add("launcher.label", rc.launcher?.label, "text", "Launcher label");
|
|
2842
|
+
rc.collections.forEach((c) => {
|
|
2843
|
+
add(`collections.${c.id}.name`, c.name, "text", `Collection \u201C${c.name}\u201D`);
|
|
2844
|
+
add(`collections.${c.id}.description`, c.description, "text", `Collection \u201C${c.name}\u201D \xB7 Description`);
|
|
2845
|
+
});
|
|
2846
|
+
rc.links.forEach((l) => add(`links.${l.id}.label`, l.label, "text", `Link \u201C${l.label}\u201D`));
|
|
2847
|
+
rc.faqs.forEach((f, i) => {
|
|
2848
|
+
add(`faqs.${f.id}.question`, f.question, "text", `FAQ ${i + 1} \xB7 Question`);
|
|
2849
|
+
add(`faqs.${f.id}.answer`, f.answer, "html", `FAQ ${i + 1} \xB7 Answer`);
|
|
2850
|
+
});
|
|
2851
|
+
return out;
|
|
2852
|
+
}
|
|
2853
|
+
function articleTextEntries(a) {
|
|
2854
|
+
const out = [];
|
|
2855
|
+
if (a.title.trim()) out.push({ key: "title", source: a.title, kind: "text", label: "Title" });
|
|
2856
|
+
if (a.summary?.trim()) out.push({ key: "summary", source: a.summary, kind: "text", label: "Summary" });
|
|
2857
|
+
if (a.body?.trim()) out.push({ key: "body", source: a.body, kind: "html", label: "Body" });
|
|
2858
|
+
return out;
|
|
2859
|
+
}
|
|
2860
|
+
function resourceCenterLocales(rc) {
|
|
2861
|
+
const set = new Set(Object.keys(rc.translations ?? {}));
|
|
2862
|
+
for (const a of rc.articles) for (const l of Object.keys(a.translations ?? {})) set.add(l);
|
|
2863
|
+
for (const a of rc.announcements ?? []) for (const l of Object.keys(a.translations ?? {})) set.add(l);
|
|
2864
|
+
return [...set];
|
|
2865
|
+
}
|
|
2866
|
+
function translationFor(map, locale) {
|
|
2867
|
+
if (!map) return void 0;
|
|
2868
|
+
const key = Object.keys(map).find((l) => normalizeLocale(l).toLowerCase() === locale.toLowerCase());
|
|
2869
|
+
return key ? map[key] : void 0;
|
|
2870
|
+
}
|
|
2871
|
+
function localizeArticle(a, locale) {
|
|
2872
|
+
const t = translationFor(a.translations, locale);
|
|
2873
|
+
if (!t) return a;
|
|
2874
|
+
const body = t.body?.trim() ? t.body : a.body;
|
|
2875
|
+
return { ...a, title: t.title?.trim() ? t.title : a.title, summary: t.summary?.trim() ? t.summary : a.summary, body, ...t.bodyOmitted ? { bodyOmitted: true } : {} };
|
|
2876
|
+
}
|
|
2877
|
+
function localizeAnnouncement(a, locale) {
|
|
2878
|
+
const t = translationFor(a.translations, locale);
|
|
2879
|
+
if (!t) return a;
|
|
2880
|
+
return { ...a, title: t.title?.trim() ? t.title : a.title, body: t.body?.trim() ? t.body : a.body };
|
|
2881
|
+
}
|
|
2882
|
+
function localizeResourceCenter(rc, requested, defaultLocale = DEFAULT_LOCALE) {
|
|
2883
|
+
const locale = resolveLocale(requested, resourceCenterLocales(rc), defaultLocale);
|
|
2884
|
+
if (locale.toLowerCase() === normalizeLocale(defaultLocale).toLowerCase()) return { ...rc, locale };
|
|
2885
|
+
const map = translationFor(rc.translations, locale);
|
|
2886
|
+
return {
|
|
2887
|
+
...rc,
|
|
2888
|
+
locale,
|
|
2889
|
+
title: pick(map, "title", rc.title),
|
|
2890
|
+
launcher: { ...rc.launcher, label: pick(map, "launcher.label", rc.launcher.label) },
|
|
2891
|
+
collections: rc.collections.map((c) => ({ ...c, name: pick(map, `collections.${c.id}.name`, c.name), description: pick(map, `collections.${c.id}.description`, c.description) })),
|
|
2892
|
+
links: rc.links.map((l) => ({ ...l, label: pick(map, `links.${l.id}.label`, l.label) })),
|
|
2893
|
+
faqs: rc.faqs.map((f) => ({ ...f, question: pick(map, `faqs.${f.id}.question`, f.question), answer: pick(map, `faqs.${f.id}.answer`, f.answer) })),
|
|
2894
|
+
articles: rc.articles.map((a) => localizeArticle(a, locale)),
|
|
2895
|
+
announcements: rc.announcements?.map((a) => localizeAnnouncement(a, locale))
|
|
2896
|
+
};
|
|
2897
|
+
}
|
|
2898
|
+
|
|
2899
|
+
// src/guide-experiments.ts
|
|
2900
|
+
var CONTROL_VARIANT_ID = "control";
|
|
2901
|
+
var GUIDE_EXPERIMENT_STATUSES = ["draft", "running", "completed"];
|
|
2902
|
+
var GUIDE_EXPERIMENT_GOALS = ["guide_completed", "event", "page_visit", "click_text"];
|
|
2903
|
+
var GUIDE_EXPERIMENT_GOAL_LABELS = {
|
|
2904
|
+
guide_completed: "Completes the guide",
|
|
2905
|
+
event: "Tracks an event",
|
|
2906
|
+
page_visit: "Visits a page",
|
|
2907
|
+
click_text: "Clicks an element with text"
|
|
2908
|
+
};
|
|
2909
|
+
function experimentSalt(experimentId) {
|
|
2910
|
+
return `gx:${experimentId}`;
|
|
2911
|
+
}
|
|
2912
|
+
function variantRanges(variants) {
|
|
2913
|
+
let at = 0;
|
|
2914
|
+
return variants.map((v) => {
|
|
2915
|
+
const from = at;
|
|
2916
|
+
at = Math.min(100, at + Math.max(0, Math.round(v.weight)));
|
|
2917
|
+
return { id: v.id, from, to: at };
|
|
2918
|
+
});
|
|
2919
|
+
}
|
|
2920
|
+
function assignGuideVariant(variants, experimentId, subject) {
|
|
2921
|
+
const bucket = rolloutBucket(subject, experimentSalt(experimentId));
|
|
2922
|
+
return variantRanges(variants).find((r) => bucket >= r.from && bucket < r.to)?.id ?? null;
|
|
2923
|
+
}
|
|
2924
|
+
function experimentBucketRules(salt, from, to) {
|
|
2925
|
+
return [
|
|
2926
|
+
{ id: "experiment-from", field: "experiment.bucket", key: salt, op: "gte", value: from },
|
|
2927
|
+
{ id: "experiment-to", field: "experiment.bucket", key: salt, op: "lt", value: to }
|
|
2928
|
+
];
|
|
2929
|
+
}
|
|
2930
|
+
function withExperimentBucket(targeting, salt, from, to) {
|
|
2931
|
+
return { id: "experiment", op: "and", rules: [...experimentBucketRules(salt, from, to), targeting] };
|
|
2932
|
+
}
|
|
2933
|
+
function variantProblems(variants) {
|
|
2934
|
+
const problems = [];
|
|
2935
|
+
if (variants.length < 2) problems.push("An A/B test needs at least two variants.");
|
|
2936
|
+
if (variants.length > 5) problems.push("An A/B test can have at most five variants.");
|
|
2937
|
+
const guides = variants.filter((v) => v.guideId);
|
|
2938
|
+
if (guides.length === 0) problems.push("At least one variant must show a guide.");
|
|
2939
|
+
if (variants.filter((v) => !v.guideId).length > 1) problems.push("Only one variant can be the control group (no guide).");
|
|
2940
|
+
if (new Set(guides.map((v) => v.guideId)).size !== guides.length) problems.push("Each variant needs its own guide.");
|
|
2941
|
+
if (new Set(variants.map((v) => v.id)).size !== variants.length) problems.push("Variant ids must be unique.");
|
|
2942
|
+
if (variants.some((v) => !Number.isInteger(v.weight) || v.weight < 1)) problems.push("Every variant needs a whole-number share of at least 1%.");
|
|
2943
|
+
const total = variants.reduce((s, v) => s + v.weight, 0);
|
|
2944
|
+
if (total !== 100) problems.push(`Traffic shares must add up to 100% (now ${total}%).`);
|
|
2945
|
+
return problems;
|
|
2946
|
+
}
|
|
2947
|
+
function evenWeights(n) {
|
|
2948
|
+
if (n <= 0) return [];
|
|
2949
|
+
const base = Math.floor(100 / n);
|
|
2950
|
+
return Array.from({ length: n }, (_, i) => base + (i < 100 - base * n ? 1 : 0));
|
|
2951
|
+
}
|
|
2952
|
+
|
|
2953
|
+
// src/custom-css.ts
|
|
2954
|
+
var MAX_CUSTOM_CSS = 2e4;
|
|
2955
|
+
var BLOCKED_AT_RULES = /^@(import|charset|namespace|document|-moz-document)\b/i;
|
|
2956
|
+
var ALLOWED_AT_RULES = /^@(media|supports|container|layer|keyframes|-webkit-keyframes|font-face)\b/i;
|
|
2957
|
+
function splitBlocks(css) {
|
|
2958
|
+
const out = [];
|
|
2959
|
+
let i = 0;
|
|
2960
|
+
const n = css.length;
|
|
2961
|
+
while (i < n) {
|
|
2962
|
+
let prelude = "";
|
|
2963
|
+
let quote = null;
|
|
2964
|
+
while (i < n) {
|
|
2965
|
+
const ch = css[i];
|
|
2966
|
+
if (quote) {
|
|
2967
|
+
prelude += ch;
|
|
2968
|
+
if (ch === "\\") prelude += css[++i] ?? "";
|
|
2969
|
+
else if (ch === quote) quote = null;
|
|
2970
|
+
} else if (ch === '"' || ch === "'") {
|
|
2971
|
+
quote = ch;
|
|
2972
|
+
prelude += ch;
|
|
2973
|
+
} else if (ch === "{") break;
|
|
2974
|
+
else if (ch === ";") {
|
|
2975
|
+
prelude = "";
|
|
2976
|
+
} else if (ch === "}") {
|
|
2977
|
+
prelude = "";
|
|
2978
|
+
} else prelude += ch;
|
|
2979
|
+
i++;
|
|
2980
|
+
}
|
|
2981
|
+
if (i >= n) break;
|
|
2982
|
+
i++;
|
|
2983
|
+
let depth = 1;
|
|
2984
|
+
let body = "";
|
|
2985
|
+
quote = null;
|
|
2986
|
+
while (i < n && depth > 0) {
|
|
2987
|
+
const ch = css[i];
|
|
2988
|
+
if (quote) {
|
|
2989
|
+
body += ch;
|
|
2990
|
+
if (ch === "\\") body += css[++i] ?? "";
|
|
2991
|
+
else if (ch === quote) quote = null;
|
|
2992
|
+
} else if (ch === '"' || ch === "'") {
|
|
2993
|
+
quote = ch;
|
|
2994
|
+
body += ch;
|
|
2995
|
+
} else if (ch === "{") {
|
|
2996
|
+
depth++;
|
|
2997
|
+
body += ch;
|
|
2998
|
+
} else if (ch === "}") {
|
|
2999
|
+
depth--;
|
|
3000
|
+
if (depth > 0) body += ch;
|
|
3001
|
+
} else body += ch;
|
|
3002
|
+
i++;
|
|
3003
|
+
}
|
|
3004
|
+
out.push({ prelude: prelude.trim(), body });
|
|
3005
|
+
}
|
|
3006
|
+
return out;
|
|
3007
|
+
}
|
|
3008
|
+
function splitSelectors(list) {
|
|
3009
|
+
const out = [];
|
|
3010
|
+
let depth = 0;
|
|
3011
|
+
let cur = "";
|
|
3012
|
+
for (const ch of list) {
|
|
3013
|
+
if (ch === "(" || ch === "[") depth++;
|
|
3014
|
+
else if (ch === ")" || ch === "]") depth = Math.max(0, depth - 1);
|
|
3015
|
+
if (ch === "," && depth === 0) {
|
|
3016
|
+
out.push(cur.trim());
|
|
3017
|
+
cur = "";
|
|
3018
|
+
} else cur += ch;
|
|
3019
|
+
}
|
|
3020
|
+
if (cur.trim()) out.push(cur.trim());
|
|
3021
|
+
return out;
|
|
3022
|
+
}
|
|
3023
|
+
function safeUrl(raw) {
|
|
3024
|
+
const u = raw.trim().replace(/^['"]|['"]$/g, "").trim();
|
|
3025
|
+
return /^https:\/\//i.test(u) || /^data:image\/(png|jpe?g|gif|webp|svg\+xml)[;,]/i.test(u);
|
|
3026
|
+
}
|
|
3027
|
+
function cleanDeclarations(body) {
|
|
3028
|
+
return body.replace(/url\(([^)]*)\)/gi, (m, inner) => safeUrl(inner) ? m : "none").replace(/expression\s*\(/gi, "(").replace(/javascript\s*:/gi, "").replace(/(^|[;{\s])(-moz-binding|behavior)\s*:[^;]*;?/gi, "$1").replace(/[{}]/g, "").trim();
|
|
3029
|
+
}
|
|
3030
|
+
function sanitizeCustomCss(input) {
|
|
3031
|
+
if (!input) return "";
|
|
3032
|
+
let css = String(input).slice(0, MAX_CUSTOM_CSS);
|
|
3033
|
+
css = css.replace(/\/\*[\s\S]*?\*\//g, "").replace(/<(script|style)\b[^>]*>[\s\S]*?<\/\1\s*>/gi, "").replace(/<\/?[a-z!][^>]*>/gi, "").replace(/</g, "");
|
|
3034
|
+
return render(splitBlocks(css), 0);
|
|
3035
|
+
}
|
|
3036
|
+
function render(blocks, depth) {
|
|
3037
|
+
const parts = [];
|
|
3038
|
+
for (const b of blocks) {
|
|
3039
|
+
if (!b.prelude) continue;
|
|
3040
|
+
if (b.prelude.startsWith("@")) {
|
|
3041
|
+
if (BLOCKED_AT_RULES.test(b.prelude) || !ALLOWED_AT_RULES.test(b.prelude)) continue;
|
|
3042
|
+
if (/^@(-webkit-)?keyframes|^@font-face/i.test(b.prelude)) {
|
|
3043
|
+
const inner = /^@font-face/i.test(b.prelude) ? cleanDeclarations(b.body) : splitBlocks(b.body).map((k) => `${k.prelude}{${cleanDeclarations(k.body)}}`).join("");
|
|
3044
|
+
parts.push(`${b.prelude}{${inner}}`);
|
|
3045
|
+
} else if (depth < 3) parts.push(`${b.prelude}{${render(splitBlocks(b.body), depth + 1)}}`);
|
|
3046
|
+
continue;
|
|
3047
|
+
}
|
|
3048
|
+
const selectors = splitSelectors(b.prelude).filter((s) => !/:host|::slotted|::part/i.test(s));
|
|
3049
|
+
if (!selectors.length) continue;
|
|
3050
|
+
parts.push(`${selectors.join(",")}{${cleanDeclarations(b.body)}}`);
|
|
3051
|
+
}
|
|
3052
|
+
return parts.join("\n");
|
|
3053
|
+
}
|
|
3054
|
+
function scopeCustomCss(css, scope) {
|
|
3055
|
+
return scopeBlocks(splitBlocks(sanitizeCustomCss(css)), scope, 0);
|
|
3056
|
+
}
|
|
3057
|
+
function scopeBlocks(blocks, scope, depth) {
|
|
3058
|
+
const parts = [];
|
|
3059
|
+
for (const b of blocks) {
|
|
3060
|
+
if (b.prelude.startsWith("@")) {
|
|
3061
|
+
if (/^@(-webkit-)?keyframes|^@font-face/i.test(b.prelude)) parts.push(`${b.prelude}{${b.body}}`);
|
|
3062
|
+
else if (depth < 3) parts.push(`${b.prelude}{${scopeBlocks(splitBlocks(b.body), scope, depth + 1)}}`);
|
|
3063
|
+
continue;
|
|
3064
|
+
}
|
|
3065
|
+
const sels = splitSelectors(b.prelude).map((s) => {
|
|
3066
|
+
const self = s.match(/^(:root|html|body|:scope|&)(?![\w-])(.*)$/i);
|
|
3067
|
+
if (self) return `${scope}${self[2] ?? ""}`;
|
|
3068
|
+
return `${scope} ${s}`;
|
|
3069
|
+
});
|
|
3070
|
+
parts.push(`${sels.join(",")}{${b.body}}`);
|
|
3071
|
+
}
|
|
3072
|
+
return parts.join("\n");
|
|
3073
|
+
}
|
|
3074
|
+
|
|
3075
|
+
// src/translation-files.ts
|
|
3076
|
+
function xmlEscape(s) {
|
|
3077
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
3078
|
+
}
|
|
3079
|
+
function xmlUnescape(s) {
|
|
3080
|
+
return s.replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g, (_, c) => c.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")).replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/&#(\d+);/g, (_, d) => String.fromCodePoint(Number(d))).replace(/&#x([0-9a-f]+);/gi, (_, h) => String.fromCodePoint(parseInt(h, 16))).replace(/&/g, "&");
|
|
3081
|
+
}
|
|
3082
|
+
function toXliff(units, opts) {
|
|
3083
|
+
const body = units.map(
|
|
3084
|
+
(u) => ` <trans-unit id="${xmlEscape(u.key)}">
|
|
3085
|
+
<source>${xmlEscape(u.source)}</source>
|
|
3086
|
+
<target${u.target ? "" : ' state="needs-translation"'}>${xmlEscape(u.target)}</target>${u.note ? `
|
|
3087
|
+
<note>${xmlEscape(u.note)}</note>` : ""}
|
|
3088
|
+
</trans-unit>`
|
|
3089
|
+
).join("\n");
|
|
3090
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
3091
|
+
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
|
3092
|
+
<file original="${xmlEscape(opts.original)}" source-language="${xmlEscape(opts.sourceLocale)}" target-language="${xmlEscape(opts.targetLocale)}" datatype="html">
|
|
3093
|
+
<body>
|
|
3094
|
+
${body}
|
|
3095
|
+
</body>
|
|
3096
|
+
</file>
|
|
3097
|
+
</xliff>
|
|
3098
|
+
`;
|
|
3099
|
+
}
|
|
3100
|
+
function parseXliff(xml) {
|
|
3101
|
+
const target = xml.match(/target-language="([^"]+)"/)?.[1] ?? xml.match(/\btrgLang="([^"]+)"/)?.[1];
|
|
3102
|
+
const entries = {};
|
|
3103
|
+
for (const m of xml.matchAll(/<(trans-unit|unit)\b[^>]*\bid="([^"]*)"[^>]*>([\s\S]*?)<\/\1>/g)) {
|
|
3104
|
+
const key = xmlUnescape(m[2]);
|
|
3105
|
+
const t = m[3].match(/<target\b[^>]*>([\s\S]*?)<\/target>/);
|
|
3106
|
+
const text = t ? xmlUnescape(t[1]) : "";
|
|
3107
|
+
if (key && text.trim()) entries[key] = text;
|
|
3108
|
+
}
|
|
3109
|
+
return { targetLocale: target ? xmlUnescape(target) : void 0, entries };
|
|
3110
|
+
}
|
|
3111
|
+
function csvCell(s) {
|
|
3112
|
+
return /[",\n\r]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
|
|
3113
|
+
}
|
|
3114
|
+
function toTranslationCsv(units, targetLocale) {
|
|
3115
|
+
const rows = [["key", "context", "source", targetLocale], ...units.map((u) => [u.key, u.note ?? "", u.source, u.target])];
|
|
3116
|
+
return rows.map((r) => r.map(csvCell).join(",")).join("\r\n") + "\r\n";
|
|
3117
|
+
}
|
|
3118
|
+
function parseCsvRows(text) {
|
|
3119
|
+
const rows = [];
|
|
3120
|
+
let row = [];
|
|
3121
|
+
let cell = "";
|
|
3122
|
+
let quoted2 = false;
|
|
3123
|
+
const src = text.replace(/^\uFEFF/, "");
|
|
3124
|
+
for (let i = 0; i < src.length; i++) {
|
|
3125
|
+
const ch = src[i];
|
|
3126
|
+
if (quoted2) {
|
|
3127
|
+
if (ch === '"') {
|
|
3128
|
+
if (src[i + 1] === '"') {
|
|
3129
|
+
cell += '"';
|
|
3130
|
+
i++;
|
|
3131
|
+
} else quoted2 = false;
|
|
3132
|
+
} else cell += ch;
|
|
3133
|
+
} else if (ch === '"') quoted2 = true;
|
|
3134
|
+
else if (ch === ",") {
|
|
3135
|
+
row.push(cell);
|
|
3136
|
+
cell = "";
|
|
3137
|
+
} else if (ch === "\n" || ch === "\r") {
|
|
3138
|
+
if (ch === "\r" && src[i + 1] === "\n") i++;
|
|
3139
|
+
row.push(cell);
|
|
3140
|
+
rows.push(row);
|
|
3141
|
+
row = [];
|
|
3142
|
+
cell = "";
|
|
3143
|
+
} else cell += ch;
|
|
3144
|
+
}
|
|
3145
|
+
if (cell !== "" || row.length) {
|
|
3146
|
+
row.push(cell);
|
|
3147
|
+
rows.push(row);
|
|
3148
|
+
}
|
|
3149
|
+
return rows.filter((r) => r.some((c) => c.trim() !== ""));
|
|
3150
|
+
}
|
|
3151
|
+
function parseTranslationCsv(text) {
|
|
3152
|
+
const [header, ...rows] = parseCsvRows(text);
|
|
3153
|
+
if (!header) return { entries: {} };
|
|
3154
|
+
const names = header.map((h) => h.trim());
|
|
3155
|
+
const lower = names.map((h) => h.toLowerCase());
|
|
3156
|
+
const keyCol = lower.indexOf("key");
|
|
3157
|
+
if (keyCol < 0) return { entries: {} };
|
|
3158
|
+
let targetCol = lower.indexOf("target");
|
|
3159
|
+
if (targetCol < 0) {
|
|
3160
|
+
for (let i = names.length - 1; i >= 0; i--) {
|
|
3161
|
+
if (!["key", "context", "source", "label", "note"].includes(lower[i])) {
|
|
3162
|
+
targetCol = i;
|
|
3163
|
+
break;
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
}
|
|
3167
|
+
if (targetCol < 0) return { entries: {} };
|
|
3168
|
+
const entries = {};
|
|
3169
|
+
for (const r of rows) {
|
|
3170
|
+
const key = (r[keyCol] ?? "").trim();
|
|
3171
|
+
const value = r[targetCol] ?? "";
|
|
3172
|
+
if (key && value.trim()) entries[key] = value;
|
|
3173
|
+
}
|
|
3174
|
+
return { targetLocale: lower[targetCol] === "target" ? void 0 : names[targetCol], entries };
|
|
3175
|
+
}
|
|
3176
|
+
|
|
1731
3177
|
// src/index.ts
|
|
1732
3178
|
var SDK_API_VERSION = "v1";
|
|
1733
|
-
var SHARED_VERSION = "0.
|
|
3179
|
+
var SHARED_VERSION = "0.11.0";
|
|
1734
3180
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1735
3181
|
0 && (module.exports = {
|
|
1736
3182
|
ADVANCE_ON,
|
|
3183
|
+
AGENT_METADATA_MAX_BYTES,
|
|
3184
|
+
AGENT_METADATA_MAX_KEYS,
|
|
3185
|
+
AGENT_OUTCOMES,
|
|
3186
|
+
AGENT_TOOL_CALLS_PER_TURN,
|
|
3187
|
+
AGENT_TOOL_STATUSES,
|
|
3188
|
+
AGENT_TURNS_PER_BATCH,
|
|
3189
|
+
AGENT_TURN_MAX_TEXT,
|
|
3190
|
+
AGENT_TURN_ROLES,
|
|
1737
3191
|
ANNOTATION_COLORS,
|
|
3192
|
+
APP_LIFECYCLE_EVENTS,
|
|
1738
3193
|
ARTICLE_VISIBILITIES,
|
|
1739
3194
|
AUTOCAPTURE_EVENTS,
|
|
3195
|
+
AgentEventsRequestSchema,
|
|
3196
|
+
AgentMetadataSchema,
|
|
3197
|
+
AgentToolCallSchema,
|
|
3198
|
+
AgentTurnInputSchema,
|
|
1740
3199
|
AppearanceSchema,
|
|
1741
3200
|
AuthoringPickSchema,
|
|
1742
3201
|
AutocaptureSettingsSchema,
|
|
@@ -1744,9 +3203,11 @@ var SHARED_VERSION = "0.10.0";
|
|
|
1744
3203
|
ButtonSchema,
|
|
1745
3204
|
CAPTURE_PARAM,
|
|
1746
3205
|
CAPTURE_SCREENSHOT_MAX_BYTES,
|
|
3206
|
+
COMMON_LOCALES,
|
|
1747
3207
|
COMPLAINT_EVENTS,
|
|
1748
3208
|
COMPLAINT_FIELD_TYPES,
|
|
1749
3209
|
COMPLAINT_STATUSES,
|
|
3210
|
+
CONTROL_VARIANT_ID,
|
|
1750
3211
|
CaptureStepSchema,
|
|
1751
3212
|
CapturedElementSchema,
|
|
1752
3213
|
ChecklistConfigSchema,
|
|
@@ -1755,28 +3216,54 @@ var SHARED_VERSION = "0.10.0";
|
|
|
1755
3216
|
ConversationLookupSchema,
|
|
1756
3217
|
ConversationRatingSchema,
|
|
1757
3218
|
DEFAULT_CAPTURE_SETTINGS,
|
|
3219
|
+
DEFAULT_FEATURE_ATTRIBUTE,
|
|
3220
|
+
DEFAULT_LOCALE,
|
|
1758
3221
|
DEFAULT_PLATFORMS,
|
|
1759
3222
|
EMBED_IFRAME_ATTRS,
|
|
1760
3223
|
EVENT_NAMES,
|
|
1761
3224
|
ErrorTrackingSettingsSchema,
|
|
1762
3225
|
EventBatchSchema,
|
|
3226
|
+
FEATURE_ATTRIBUTE_PATTERN,
|
|
3227
|
+
FEATURE_RULE_LIMITS,
|
|
3228
|
+
FEEDBACK_EVENTS,
|
|
3229
|
+
FEEDBACK_PRIORITIES,
|
|
3230
|
+
FEEDBACK_PRIORITY_LABEL,
|
|
3231
|
+
FEEDBACK_PRIORITY_WEIGHT,
|
|
3232
|
+
FEEDBACK_STATUSES,
|
|
3233
|
+
FEEDBACK_STATUS_LABEL,
|
|
1763
3234
|
FILE_LINK_CLASS,
|
|
3235
|
+
FeedbackCommentSchema,
|
|
3236
|
+
FeedbackFollowSchema,
|
|
3237
|
+
FeedbackListRequestSchema,
|
|
3238
|
+
FeedbackSimilarSchema,
|
|
3239
|
+
FeedbackUpdatesReadSchema,
|
|
3240
|
+
FeedbackVisitorSchema,
|
|
3241
|
+
FeedbackVoteSchema,
|
|
1764
3242
|
FileComplaintSchema,
|
|
1765
3243
|
FrequencySchema,
|
|
1766
3244
|
GUIDELY_ID_ATTRIBUTE,
|
|
3245
|
+
GUIDE_EXPERIMENT_GOALS,
|
|
3246
|
+
GUIDE_EXPERIMENT_GOAL_LABELS,
|
|
3247
|
+
GUIDE_EXPERIMENT_STATUSES,
|
|
1767
3248
|
GUIDE_KINDS,
|
|
1768
3249
|
GUIDE_LIFECYCLE_EVENTS,
|
|
1769
3250
|
GUIDE_STATUSES,
|
|
1770
3251
|
GUIDE_TEMPLATES,
|
|
1771
3252
|
GUIDE_VISIBILITIES,
|
|
1772
3253
|
GuideConfigSchema,
|
|
3254
|
+
GuideLocalizationSchema,
|
|
3255
|
+
GuideScheduleSchema,
|
|
1773
3256
|
GuideStateUpdateSchema,
|
|
3257
|
+
GuideThrottlingSchema,
|
|
1774
3258
|
HEATMAP_VIEWPORTS,
|
|
1775
3259
|
HOWTO_ACTIONS,
|
|
1776
3260
|
HOWTO_STEP_KINDS,
|
|
1777
3261
|
HowToAnnotationSchema,
|
|
1778
3262
|
IdentifyRequestSchema,
|
|
3263
|
+
LOCALE_PATTERN,
|
|
1779
3264
|
LOGGED_IN_AUDIENCE,
|
|
3265
|
+
LocaleSchema,
|
|
3266
|
+
LocalizationSettingsSchema,
|
|
1780
3267
|
MAX_ANNOTATIONS,
|
|
1781
3268
|
MAX_COLLECTION_DEPTH,
|
|
1782
3269
|
MAX_COMPLAINT_ANSWER_LENGTH,
|
|
@@ -1784,6 +3271,11 @@ var SHARED_VERSION = "0.10.0";
|
|
|
1784
3271
|
MAX_COMPLAINT_CHOICES,
|
|
1785
3272
|
MAX_COMPLAINT_FIELDS,
|
|
1786
3273
|
MAX_COMPLAINT_LENGTH,
|
|
3274
|
+
MAX_CUSTOM_CSS,
|
|
3275
|
+
MAX_FEEDBACK_COMMENT,
|
|
3276
|
+
MAX_FEEDBACK_DESCRIPTION,
|
|
3277
|
+
MAX_FEEDBACK_NOTE,
|
|
3278
|
+
MAX_FEEDBACK_TITLE,
|
|
1787
3279
|
MAX_MESSAGE_LENGTH,
|
|
1788
3280
|
MAX_PROPERTY_BYTES,
|
|
1789
3281
|
MAX_STACK_FRAMES,
|
|
@@ -1797,8 +3289,10 @@ var SHARED_VERSION = "0.10.0";
|
|
|
1797
3289
|
MESSAGE_AUTHORS,
|
|
1798
3290
|
MessengerPageRequestSchema,
|
|
1799
3291
|
NETWORK_PLUGIN,
|
|
3292
|
+
NOISY_DATA_ATTR,
|
|
1800
3293
|
NormalizedPointSchema,
|
|
1801
3294
|
NormalizedRectSchema,
|
|
3295
|
+
PAGE_RULE_LIMITS,
|
|
1802
3296
|
PATH_ID_PATTERN,
|
|
1803
3297
|
PDF_BLOCK_CLASS,
|
|
1804
3298
|
PDF_MAX_PAGES,
|
|
@@ -1808,6 +3302,8 @@ var SHARED_VERSION = "0.10.0";
|
|
|
1808
3302
|
PostMessageSchema,
|
|
1809
3303
|
ProjectThemeSchema,
|
|
1810
3304
|
PublishedGuideSchema,
|
|
3305
|
+
RC_MODULE_IDS,
|
|
3306
|
+
RC_MODULE_LABELS,
|
|
1811
3307
|
REPLAY_MAX_COMPRESSED_BYTES,
|
|
1812
3308
|
REPLAY_MAX_RAW_BYTES,
|
|
1813
3309
|
REPLY_TIMES,
|
|
@@ -1817,6 +3313,7 @@ var SHARED_VERSION = "0.10.0";
|
|
|
1817
3313
|
ReplaySettingsSchema,
|
|
1818
3314
|
RuleGroupSchema,
|
|
1819
3315
|
RuleSchema,
|
|
3316
|
+
SCOUT_AGENT_ID,
|
|
1820
3317
|
SCRIPT_STUB,
|
|
1821
3318
|
SCRIPT_STUB_METHODS,
|
|
1822
3319
|
SDK_API_VERSION,
|
|
@@ -1828,30 +3325,46 @@ var SHARED_VERSION = "0.10.0";
|
|
|
1828
3325
|
SHARED_VERSION,
|
|
1829
3326
|
SHOW_ME_CLASS,
|
|
1830
3327
|
SHOW_ME_HREF_PREFIX,
|
|
3328
|
+
SNAPSHOT_ATTRS,
|
|
3329
|
+
SNAPSHOT_LIMITS,
|
|
1831
3330
|
SOURCEMAP_MAX_FILES_PER_UPLOAD,
|
|
1832
3331
|
SOURCEMAP_MAX_FILE_BYTES,
|
|
1833
3332
|
STATUS_LEVELS,
|
|
1834
3333
|
STEP_TYPES,
|
|
1835
3334
|
SURVEY_QUESTION_TYPES,
|
|
3335
|
+
SdkAgentEventsSchema,
|
|
1836
3336
|
SdkEventSchema,
|
|
1837
3337
|
SelectorStrategySchema,
|
|
3338
|
+
SelectorSyntaxError,
|
|
1838
3339
|
StartConversationSchema,
|
|
1839
3340
|
StepBranchSchema,
|
|
1840
3341
|
StepSchema,
|
|
3342
|
+
SubmitFeedbackSchema,
|
|
1841
3343
|
SurveyConfigSchema,
|
|
1842
3344
|
SurveyQuestionSchema,
|
|
1843
3345
|
SurveyResponseRequestSchema,
|
|
3346
|
+
TAG_PROPERTY_LIMITS,
|
|
1844
3347
|
TRIGGER_TYPES,
|
|
1845
3348
|
TargetSchema,
|
|
1846
3349
|
TriggerSchema,
|
|
1847
3350
|
VIDEO_ATTRS,
|
|
3351
|
+
WCAG_AA_LARGE,
|
|
3352
|
+
WCAG_AA_TEXT,
|
|
1848
3353
|
WS_MAX_MESSAGES_PER_SOCKET,
|
|
1849
3354
|
WS_MAX_MESSAGE_BYTES,
|
|
3355
|
+
applyGuideTranslations,
|
|
3356
|
+
articleTextEntries,
|
|
3357
|
+
assignGuideVariant,
|
|
3358
|
+
baseLanguage,
|
|
1850
3359
|
clamp,
|
|
1851
3360
|
cleanLabel,
|
|
1852
3361
|
compare,
|
|
1853
3362
|
compareVersions,
|
|
1854
3363
|
complaintReference,
|
|
3364
|
+
compoundMatches,
|
|
3365
|
+
contrastIssues,
|
|
3366
|
+
contrastRatio,
|
|
3367
|
+
cssSelectorError,
|
|
1855
3368
|
defaultGuideConfig,
|
|
1856
3369
|
defaultStep,
|
|
1857
3370
|
describeCaptureStep,
|
|
@@ -1859,12 +3372,21 @@ var SHARED_VERSION = "0.10.0";
|
|
|
1859
3372
|
emptyRuleGroup,
|
|
1860
3373
|
evaluateRule,
|
|
1861
3374
|
evaluateRules,
|
|
3375
|
+
evenWeights,
|
|
3376
|
+
experimentBucketRules,
|
|
3377
|
+
experimentSalt,
|
|
3378
|
+
featureCssSelectors,
|
|
3379
|
+
featureRuleError,
|
|
3380
|
+
featureRuleMatchesClick,
|
|
3381
|
+
feedbackReference,
|
|
1862
3382
|
fingerprintError,
|
|
1863
3383
|
firstNameFromTraits,
|
|
1864
3384
|
fnv1a,
|
|
1865
3385
|
foldPathIds,
|
|
1866
3386
|
getPath,
|
|
3387
|
+
guideLocales,
|
|
1867
3388
|
guidePlatforms,
|
|
3389
|
+
guideTextEntries,
|
|
1868
3390
|
guidelyIdFromSelector,
|
|
1869
3391
|
hasVideoMedia,
|
|
1870
3392
|
isAllowedEmbedSrc,
|
|
@@ -1877,6 +3399,12 @@ var SHARED_VERSION = "0.10.0";
|
|
|
1877
3399
|
isRuleGroup,
|
|
1878
3400
|
isSafeMediaUrl,
|
|
1879
3401
|
isVideoContentType,
|
|
3402
|
+
localeName,
|
|
3403
|
+
localizeAnnouncement,
|
|
3404
|
+
localizeArticle,
|
|
3405
|
+
localizeGuide,
|
|
3406
|
+
localizeResourceCenter,
|
|
3407
|
+
matchCssSelector,
|
|
1880
3408
|
matchUrlPattern,
|
|
1881
3409
|
matchesAudiences,
|
|
1882
3410
|
matchesHelpQuery,
|
|
@@ -1884,16 +3412,37 @@ var SHARED_VERSION = "0.10.0";
|
|
|
1884
3412
|
mediaMaxBytes,
|
|
1885
3413
|
normalizeErrorMessage,
|
|
1886
3414
|
normalizeFrameFile,
|
|
3415
|
+
normalizeLocale,
|
|
3416
|
+
normalizeSnapshot,
|
|
3417
|
+
orderedModules,
|
|
1887
3418
|
pageLabel,
|
|
1888
3419
|
pageName,
|
|
3420
|
+
pagePattern,
|
|
3421
|
+
pageRuleError,
|
|
3422
|
+
pageRuleMatches,
|
|
3423
|
+
pageRulesMatch,
|
|
1889
3424
|
pageTerms,
|
|
3425
|
+
parseCssSelector,
|
|
3426
|
+
parseCsvRows,
|
|
3427
|
+
parseHexColor,
|
|
1890
3428
|
parseStack,
|
|
3429
|
+
parseTranslationCsv,
|
|
3430
|
+
parseXliff,
|
|
3431
|
+
propertyAttributeAllowed,
|
|
3432
|
+
queryConditionRegex,
|
|
1891
3433
|
randomId,
|
|
3434
|
+
readableTextOn,
|
|
3435
|
+
relativeLuminance,
|
|
1892
3436
|
resolveCaptureSettings,
|
|
3437
|
+
resolveLocale,
|
|
3438
|
+
resourceCenterLocales,
|
|
1893
3439
|
resourceCenterSections,
|
|
3440
|
+
resourceCenterTextEntries,
|
|
1894
3441
|
rolloutBucket,
|
|
1895
3442
|
safeRegExp,
|
|
3443
|
+
sanitizeCustomCss,
|
|
1896
3444
|
sanitizeProperties,
|
|
3445
|
+
scopeCustomCss,
|
|
1897
3446
|
screenPath,
|
|
1898
3447
|
scriptSnippet,
|
|
1899
3448
|
servedArticleAudiences,
|
|
@@ -1901,14 +3450,25 @@ var SHARED_VERSION = "0.10.0";
|
|
|
1901
3450
|
showMeKeyFromHref,
|
|
1902
3451
|
showMeKeys,
|
|
1903
3452
|
slugify,
|
|
3453
|
+
snapshotFromSelector,
|
|
3454
|
+
stableStringify,
|
|
1904
3455
|
stripOrigin,
|
|
1905
3456
|
supportsPlatform,
|
|
1906
3457
|
templateConfig,
|
|
1907
3458
|
toEmbedUrl,
|
|
3459
|
+
toTranslationCsv,
|
|
3460
|
+
toXliff,
|
|
3461
|
+
translationCoverage,
|
|
3462
|
+
unreadAnnouncements,
|
|
1908
3463
|
validateGuideConfig,
|
|
3464
|
+
variantProblems,
|
|
3465
|
+
variantRanges,
|
|
3466
|
+
visibleAnnouncements,
|
|
1909
3467
|
visibleArticleIds,
|
|
1910
3468
|
visibleButtons,
|
|
1911
3469
|
visitorAudiences,
|
|
3470
|
+
visitorLocales,
|
|
3471
|
+
withExperimentBucket,
|
|
1912
3472
|
withVisibility
|
|
1913
3473
|
});
|
|
1914
3474
|
//# sourceMappingURL=index.cjs.map
|