@percy/dom 1.31.5-beta.2 → 1.31.5
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/bundle.js +135 -186
- package/package.json +3 -3
package/dist/bundle.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
process.env.__PERCY_BROWSERIFIED__ = true;
|
|
8
8
|
|
|
9
9
|
// Creates a resource object from an element's unique ID and data URL
|
|
10
|
-
function resourceFromDataURL
|
|
10
|
+
function resourceFromDataURL(uid, dataURL) {
|
|
11
11
|
// split dataURL into desired parts
|
|
12
12
|
let [data, content] = dataURL.split(',');
|
|
13
13
|
let [, mimetype] = data.split(':');
|
|
@@ -142,8 +142,8 @@
|
|
|
142
142
|
(_dom$querySelector = dom.querySelector('head')) === null || _dom$querySelector === void 0 || _dom$querySelector.prepend($base);
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
// Recursively serializes iframe documents into srcdoc attributes
|
|
146
|
-
|
|
145
|
+
// Recursively serializes iframe documents into srcdoc attributes.
|
|
146
|
+
function serializeFrames({
|
|
147
147
|
dom,
|
|
148
148
|
clone,
|
|
149
149
|
warnings,
|
|
@@ -170,8 +170,8 @@
|
|
|
170
170
|
// the frame has yet to load and wasn't built with js, it is unsafe to serialize
|
|
171
171
|
if (!builtWithJs && !frame.contentWindow.performance.timing.loadEventEnd) continue;
|
|
172
172
|
|
|
173
|
-
// recersively serialize contents
|
|
174
|
-
let serialized =
|
|
173
|
+
// recersively serialize contents
|
|
174
|
+
let serialized = serializeDOM({
|
|
175
175
|
domTransformation: setBaseURI,
|
|
176
176
|
dom: frame.contentDocument,
|
|
177
177
|
enableJavaScript,
|
|
@@ -196,7 +196,7 @@
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
// Returns a mostly random uid.
|
|
199
|
-
function uid
|
|
199
|
+
function uid() {
|
|
200
200
|
return `_${Math.random().toString(36).substr(2, 9)}`;
|
|
201
201
|
}
|
|
202
202
|
function markElement(domElement, disableShadowDOM, forceShadowAsLightDOM) {
|
|
@@ -204,7 +204,7 @@
|
|
|
204
204
|
// Mark elements that are to be serialized later with a data attribute.
|
|
205
205
|
if (['input', 'textarea', 'select', 'iframe', 'canvas', 'video', 'style'].includes((_domElement$tagName = domElement.tagName) === null || _domElement$tagName === void 0 ? void 0 : _domElement$tagName.toLowerCase())) {
|
|
206
206
|
if (!domElement.getAttribute('data-percy-element-id')) {
|
|
207
|
-
domElement.setAttribute('data-percy-element-id', uid
|
|
207
|
+
domElement.setAttribute('data-percy-element-id', uid());
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
210
|
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
domElement.setAttribute('data-percy-shadow-host', '');
|
|
216
216
|
}
|
|
217
217
|
if (!domElement.getAttribute('data-percy-element-id')) {
|
|
218
|
-
domElement.setAttribute('data-percy-element-id', uid
|
|
218
|
+
domElement.setAttribute('data-percy-element-id', uid());
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
}
|
|
@@ -250,7 +250,7 @@
|
|
|
250
250
|
}
|
|
251
251
|
function createStyleResource(styleSheet) {
|
|
252
252
|
const styles = Array.from(styleSheet.cssRules).map(cssRule => cssRule.cssText).join('\n');
|
|
253
|
-
let resource = resourceFromText(uid
|
|
253
|
+
let resource = resourceFromText(uid(), 'text/css', styles);
|
|
254
254
|
return resource;
|
|
255
255
|
}
|
|
256
256
|
function serializeCSSOM(ctx) {
|
|
@@ -416,7 +416,7 @@
|
|
|
416
416
|
if (!dataUrl || dataUrl === 'data:,') continue;
|
|
417
417
|
|
|
418
418
|
// create a resource for the canvas data
|
|
419
|
-
let resource = resourceFromDataURL
|
|
419
|
+
let resource = resourceFromDataURL(percyElementId, dataUrl);
|
|
420
420
|
resources.add(resource);
|
|
421
421
|
|
|
422
422
|
// create and insert image element with the resource URL
|
|
@@ -467,7 +467,7 @@
|
|
|
467
467
|
if (!dataUrl || dataUrl === 'data:,') continue;
|
|
468
468
|
|
|
469
469
|
// create a resource from the serialized data url
|
|
470
|
-
let resource = resourceFromDataURL
|
|
470
|
+
let resource = resourceFromDataURL(videoId, dataUrl);
|
|
471
471
|
resources.add(resource);
|
|
472
472
|
|
|
473
473
|
// use a data attribute to avoid making a real request
|
|
@@ -478,186 +478,137 @@
|
|
|
478
478
|
}
|
|
479
479
|
}
|
|
480
480
|
|
|
481
|
-
/* global
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
// Helper: Create resource from data URL
|
|
489
|
-
function resourceFromDataURL(id, dataURL) {
|
|
490
|
-
let [data, content] = dataURL.split(',');
|
|
491
|
-
let [, mimetype] = data.split(':');
|
|
492
|
-
[mimetype] = mimetype.split(';');
|
|
493
|
-
let [, ext] = mimetype.split('/');
|
|
494
|
-
let path = `/__serialized__/${id}.${ext}`;
|
|
495
|
-
let url = new URL(path, document.URL).toString();
|
|
496
|
-
return {
|
|
497
|
-
url,
|
|
498
|
-
content,
|
|
499
|
-
mimetype
|
|
500
|
-
};
|
|
481
|
+
/* global XPathResult */
|
|
482
|
+
const PSEDUO_ELEMENT_MARKER_ATTR = 'data-percy-pseudo-element-id';
|
|
483
|
+
function markElementIfNeeded(element, markWithId) {
|
|
484
|
+
if (markWithId && !element.getAttribute(PSEDUO_ELEMENT_MARKER_ATTR)) {
|
|
485
|
+
element.setAttribute(PSEDUO_ELEMENT_MARKER_ATTR, uid());
|
|
486
|
+
}
|
|
501
487
|
}
|
|
502
488
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
489
|
+
/**
|
|
490
|
+
* Get all elements matching the pseudoClassEnabledElements configuration
|
|
491
|
+
* @param {Document} dom - The document to search
|
|
492
|
+
* @param {Object} config - Configuration with id, className, and xpath arrays
|
|
493
|
+
* @param {boolean} markWithId - Whether to mark elements with PSEDUO_ELEMENT_MARKER_ATTR
|
|
494
|
+
* @returns {Array} Array of elements found
|
|
495
|
+
*/
|
|
496
|
+
function getElementsToProcess(ctx, config, markWithId = false) {
|
|
497
|
+
const {
|
|
498
|
+
dom
|
|
499
|
+
} = ctx;
|
|
500
|
+
const elements = [];
|
|
501
|
+
if (config.id && Array.isArray(config.id)) {
|
|
502
|
+
for (const id of config.id) {
|
|
503
|
+
const element = dom.getElementById(id);
|
|
504
|
+
if (!element) {
|
|
505
|
+
ctx.warnings.add(`No element found with ID: ${id} for pseudo-class serialization`);
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
markElementIfNeeded(element, markWithId);
|
|
509
|
+
elements.push(element);
|
|
512
510
|
}
|
|
513
|
-
blobUrls.push({
|
|
514
|
-
element: el,
|
|
515
|
-
blobUrl: el.src,
|
|
516
|
-
property: 'src',
|
|
517
|
-
id: el.getAttribute('data-percy-element-id')
|
|
518
|
-
});
|
|
519
511
|
}
|
|
520
512
|
|
|
521
|
-
//
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
513
|
+
// Process only first match per class name
|
|
514
|
+
if (config.className && Array.isArray(config.className)) {
|
|
515
|
+
for (const className of config.className) {
|
|
516
|
+
const elementCollection = dom.getElementsByClassName(className);
|
|
517
|
+
if (!elementCollection.length) {
|
|
518
|
+
ctx.warnings.add(`No element found with class name: ${className} for pseudo-class serialization`);
|
|
519
|
+
continue;
|
|
520
|
+
}
|
|
521
|
+
const element = elementCollection[0];
|
|
522
|
+
markElementIfNeeded(element, markWithId);
|
|
523
|
+
elements.push(element);
|
|
531
524
|
}
|
|
532
|
-
blobUrls.push({
|
|
533
|
-
element: el,
|
|
534
|
-
blobUrl: el.href,
|
|
535
|
-
property: 'href',
|
|
536
|
-
id: el.getAttribute('data-percy-element-id')
|
|
537
|
-
});
|
|
538
525
|
}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
if (blobMatches) {
|
|
547
|
-
if (!el.getAttribute('data-percy-element-id')) {
|
|
548
|
-
el.setAttribute('data-percy-element-id', uid());
|
|
549
|
-
}
|
|
550
|
-
for (const match of blobMatches) {
|
|
551
|
-
const urlMatch = match.match(/url\(["']?(blob:[^"')]+)["']?\)/);
|
|
552
|
-
blobUrls.push({
|
|
553
|
-
element: el,
|
|
554
|
-
blobUrl: urlMatch[1],
|
|
555
|
-
property: 'style',
|
|
556
|
-
id: el.getAttribute('data-percy-element-id')
|
|
557
|
-
});
|
|
526
|
+
if (config.xpath && Array.isArray(config.xpath)) {
|
|
527
|
+
for (const xpathExpression of config.xpath) {
|
|
528
|
+
try {
|
|
529
|
+
const element = dom.evaluate(xpathExpression, dom, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
|
|
530
|
+
if (!element) {
|
|
531
|
+
ctx.warnings.add(`No element found for XPath: ${xpathExpression} for pseudo-class serialization`);
|
|
532
|
+
continue;
|
|
558
533
|
}
|
|
534
|
+
markElementIfNeeded(element, markWithId);
|
|
535
|
+
} catch (err) {
|
|
536
|
+
console.warn(`Invalid XPath expression "${xpathExpression}". Error: ${err.message}`);
|
|
559
537
|
}
|
|
560
538
|
}
|
|
561
539
|
}
|
|
562
|
-
return
|
|
540
|
+
return elements;
|
|
563
541
|
}
|
|
564
542
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
// Fetch the blob data
|
|
575
|
-
const response = await fetch(blobUrl);
|
|
576
|
-
const blob = await response.blob();
|
|
577
|
-
|
|
578
|
-
// Convert blob to data URL using FileReader
|
|
579
|
-
const dataUrl = await new Promise((resolve, reject) => {
|
|
580
|
-
/* eslint-disable-next-line no-undef */
|
|
581
|
-
const reader = new FileReader();
|
|
582
|
-
reader.onloadend = () => resolve(reader.result);
|
|
583
|
-
reader.onerror = reject;
|
|
584
|
-
reader.readAsDataURL(blob);
|
|
585
|
-
});
|
|
586
|
-
|
|
587
|
-
// Create Percy resource
|
|
588
|
-
const resource = resourceFromDataURL(id, dataUrl);
|
|
589
|
-
|
|
590
|
-
/* istanbul ignore else: property is always one of 'src', 'href', or 'style' */
|
|
591
|
-
if (property === 'src') {
|
|
592
|
-
element.removeAttribute('src');
|
|
593
|
-
element.setAttribute('data-percy-serialized-attribute-src', resource.url);
|
|
594
|
-
} else if (property === 'href') {
|
|
595
|
-
element.removeAttribute('href');
|
|
596
|
-
element.setAttribute('data-percy-serialized-attribute-href', resource.url);
|
|
597
|
-
} else if (property === 'style') {
|
|
598
|
-
const currentStyle = element.getAttribute('style');
|
|
599
|
-
const updatedStyle = currentStyle.replace(blobUrl, resource.url);
|
|
600
|
-
element.setAttribute('style', updatedStyle);
|
|
601
|
-
}
|
|
602
|
-
return resource;
|
|
603
|
-
} catch (err) {
|
|
604
|
-
throw new Error(`Failed to convert blob URL ${blobUrl}: ${err.message}`);
|
|
605
|
-
}
|
|
543
|
+
/**
|
|
544
|
+
* Mark pseudo-class enabled elements with data-percy-element-id before cloning
|
|
545
|
+
* This must be called before the DOM is cloned
|
|
546
|
+
* @param {Document} dom - The document to mark
|
|
547
|
+
* @param {Object} config - Configuration with id and xpath arrays
|
|
548
|
+
*/
|
|
549
|
+
function markPseudoClassElements(ctx, config) {
|
|
550
|
+
if (!config) return;
|
|
551
|
+
getElementsToProcess(ctx, config, true);
|
|
606
552
|
}
|
|
607
553
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
processedCount++;
|
|
620
|
-
}
|
|
621
|
-
} catch (e) {
|
|
622
|
-
// Invalid URL, skip
|
|
623
|
-
}
|
|
624
|
-
}
|
|
554
|
+
/**
|
|
555
|
+
* Convert CSSStyleDeclaration to CSS text with !important declarations
|
|
556
|
+
* @param {CSSStyleDeclaration} styles - Computed style declaration
|
|
557
|
+
* @returns {string} CSS text
|
|
558
|
+
*/
|
|
559
|
+
function stylesToCSSText(styles) {
|
|
560
|
+
const cssProperties = [];
|
|
561
|
+
for (let i = 0; i < styles.length; i++) {
|
|
562
|
+
const property = styles[i];
|
|
563
|
+
const value = styles.getPropertyValue(property);
|
|
564
|
+
cssProperties.push(`${property}: ${value} !important;`);
|
|
625
565
|
}
|
|
626
|
-
return
|
|
566
|
+
return cssProperties.join(' ');
|
|
627
567
|
}
|
|
628
568
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
569
|
+
/**
|
|
570
|
+
* Process pseudo-class elements and add percy-pseudo-class CSS
|
|
571
|
+
* @param {Object} ctx - Serialization context
|
|
572
|
+
*/
|
|
573
|
+
function serializePseudoClasses(ctx) {
|
|
574
|
+
if (!ctx.pseudoClassEnabledElements) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
const elements = ctx.dom.querySelectorAll(`[${PSEDUO_ELEMENT_MARKER_ATTR}]`);
|
|
578
|
+
if (elements.length === 0) {
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
const cssRules = [];
|
|
582
|
+
for (const element of elements) {
|
|
583
|
+
const percyElementId = element.getAttribute(PSEDUO_ELEMENT_MARKER_ATTR);
|
|
584
|
+
const cloneElement = ctx.clone.querySelector(`[${PSEDUO_ELEMENT_MARKER_ATTR}="${percyElementId}"]`);
|
|
585
|
+
if (!cloneElement) {
|
|
586
|
+
ctx.warnings.add(`Element not found for pseudo-class serialization with percy-element-id: ${percyElementId}`);
|
|
587
|
+
continue;
|
|
588
|
+
}
|
|
589
|
+
try {
|
|
590
|
+
// Get all computed styles including pseudo-classes
|
|
591
|
+
const computedStyles = window.getComputedStyle(element);
|
|
592
|
+
const cssText = stylesToCSSText(computedStyles);
|
|
593
|
+
const selector = `[${PSEDUO_ELEMENT_MARKER_ATTR}="${percyElementId}"]`;
|
|
594
|
+
cssRules.push(`${selector} { ${cssText} }`);
|
|
595
|
+
} catch (err) {
|
|
596
|
+
console.warn('Could not get computed styles for element', element, err);
|
|
597
|
+
}
|
|
637
598
|
}
|
|
638
599
|
|
|
639
|
-
//
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
}
|
|
650
|
-
warnings.add(err.message);
|
|
651
|
-
console.warn(`Percy: ${err.message}`);
|
|
652
|
-
return null;
|
|
653
|
-
}));
|
|
654
|
-
|
|
655
|
-
// Wait for all conversions
|
|
656
|
-
await Promise.all(conversions);
|
|
657
|
-
const successCount = processedResources.length;
|
|
658
|
-
console.debug(`Percy: Successfully converted ${successCount}/${blobUrls.length} blob URLs`);
|
|
600
|
+
// Inject CSS into cloned document
|
|
601
|
+
if (cssRules.length > 0) {
|
|
602
|
+
const styleElement = ctx.dom.createElement('style');
|
|
603
|
+
styleElement.setAttribute('data-percy-pseudo-class-styles', 'true');
|
|
604
|
+
styleElement.textContent = cssRules.join('\n');
|
|
605
|
+
const head = ctx.clone.head || ctx.clone.querySelector('head');
|
|
606
|
+
if (head) {
|
|
607
|
+
head.appendChild(styleElement);
|
|
608
|
+
} else {
|
|
609
|
+
ctx.warnings.add('Could not inject pseudo-class styles: no <head> element found');
|
|
610
|
+
}
|
|
659
611
|
}
|
|
660
|
-
return processedResources;
|
|
661
612
|
}
|
|
662
613
|
|
|
663
614
|
// Drop loading attribute. We do not scroll page in discovery stage but we want to make sure that
|
|
@@ -711,7 +662,7 @@
|
|
|
711
662
|
if (base64String == null) return;
|
|
712
663
|
if (!cache.has(base64String)) {
|
|
713
664
|
// create a resource from the serialized data url
|
|
714
|
-
let resource = resourceFromText(uid
|
|
665
|
+
let resource = resourceFromText(uid(), mimetype, base64String);
|
|
715
666
|
resources.add(resource);
|
|
716
667
|
cache.set(base64String, resource.url);
|
|
717
668
|
}
|
|
@@ -931,9 +882,9 @@
|
|
|
931
882
|
// include the doctype with the html string
|
|
932
883
|
return doctype(ctx.dom) + html;
|
|
933
884
|
}
|
|
934
|
-
|
|
885
|
+
function serializeElements(ctx) {
|
|
935
886
|
serializeInputElements(ctx);
|
|
936
|
-
|
|
887
|
+
serializeFrames(ctx);
|
|
937
888
|
serializeVideos(ctx);
|
|
938
889
|
if (!ctx.enableJavaScript) {
|
|
939
890
|
serializeCSSOM(ctx);
|
|
@@ -948,8 +899,7 @@
|
|
|
948
899
|
// getHTML requires shadowRoot to be passed explicitly
|
|
949
900
|
// to serialize the shadow elements properly
|
|
950
901
|
ctx.shadowRootElements.push(cloneShadowHost.shadowRoot);
|
|
951
|
-
|
|
952
|
-
// AWAIT recursive call for shadow DOM
|
|
902
|
+
serializeElements({
|
|
953
903
|
...ctx,
|
|
954
904
|
dom: shadowHost.shadowRoot,
|
|
955
905
|
clone: cloneShadowHost.shadowRoot
|
|
@@ -977,8 +927,8 @@
|
|
|
977
927
|
window.resizeCount = 0;
|
|
978
928
|
}
|
|
979
929
|
|
|
980
|
-
// Serializes a document and returns the resulting DOM string
|
|
981
|
-
|
|
930
|
+
// Serializes a document and returns the resulting DOM string.
|
|
931
|
+
function serializeDOM(options) {
|
|
982
932
|
var _ctx$clone$body;
|
|
983
933
|
let {
|
|
984
934
|
dom = document,
|
|
@@ -990,7 +940,8 @@
|
|
|
990
940
|
reshuffleInvalidTags = options === null || options === void 0 ? void 0 : options.reshuffle_invalid_tags,
|
|
991
941
|
ignoreCanvasSerializationErrors = options === null || options === void 0 ? void 0 : options.ignore_canvas_serialization_errors,
|
|
992
942
|
ignoreStyleSheetSerializationErrors = options === null || options === void 0 ? void 0 : options.ignore_style_sheet_serialization_errors,
|
|
993
|
-
forceShadowAsLightDOM = options === null || options === void 0 ? void 0 : options.force_shadow_dom_as_light_dom
|
|
943
|
+
forceShadowAsLightDOM = options === null || options === void 0 ? void 0 : options.force_shadow_dom_as_light_dom,
|
|
944
|
+
pseudoClassEnabledElements = options === null || options === void 0 ? void 0 : options.pseudo_class_enabled_elements
|
|
994
945
|
} = options || {};
|
|
995
946
|
|
|
996
947
|
// keep certain records throughout serialization
|
|
@@ -1004,18 +955,16 @@
|
|
|
1004
955
|
disableShadowDOM,
|
|
1005
956
|
ignoreCanvasSerializationErrors,
|
|
1006
957
|
ignoreStyleSheetSerializationErrors,
|
|
1007
|
-
forceShadowAsLightDOM
|
|
958
|
+
forceShadowAsLightDOM,
|
|
959
|
+
pseudoClassEnabledElements
|
|
1008
960
|
};
|
|
1009
961
|
ctx.dom = dom;
|
|
1010
|
-
|
|
1011
|
-
// STEP 1: Preprocess dynamic resources (async) - before cloning
|
|
1012
|
-
await preprocessDynamicResources(ctx.dom, ctx.resources, ctx.warnings);
|
|
1013
|
-
|
|
1014
|
-
// STEP 2: Clone the DOM
|
|
962
|
+
markPseudoClassElements(ctx, pseudoClassEnabledElements);
|
|
1015
963
|
ctx.clone = cloneNodeAndShadow(ctx);
|
|
964
|
+
serializeElements(ctx);
|
|
1016
965
|
|
|
1017
|
-
// STEP
|
|
1018
|
-
|
|
966
|
+
// STEP 4: Process pseudo-class enabled elements
|
|
967
|
+
serializePseudoClasses(ctx);
|
|
1019
968
|
if (domTransformation) {
|
|
1020
969
|
try {
|
|
1021
970
|
// eslint-disable-next-line no-eval
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percy/dom",
|
|
3
|
-
"version": "1.31.5
|
|
3
|
+
"version": "1.31.5",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"publishConfig": {
|
|
11
11
|
"access": "public",
|
|
12
|
-
"tag": "
|
|
12
|
+
"tag": "latest"
|
|
13
13
|
},
|
|
14
14
|
"main": "dist/bundle.js",
|
|
15
15
|
"browser": "dist/bundle.js",
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"interactor.js": "^2.0.0-beta.10"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "835297c48a25843d8c719d6b476134c603721d13"
|
|
39
39
|
}
|