@papercups-io/chat-widget
Advanced tools
Comparing version 1.0.16 to 1.0.17-beta.0
@@ -9,2 +9,20 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return _extends.apply(this, arguments); | ||
} | ||
var Path = function Path(props) { | ||
@@ -326,2 +344,293 @@ return React.createElement(framerMotion.motion.path, Object.assign({ | ||
var ArrayProto = Array.prototype; | ||
var ObjProto = Object.prototype; | ||
var toString = ObjProto.toString; | ||
var hasOwnProperty = ObjProto.hasOwnProperty; | ||
var win = window; | ||
var navigator = win.navigator; | ||
var windowOpera = win.opera; | ||
var userAgent = navigator.userAgent; | ||
var nativeForEach = ArrayProto.forEach; | ||
var breaker = {}; | ||
function isString(obj) { | ||
return toString.call(obj) == '[object String]'; | ||
} | ||
function includes(str, needle) { | ||
return str.indexOf(needle) !== -1; | ||
} | ||
function timestamp() { | ||
Date.now = Date.now || function () { | ||
return +new Date(); | ||
}; | ||
return Date.now(); | ||
} | ||
function each(obj, iterator, context) { | ||
if (obj === null || obj === undefined) { | ||
return; | ||
} | ||
if (nativeForEach && obj.forEach === nativeForEach) { | ||
obj.forEach(iterator, context); | ||
} else if (obj.length === +obj.length) { | ||
for (var i = 0, l = obj.length; i < l; i++) { | ||
if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) { | ||
return; | ||
} | ||
} | ||
} else { | ||
for (var key in obj) { | ||
if (hasOwnProperty.call(obj, key)) { | ||
if (iterator.call(context, obj[key], key, obj) === breaker) { | ||
return; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
function extend(obj) { | ||
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
} | ||
each(args, function (source) { | ||
for (var prop in source) { | ||
if (source[prop] !== void 0) { | ||
obj[prop] = source[prop]; | ||
} | ||
} | ||
}); | ||
return obj; | ||
} | ||
function stripEmptyProperties(obj) { | ||
var ret = {}; | ||
each(obj, function (v, k) { | ||
if (isString(v) && v.length > 0) { | ||
ret[k] = v; | ||
} | ||
}); | ||
return ret; | ||
} | ||
function getQueryParam(url, param) { | ||
param = param.replace(/[[]/, '\\[').replace(/[\]]/, '\\]'); | ||
var regexS = '[\\?&]' + param + '=([^&#]*)'; | ||
var regex = new RegExp(regexS); | ||
var results = regex.exec(url); | ||
if (results === null || results && typeof results[1] !== 'string' && results[1].length) { | ||
return ''; | ||
} else { | ||
var result = results[1]; | ||
try { | ||
result = decodeURIComponent(result); | ||
} catch (err) { | ||
console.error('Skipping decoding for malformed query param: ' + result); | ||
} | ||
return result.replace(/\+/g, ' '); | ||
} | ||
} | ||
var info = { | ||
campaignParams: function campaignParams() { | ||
var campaign_keywords = 'utm_source utm_medium utm_campaign utm_content utm_term'.split(' '); | ||
var kw = ''; | ||
var params = {}; | ||
each(campaign_keywords, function (kwkey) { | ||
kw = getQueryParam(document.URL, kwkey); | ||
if (kw.length) { | ||
params[kwkey] = kw; | ||
} | ||
}); | ||
return params; | ||
}, | ||
searchEngine: function searchEngine(referrer) { | ||
if (referrer.search('https?://(.*)google.([^/?]*)') === 0) { | ||
return 'google'; | ||
} else if (referrer.search('https?://(.*)bing.com') === 0) { | ||
return 'bing'; | ||
} else if (referrer.search('https?://(.*)yahoo.com') === 0) { | ||
return 'yahoo'; | ||
} else if (referrer.search('https?://(.*)duckduckgo.com') === 0) { | ||
return 'duckduckgo'; | ||
} else { | ||
return null; | ||
} | ||
}, | ||
searchInfo: function searchInfo(referrer) { | ||
var search = info.searchEngine(referrer); | ||
var param = search != 'yahoo' ? 'q' : 'p'; | ||
var ret = {}; | ||
if (search !== null) { | ||
ret['$search_engine'] = search; | ||
var keyword = getQueryParam(referrer, param); | ||
if (keyword.length) { | ||
ret['ph_keyword'] = keyword; | ||
} | ||
} | ||
return ret; | ||
}, | ||
browser: function browser(user_agent, vendor, opera) { | ||
vendor = vendor || ''; | ||
if (opera || includes(user_agent, ' OPR/')) { | ||
if (includes(user_agent, 'Mini')) { | ||
return 'Opera Mini'; | ||
} | ||
return 'Opera'; | ||
} else if (/(BlackBerry|PlayBook|BB10)/i.test(user_agent)) { | ||
return 'BlackBerry'; | ||
} else if (includes(user_agent, 'IEMobile') || includes(user_agent, 'WPDesktop')) { | ||
return 'Internet Explorer Mobile'; | ||
} else if (includes(user_agent, 'SamsungBrowser/')) { | ||
return 'Samsung Internet'; | ||
} else if (includes(user_agent, 'Edge') || includes(user_agent, 'Edg/')) { | ||
return 'Microsoft Edge'; | ||
} else if (includes(user_agent, 'FBIOS')) { | ||
return 'Facebook Mobile'; | ||
} else if (includes(user_agent, 'Chrome')) { | ||
return 'Chrome'; | ||
} else if (includes(user_agent, 'CriOS')) { | ||
return 'Chrome iOS'; | ||
} else if (includes(user_agent, 'UCWEB') || includes(user_agent, 'UCBrowser')) { | ||
return 'UC Browser'; | ||
} else if (includes(user_agent, 'FxiOS')) { | ||
return 'Firefox iOS'; | ||
} else if (includes(vendor, 'Apple')) { | ||
if (includes(user_agent, 'Mobile')) { | ||
return 'Mobile Safari'; | ||
} | ||
return 'Safari'; | ||
} else if (includes(user_agent, 'Android')) { | ||
return 'Android Mobile'; | ||
} else if (includes(user_agent, 'Konqueror')) { | ||
return 'Konqueror'; | ||
} else if (includes(user_agent, 'Firefox')) { | ||
return 'Firefox'; | ||
} else if (includes(user_agent, 'MSIE') || includes(user_agent, 'Trident/')) { | ||
return 'Internet Explorer'; | ||
} else if (includes(user_agent, 'Gecko')) { | ||
return 'Mozilla'; | ||
} else { | ||
return ''; | ||
} | ||
}, | ||
browserVersion: function browserVersion(userAgent, vendor, opera) { | ||
var browser = info.browser(userAgent, vendor, opera); | ||
var versionRegexs = { | ||
'Internet Explorer Mobile': /rv:(\d+(\.\d+)?)/, | ||
'Microsoft Edge': /Edge?\/(\d+(\.\d+)?)/, | ||
Chrome: /Chrome\/(\d+(\.\d+)?)/, | ||
'Chrome iOS': /CriOS\/(\d+(\.\d+)?)/, | ||
'UC Browser': /(UCBrowser|UCWEB)\/(\d+(\.\d+)?)/, | ||
Safari: /Version\/(\d+(\.\d+)?)/, | ||
'Mobile Safari': /Version\/(\d+(\.\d+)?)/, | ||
Opera: /(Opera|OPR)\/(\d+(\.\d+)?)/, | ||
Firefox: /Firefox\/(\d+(\.\d+)?)/, | ||
'Firefox iOS': /FxiOS\/(\d+(\.\d+)?)/, | ||
Konqueror: /Konqueror:(\d+(\.\d+)?)/, | ||
BlackBerry: /BlackBerry (\d+(\.\d+)?)/, | ||
'Android Mobile': /android\s(\d+(\.\d+)?)/, | ||
'Samsung Internet': /SamsungBrowser\/(\d+(\.\d+)?)/, | ||
'Internet Explorer': /(rv:|MSIE )(\d+(\.\d+)?)/, | ||
Mozilla: /rv:(\d+(\.\d+)?)/ | ||
}; | ||
var regex = versionRegexs[browser]; | ||
if (regex === undefined) { | ||
return null; | ||
} | ||
var matches = userAgent.match(regex); | ||
if (!matches) { | ||
return null; | ||
} | ||
return parseFloat(matches[matches.length - 2]); | ||
}, | ||
os: function os() { | ||
var a = userAgent; | ||
if (/Windows/i.test(a)) { | ||
if (/Phone/.test(a) || /WPDesktop/.test(a)) { | ||
return 'Windows Phone'; | ||
} | ||
return 'Windows'; | ||
} else if (/(iPhone|iPad|iPod)/.test(a)) { | ||
return 'iOS'; | ||
} else if (/Android/.test(a)) { | ||
return 'Android'; | ||
} else if (/(BlackBerry|PlayBook|BB10)/i.test(a)) { | ||
return 'BlackBerry'; | ||
} else if (/Mac/i.test(a)) { | ||
return 'Mac OS X'; | ||
} else if (/Linux/.test(a)) { | ||
return 'Linux'; | ||
} else if (/CrOS/.test(a)) { | ||
return 'Chrome OS'; | ||
} else { | ||
return ''; | ||
} | ||
}, | ||
device: function device(user_agent) { | ||
if (/Windows Phone/i.test(user_agent) || /WPDesktop/.test(user_agent)) { | ||
return 'Windows Phone'; | ||
} else if (/iPad/.test(user_agent)) { | ||
return 'iPad'; | ||
} else if (/iPod/.test(user_agent)) { | ||
return 'iPod Touch'; | ||
} else if (/iPhone/.test(user_agent)) { | ||
return 'iPhone'; | ||
} else if (/(BlackBerry|PlayBook|BB10)/i.test(user_agent)) { | ||
return 'BlackBerry'; | ||
} else if (/Android/.test(user_agent)) { | ||
return 'Android'; | ||
} else { | ||
return ''; | ||
} | ||
}, | ||
referringDomain: function referringDomain(referrer) { | ||
var split = referrer.split('/'); | ||
if (split.length >= 3) { | ||
return split[2]; | ||
} | ||
return ''; | ||
}, | ||
properties: function properties() { | ||
var _info$browserVersion; | ||
return extend(stripEmptyProperties({ | ||
os: info.os(), | ||
browser: info.browser(userAgent, navigator.vendor, windowOpera), | ||
referrer: document.referrer, | ||
referring_domain: info.referringDomain(document.referrer), | ||
device: info.device(userAgent) | ||
}), { | ||
current_url: win.location.href, | ||
host: win.location.host, | ||
pathname: win.location.pathname, | ||
browser_version: (_info$browserVersion = info.browserVersion(userAgent, navigator.vendor, windowOpera)) === null || _info$browserVersion === void 0 ? void 0 : _info$browserVersion.toString(), | ||
screen_height: screen.height, | ||
screen_width: screen.width, | ||
lib: 'web', | ||
insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10), | ||
time: timestamp() / 1000 | ||
}); | ||
} | ||
}; | ||
function getUserInfo() { | ||
return info.properties(); | ||
} | ||
var IFRAME_URL = 'https://chat-window.vercel.app'; | ||
@@ -405,5 +714,9 @@ | ||
var customerId = payload.customerId; | ||
var customerBrowserInfo = getUserInfo(); | ||
var metadata = _extends({}, customerBrowserInfo, customer); | ||
return send('customer:update', { | ||
customerId: customerId, | ||
metadata: customer | ||
metadata: metadata | ||
}); | ||
@@ -410,0 +723,0 @@ }; |
@@ -7,2 +7,20 @@ import React from 'react'; | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return _extends.apply(this, arguments); | ||
} | ||
var Path = function Path(props) { | ||
@@ -324,2 +342,293 @@ return React.createElement(motion.path, Object.assign({ | ||
var ArrayProto = Array.prototype; | ||
var ObjProto = Object.prototype; | ||
var toString = ObjProto.toString; | ||
var hasOwnProperty = ObjProto.hasOwnProperty; | ||
var win = window; | ||
var navigator = win.navigator; | ||
var windowOpera = win.opera; | ||
var userAgent = navigator.userAgent; | ||
var nativeForEach = ArrayProto.forEach; | ||
var breaker = {}; | ||
function isString(obj) { | ||
return toString.call(obj) == '[object String]'; | ||
} | ||
function includes(str, needle) { | ||
return str.indexOf(needle) !== -1; | ||
} | ||
function timestamp() { | ||
Date.now = Date.now || function () { | ||
return +new Date(); | ||
}; | ||
return Date.now(); | ||
} | ||
function each(obj, iterator, context) { | ||
if (obj === null || obj === undefined) { | ||
return; | ||
} | ||
if (nativeForEach && obj.forEach === nativeForEach) { | ||
obj.forEach(iterator, context); | ||
} else if (obj.length === +obj.length) { | ||
for (var i = 0, l = obj.length; i < l; i++) { | ||
if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) { | ||
return; | ||
} | ||
} | ||
} else { | ||
for (var key in obj) { | ||
if (hasOwnProperty.call(obj, key)) { | ||
if (iterator.call(context, obj[key], key, obj) === breaker) { | ||
return; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
function extend(obj) { | ||
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
} | ||
each(args, function (source) { | ||
for (var prop in source) { | ||
if (source[prop] !== void 0) { | ||
obj[prop] = source[prop]; | ||
} | ||
} | ||
}); | ||
return obj; | ||
} | ||
function stripEmptyProperties(obj) { | ||
var ret = {}; | ||
each(obj, function (v, k) { | ||
if (isString(v) && v.length > 0) { | ||
ret[k] = v; | ||
} | ||
}); | ||
return ret; | ||
} | ||
function getQueryParam(url, param) { | ||
param = param.replace(/[[]/, '\\[').replace(/[\]]/, '\\]'); | ||
var regexS = '[\\?&]' + param + '=([^&#]*)'; | ||
var regex = new RegExp(regexS); | ||
var results = regex.exec(url); | ||
if (results === null || results && typeof results[1] !== 'string' && results[1].length) { | ||
return ''; | ||
} else { | ||
var result = results[1]; | ||
try { | ||
result = decodeURIComponent(result); | ||
} catch (err) { | ||
console.error('Skipping decoding for malformed query param: ' + result); | ||
} | ||
return result.replace(/\+/g, ' '); | ||
} | ||
} | ||
var info = { | ||
campaignParams: function campaignParams() { | ||
var campaign_keywords = 'utm_source utm_medium utm_campaign utm_content utm_term'.split(' '); | ||
var kw = ''; | ||
var params = {}; | ||
each(campaign_keywords, function (kwkey) { | ||
kw = getQueryParam(document.URL, kwkey); | ||
if (kw.length) { | ||
params[kwkey] = kw; | ||
} | ||
}); | ||
return params; | ||
}, | ||
searchEngine: function searchEngine(referrer) { | ||
if (referrer.search('https?://(.*)google.([^/?]*)') === 0) { | ||
return 'google'; | ||
} else if (referrer.search('https?://(.*)bing.com') === 0) { | ||
return 'bing'; | ||
} else if (referrer.search('https?://(.*)yahoo.com') === 0) { | ||
return 'yahoo'; | ||
} else if (referrer.search('https?://(.*)duckduckgo.com') === 0) { | ||
return 'duckduckgo'; | ||
} else { | ||
return null; | ||
} | ||
}, | ||
searchInfo: function searchInfo(referrer) { | ||
var search = info.searchEngine(referrer); | ||
var param = search != 'yahoo' ? 'q' : 'p'; | ||
var ret = {}; | ||
if (search !== null) { | ||
ret['$search_engine'] = search; | ||
var keyword = getQueryParam(referrer, param); | ||
if (keyword.length) { | ||
ret['ph_keyword'] = keyword; | ||
} | ||
} | ||
return ret; | ||
}, | ||
browser: function browser(user_agent, vendor, opera) { | ||
vendor = vendor || ''; | ||
if (opera || includes(user_agent, ' OPR/')) { | ||
if (includes(user_agent, 'Mini')) { | ||
return 'Opera Mini'; | ||
} | ||
return 'Opera'; | ||
} else if (/(BlackBerry|PlayBook|BB10)/i.test(user_agent)) { | ||
return 'BlackBerry'; | ||
} else if (includes(user_agent, 'IEMobile') || includes(user_agent, 'WPDesktop')) { | ||
return 'Internet Explorer Mobile'; | ||
} else if (includes(user_agent, 'SamsungBrowser/')) { | ||
return 'Samsung Internet'; | ||
} else if (includes(user_agent, 'Edge') || includes(user_agent, 'Edg/')) { | ||
return 'Microsoft Edge'; | ||
} else if (includes(user_agent, 'FBIOS')) { | ||
return 'Facebook Mobile'; | ||
} else if (includes(user_agent, 'Chrome')) { | ||
return 'Chrome'; | ||
} else if (includes(user_agent, 'CriOS')) { | ||
return 'Chrome iOS'; | ||
} else if (includes(user_agent, 'UCWEB') || includes(user_agent, 'UCBrowser')) { | ||
return 'UC Browser'; | ||
} else if (includes(user_agent, 'FxiOS')) { | ||
return 'Firefox iOS'; | ||
} else if (includes(vendor, 'Apple')) { | ||
if (includes(user_agent, 'Mobile')) { | ||
return 'Mobile Safari'; | ||
} | ||
return 'Safari'; | ||
} else if (includes(user_agent, 'Android')) { | ||
return 'Android Mobile'; | ||
} else if (includes(user_agent, 'Konqueror')) { | ||
return 'Konqueror'; | ||
} else if (includes(user_agent, 'Firefox')) { | ||
return 'Firefox'; | ||
} else if (includes(user_agent, 'MSIE') || includes(user_agent, 'Trident/')) { | ||
return 'Internet Explorer'; | ||
} else if (includes(user_agent, 'Gecko')) { | ||
return 'Mozilla'; | ||
} else { | ||
return ''; | ||
} | ||
}, | ||
browserVersion: function browserVersion(userAgent, vendor, opera) { | ||
var browser = info.browser(userAgent, vendor, opera); | ||
var versionRegexs = { | ||
'Internet Explorer Mobile': /rv:(\d+(\.\d+)?)/, | ||
'Microsoft Edge': /Edge?\/(\d+(\.\d+)?)/, | ||
Chrome: /Chrome\/(\d+(\.\d+)?)/, | ||
'Chrome iOS': /CriOS\/(\d+(\.\d+)?)/, | ||
'UC Browser': /(UCBrowser|UCWEB)\/(\d+(\.\d+)?)/, | ||
Safari: /Version\/(\d+(\.\d+)?)/, | ||
'Mobile Safari': /Version\/(\d+(\.\d+)?)/, | ||
Opera: /(Opera|OPR)\/(\d+(\.\d+)?)/, | ||
Firefox: /Firefox\/(\d+(\.\d+)?)/, | ||
'Firefox iOS': /FxiOS\/(\d+(\.\d+)?)/, | ||
Konqueror: /Konqueror:(\d+(\.\d+)?)/, | ||
BlackBerry: /BlackBerry (\d+(\.\d+)?)/, | ||
'Android Mobile': /android\s(\d+(\.\d+)?)/, | ||
'Samsung Internet': /SamsungBrowser\/(\d+(\.\d+)?)/, | ||
'Internet Explorer': /(rv:|MSIE )(\d+(\.\d+)?)/, | ||
Mozilla: /rv:(\d+(\.\d+)?)/ | ||
}; | ||
var regex = versionRegexs[browser]; | ||
if (regex === undefined) { | ||
return null; | ||
} | ||
var matches = userAgent.match(regex); | ||
if (!matches) { | ||
return null; | ||
} | ||
return parseFloat(matches[matches.length - 2]); | ||
}, | ||
os: function os() { | ||
var a = userAgent; | ||
if (/Windows/i.test(a)) { | ||
if (/Phone/.test(a) || /WPDesktop/.test(a)) { | ||
return 'Windows Phone'; | ||
} | ||
return 'Windows'; | ||
} else if (/(iPhone|iPad|iPod)/.test(a)) { | ||
return 'iOS'; | ||
} else if (/Android/.test(a)) { | ||
return 'Android'; | ||
} else if (/(BlackBerry|PlayBook|BB10)/i.test(a)) { | ||
return 'BlackBerry'; | ||
} else if (/Mac/i.test(a)) { | ||
return 'Mac OS X'; | ||
} else if (/Linux/.test(a)) { | ||
return 'Linux'; | ||
} else if (/CrOS/.test(a)) { | ||
return 'Chrome OS'; | ||
} else { | ||
return ''; | ||
} | ||
}, | ||
device: function device(user_agent) { | ||
if (/Windows Phone/i.test(user_agent) || /WPDesktop/.test(user_agent)) { | ||
return 'Windows Phone'; | ||
} else if (/iPad/.test(user_agent)) { | ||
return 'iPad'; | ||
} else if (/iPod/.test(user_agent)) { | ||
return 'iPod Touch'; | ||
} else if (/iPhone/.test(user_agent)) { | ||
return 'iPhone'; | ||
} else if (/(BlackBerry|PlayBook|BB10)/i.test(user_agent)) { | ||
return 'BlackBerry'; | ||
} else if (/Android/.test(user_agent)) { | ||
return 'Android'; | ||
} else { | ||
return ''; | ||
} | ||
}, | ||
referringDomain: function referringDomain(referrer) { | ||
var split = referrer.split('/'); | ||
if (split.length >= 3) { | ||
return split[2]; | ||
} | ||
return ''; | ||
}, | ||
properties: function properties() { | ||
var _info$browserVersion; | ||
return extend(stripEmptyProperties({ | ||
os: info.os(), | ||
browser: info.browser(userAgent, navigator.vendor, windowOpera), | ||
referrer: document.referrer, | ||
referring_domain: info.referringDomain(document.referrer), | ||
device: info.device(userAgent) | ||
}), { | ||
current_url: win.location.href, | ||
host: win.location.host, | ||
pathname: win.location.pathname, | ||
browser_version: (_info$browserVersion = info.browserVersion(userAgent, navigator.vendor, windowOpera)) === null || _info$browserVersion === void 0 ? void 0 : _info$browserVersion.toString(), | ||
screen_height: screen.height, | ||
screen_width: screen.width, | ||
lib: 'web', | ||
insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10), | ||
time: timestamp() / 1000 | ||
}); | ||
} | ||
}; | ||
function getUserInfo() { | ||
return info.properties(); | ||
} | ||
var IFRAME_URL = 'https://chat-window.vercel.app'; | ||
@@ -403,5 +712,9 @@ | ||
var customerId = payload.customerId; | ||
var customerBrowserInfo = getUserInfo(); | ||
var metadata = _extends({}, customerBrowserInfo, customer); | ||
return send('customer:update', { | ||
customerId: customerId, | ||
metadata: customer | ||
metadata: metadata | ||
}); | ||
@@ -408,0 +721,0 @@ }; |
{ | ||
"name": "@papercups-io/chat-widget", | ||
"version": "1.0.16", | ||
"version": "1.0.17-beta.0", | ||
"description": "Papercups chat widget", | ||
@@ -5,0 +5,0 @@ "author": "reichert621", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
204574
29
2642
2