// store code in the URL window.common = (function(global) { const { encodeURIComponent: encode, decodeURIComponent: decode, location, history, common = { init: [] } } = global; const { replaceScriptTags, replaceSafeTags, replaceFormActionAttr, replaceFccfaaAttr, replaceNoprotect } = common; const queryRegex = /^(\?|#\?)/; function encodeFcc(val) { return replaceScriptTags(replaceFormActionAttr(replaceNoprotect(val))); } function decodeFcc(val) { return replaceSafeTags(replaceFccfaaAttr(val)); } var codeUri = { encode: function(code) { return encode(code); }, decode: function(code) { try { return decode(code); } catch (ignore) { return null; } }, isInQuery: function(query) { var decoded = codeUri.decode(query); if (!decoded || typeof decoded.split !== 'function') { return false; } return decoded .replace(queryRegex, '') .split('&') .reduce(function(found, param) { var key = param.split('=')[0]; if (key === 'solution') { return true; } return found; }, false); }, isAlive: function() { return codeUri.enabled && codeUri.isInQuery(location.search) || codeUri.isInQuery(location.hash); }, getKeyInQuery(query, keyToFind = '') { return query .split('&') .reduce(function(oldValue, param) { var key = param.split('=')[0]; var value = param .split('=') .slice(1) .join('='); if (key === keyToFind) { return value; } return oldValue; }, null); }, getSolutionFromQuery(query = '') { return decodeFcc( codeUri.decode(codeUri.getKeyInQuery(query, 'solution')) ); }, parse: function() { if (!codeUri.enabled) { return null; } var query; if (location.search && codeUri.isInQuery(location.search)) { query = location.search.replace(/^\?/, ''); if (history && typeof history.replaceState === 'function') { history.replaceState( history.state, null, location.href.split('?')[0] ); location.hash = '#?' + encodeFcc(query); } } else { query = location.hash.replace(/^\#\?/, ''); } if (!query) { return null; } return this.getSolutionFromQuery(query); }, querify: function(solution) { if (!codeUri.enabled) { return null; } if (history && typeof history.replaceState === 'function') { // grab the url up to the query // destroy any hash symbols still clinging to life const url = (location.href.split('?')[0]).replace(/(#*)$/, ''); history.replaceState( history.state, null, url + '#?' + (codeUri.shouldRun() ? '' : 'run=disabled&') + 'solution=' + codeUri.encode(encodeFcc(solution)) ); } else { location.hash = '?solution=' + codeUri.encode(encodeFcc(solution)); } return solution; }, enabled: true, shouldRun() { return !this.getKeyInQuery( (location.search || location.hash).replace(queryRegex, ''), 'run' ); } }; common.init.push(function() { codeUri.parse(); }); common.codeUri = codeUri; common.shouldRun = () => codeUri.shouldRun(); return common; }(window));