regstr
Version:
JSON.stringify objects with RegExp properties and then JSON.parse json string resulted back into original objects. Converts RegExp object to be serializable - into pair of strings (key,value). Could be used for RegExp being bilaterally stringified and ge
706 lines (693 loc) • 31.9 kB
JavaScript
/**
* @fileoverview Description of regStr module usage details and
* algorithm.
* @author vladimir@uralov.com (Vladimir Uralov)
*/
(function () {
var o, v;
console.log('\n' + // ciphering_explain
' Package <regStr>\n' +
' (serialization of objects and arrays containing regular expression objects.\n' +
' JSON.stringify - JSON.parse - compatible)\n' +
'\n' +
' Converts single RegExp object or some object with RegExp properties\n' +
' to the form adequate to stringify and back parse them using JSON\n' +
' by means of JSON.stringify and then JSON.parse back.)\n' +
'\n' +
' ----- Ciphering or conversion ------\n' +
'\n' +
' The main concept is to cipher RegExp object into \'cipher\' pair of strings\n' +
' or cipher object - single property object, easily stringifiable,\n' +
' and automatically recognizable after back parsing to get "initial"\n' +
' object contained RegExp-s.\n' +
' The easiest way to get acquaintance with module is to look at examples:\n' +
'\n' +
' Loading handler from working directory ( using variable - h presumes\n' +
' that module is a handler. Identifier regstr or any yourVar would be OK\n' +
' as well):\n\n' +
' var h=require(\'./regstr\').regStr;\n');
regstr = require('../regstr').regStr;
console.log('' +
'\n' +
' ciphering is provided by method h.streger() , like this:\n' +
'\n' +
' var v=/asdf/gi;\n'
);
v = /asdf/gi;
console.log(v);
console.log('' +
'\n' +
' h.streger( v ) or h.streger(/asdf/gi)\n' +
' gives\n'
);
console.log(regstr.streger(v));
console.log('' +
'\n or an object\n\n' +
' var o={a:/asdf/gim};\n' +
'\n' +
' h.streger(o) or h.streger( {a:/asdf/gim} )\n\n' +
' gives\n');
o = {
a: /asdf/gim
};
console.log(regstr.streger(o));
console.log('' +
'\n or an object inside an array\n\n' +
' h.streger( [ {a:/asdf/gi},/^[+]+cc.*$/gim ] );\n' +
'\n' +
' returns\n'
);
console.log(
regstr.streger([{
a: /asdf/gi
}, /^[+]+cc.*$/gim])
);
console.log('' +
'\n' +
'or array with RegExp objects elements \n\n' +
' h.streger( [\n' +
' /asdf/gi,\n' +
' /^[+]+cc.*$/gim,\n' +
' /sdf/\n' +
' ]\n' +
' );\n' +
'\n');
console.log(
regstr.streger([
/asdf/gi,
/^[+]+cc.*$/gim,
/sdf/
]));
console.log('' +
'or object with RegExp objects properties \n\n' +
' h.streger(\n' +
' { a: /asdf/gi,\n' +
' b: /^[+]+cc.*$/gim,\n' +
' ab:[{ bb:/sdfg/mg},/sdf/]\n' +
' }\n' +
' );\n' +
'\n');
console.log(
regstr.streger({
a: /asdf/gi,
b: /^[+]+cc.*$/gim,
ab: [{
bb: /sdfg/mg
}, /sdf/]
}));
console.log('' +
' all these results are easily stringified and back parsed by\n' +
' JSON.stringify and JSON.parse\n\n' +
' Applying h.reger() method after parsing will bring RegEpx:\n' +
' keeping in mind the process flow\n\n' +
' ciphering deciphering\n' +
' RegExp > h.streger > cipherObject > h.reger > RegExp\n' +
'\n' +
' h.reger( h.streger({ a: /asdf/gi,\n' +
' b: /^[+]+cc.*$/gim,\n' +
' ab:[{ bb:/sdfg/mg},/sdf/] } )\n' +
' );\n' +
' gives:\n'
);
console.log(
regstr.reger(regstr.streger({
a: /asdf/gi,
b: /^[+]+cc.*$/gim,
ab: [{
bb: /sdfg/mg
}, /sdf/]
})));
console.log('' +
' You already could have observed the letters \'RE\' and few (two)' +
' digits after\n' +
' it in strings representing keys and values ciphered. This is a mark\n' +
' using in ciphering and identification ciphered regExp later. Digits are\n' +
' random and their number could be changed by property h.nMin. For example\n' +
' let\'s set it to 5.\n' +
' h.nMin=5;\n\n' +
' and the lay out of key and value strings will have changed. For ex.:\n' +
' h.streger( { a: /asdf/gi,\n' +
' b: /^[+]+cc.*$/gim,\n' +
' ab:[{ bb:/sdfg/mg},/sdf/],\n' +
' c:{re:/nnn.+$/gim,ar:[/aaa/,/bbb/g]} \n' +
' }\n' +
' );\n' +
' returns: \n');
regstr.nMin = 5;
console.log(
regstr.streger({
a: /asdf/gi,
b: /^[+]+cc.*$/gim,
ab: [{
bb: /sdfg/mg
}, /sdf/],
c: {
re: /nnn.+$/gim,
ar: [/aaa/, /bbb/g]
}
}));
regstr.nMin = 2;
console.log('\n' +
' The explanation regarding REn follows bellow. Here we just mention\n' +
' that during deciphering different key-value pairs ciphering different\n' +
' regexp-s could have different number of that random digits after \'RE\'' +
'\n\n' +
' like this: \n\n' +
' var b=[ { aRE28: \'asdfRE28gi\' },' +
' { \'1RE62555\': \'^[+]+cc.*$RE62555gmi\' } ]\n\n' +
' h.reger( b); will return \n');
var b = [{
aRE28: 'asdfRE28gi'
}, {
"1RE62555": "^[+]+cc.*$RE62555gmi"
}];
console.log(regstr.reger(b));
console.log('' +
'\n' +
' Handler h (regstr) has h.replacer and h.reviver \n' +
' methods that could be used to serialize and parse back objects and \n' +
' arrays with RegExp-s without\n' +
' direct intermediary of h.streger(...) and h.reger(...).\n' +
' functions could be used \n' +
' var replacer = h.replacer.bind(h);\n' +
' var reviver = h.reviver.bind(h);\n' +
' and\n' +
' o -> o1 = JSON.stringify(o,replacer) ->\n' +
' o = JSON.parse(o1,reviver)\n' +
' compare o \n');
o = [{
a: /asdf/gi
}, /^[+]+cc.*$/gim];
console.log(o);
console.log('\n' +
'with\n' +
'\n' +
' o=JSON.parse ( JSON.stringify(o,h.replacer.bind(h)), h.reviver.bind(h))\n' +
' or\n' +
' o=JSON.parse ( JSON.stringify(o,replacer), reviver)\n' +
'\n');
var replacer = regstr.replacer.bind(regstr);
var reviver = regstr.reviver.bind(regstr);
console.log(JSON.parse(JSON.stringify(o, replacer), reviver));
console.log('\n' +
'and with\n' +
' h.reger( h.streger([{a:/asdf/gi},/^[+]+cc.*$/gim]) );\n' +
'\n');
console.log(regstr.reger(regstr.streger([{
a: /asdf/gi
}, /^[+]+cc.*$/gim])));
console.log('\n' +
'\n' +
' Explanation:\n' +
' Let\'s pO is some parent object with a property described by\n' +
' (key,value) pair, where\n' +
'\n' +
' value=pO[key]; // and value is regular expression object\n' +
' (value instanceof RegExp===true)?true:false; // is true and\n' +
'\n' +
' value=new RegExp(body,mig); // where body and mig are strings\n' +
'\n' +
' {string}body - is string of regular expression and\n' +
' {string}mig - RegExp flags - ( multi-line, insensitive, global)\n' +
'\n' +
' Conversion algorithm fitures:\n' +
' 1. Additional property key1 is added to object pO -\n' +
'\n' +
' pO[key1]=value1;\n' +
' key1=key+RE; // value=new RegExp(body,mig) are converted into string\n' +
' value1=body+RE+mig; // where\n' +
' RE=\'RE\'+rndm10;\n' +
'\n' +
' and {string}rndm10 is random string consisted of 10 random digits\n' +
' from 0-9 in each place, for ex.\n' +
' rndm10=\'0987654321\'; // \n' +
'\n' +
' The number of random digit depends and could be any of your choice\n' +
' rndm4, ..rndm2 ...\n' +
' Obviously pO[key1] is serializable by JSON.\n' +
' 2. Or\n' +
' delete pO[key];\n' +
' or if you would not have done it yourself the JSON.stringify will do\n' +
' during serialization\n' +
'\n' +
' Inclusion of RE string into key1 and value1 is used as a mark\n' +
' marking the property and permits to identify it during reverse\n' +
' parse procedure and to transform\n' +
' value1 string body+RE+mig into new RegExp(body,mig) :\n' +
' Back Parsing features:\n' +
' After JSON.parse( regExpJsoned )\n' +
' 1. Selects object string property containing in key and value\n' +
' marking string RE===\'RE\'+rndmN ,\n' +
' where N is number of digital positions in random rndmN N-digital string.\n' +
' RE populates the ending positions of key( property name string) and\n' +
' separates body-part from mig-part in property string value===body+RE+mig, so\n' +
'\n' +
' var vs=pO[oid+RE].split(RE); // (5)\n' +
' var newRegExpValue= new RegExp( vs[0],vs[1]); // (6)\n' +
'\n' +
' when you would be needed to get RE you should look for a property\n' +
' with string value, in (key,value) pair :\n' +
' and\n' +
' 1. property name and property string value contain the same pattern RE\n' +
' 2. the property name has it located at the end of string\n' +
' 3. the value string consists of three parts: body,RE and mig\n' +
' splitting the valueString by RE pattern body and mig -parts could be got\n' +
' and therefor RegExp value be invoked\n' +
'\n' +
' Package Usage for pO object:\n' +
'\n' +
' var regstr=require(\'regstr).regStr; // handler object\n' +
'\n' +
' variant A.\n' +
' RegExp property conversions into string:\n' +
' For each property being RegExp new converted string property\n' +
' is created. Original ones keep safe.( are not deleted from object\n' +
' if it\'s necessary do it yourself or use optional parameter opt_ciphMode\n' +
' to manage this option)\n' +
'\n' +
' pO=regstr.streger(pO); // Remark: changes of pO properties are accessible\n' +
' // for external scope of stregger. Possible call is\n' +
' // regstr.streger(pO);\n' +
'\n' +
' variant B.\n' +
' per single RegExp property transformation\n' +
'\n' +
' var o;\n' +
' // preJson step\n' +
' for(var k in pO){\n' +
' if( pO[k] instanceof RegExp){\n' +
' o=regstr.reStr(pO[k],k);\n' +
' // creates new property with new key and value {string}\n' +
' pO[o.ky]=o.v;\n' +
' }\n' +
' }\n' +
' // json.stringify\n' +
' var jsonPo=JSON.stringify(pO)\n' +
'\n' +
' // parse Back\n' +
'\n' +
' detailed explanation see in deciphering_explain.txt of deciphering_explain.js-object\n' +
' in docs directory.\n' +
' to get it in console type: npm run explain\n' +
' or inside node by require(\'./docs.deciphering_explain.js\'); command\n' +
'\n' +
' var oP=JSON.parse(jsonPo);\n' +
'\n' +
' postParse properties\' conversion into RegExp-s if any\n' +
' variant 1.\n' +
' All chyphered propertiesif are available are selected\n' +
' and are converted to RegExp with new keys (by excluding RE from key):\n' +
'\n' +
' oP=regstr.reger(oP);\n' +
'\n' +
' // or Variant 2\n' +
' // if \'property by property\' handling is necessary\n' +
' var ob;\n' +
' for( var ip in oP){\n' +
' if( typeof oP[ip]===\'string\'){\n' +
' ob=regstr.regUp(oP[ip]);\n' +
' if(ob.key!==ip){\n' +
' // new RegExp property of oP\n' +
' ob[ob.key]=ob.value;\n' +
' delete oP[ip];\n' +
' }\n' +
' }\n' +
' }\n' +
' Remark 1.\n' +
' RegExp object variable itself could be converted into\n' +
' object with one property {RE:regString}\n' +
' var regE=someRegExp; // someRegExp=new RegExp(body,mig);\n' +
' var oStrReg=regstr.reStr(regE);\n' +
' // var o=oStrReg.o(); where o={ RE: regString } where\n' +
' // RE=\'RE\'+rndmN , regString = body+RE+mig,\n' +
' // at the same time RE=oStrReg.re;\n' +
' // regString=oStrReg.c;\n' +
' // body=oStrReg.b;\n' +
' // mig=oStrReg.mig\n' +
' //\n' +
' Remark 2.\n' +
' uncycle package extension. (miss it now, go further up to Decipher\n' +
' method concept...)\n' +
'\n' +
' This RegExp handling algorithm could be included in preStringify methods\n' +
' of <uncycle> package -targeting to stringify objects with circular references\n' +
' to provide extending functionality, or when json is used for cloning objects.\n' +
' to switch it on set\n' +
' unCycle.uiDirect.regOn=true;\n' +
'\n' +
' .................................\n\n' +
' Following comments are based on notion of uncycle package.\n' +
' suppose some ith-property with (oid,uid,value) being RegExp\n' +
' oid=\'oid\'; // property\'s object id or key\n' +
' uid=\'##x#x#...#oid\'; // appropriate universal identifier of this property\n' +
'\n' +
' If pO is this property\'s parent object,\n' +
' property\'s value is RegExp object\n' +
'\n' +
' pO[oid]=new RegExp(body,mig); // (1) {RegExp}\n' +
' unCycle.uiDirect[uid]=new RegExp(body,mig); // (2) {RegExp}\n' +
'\n' +
' to create new property for parent object with string value:\n' +
' pO[oid+RE]=body+RE+mig; // (3) {string}\n' +
' where RE=\'RE\'+rndm10\n' +
' and\n' +
' rndm10=\'0987654321\'; // -random string of 10 digits from 0-9 in each place\n' +
' The number of random digit depends and could be any of your choise\n' +
' rndm4, ..rendm2 ...\n' +
'\n' +
'\n' +
' 2. delete pO[oid]; // if you would no have done it yourself\n' +
' // JSON.stringify will not do it but only\n' +
' // would set empty appropriate object\n' +
' 3. appropriately, the uid of this new property will be\n' +
' uidNewPr=uid+RE; // {string} and uiDirect object will contain property\n' +
' unCycle.uiDirect[uid+RE]=body+RE+mig; // (4) {string}\n' +
'\n' +
' Inclusion of RE string into oid and string value of newly created property\n' +
' simplifies it\'s identification and following transformation of\n' +
' body+RE+mig string into new RegExp(body,mig) :\n' +
'\n' +
' var vs=pO[oid+RE].split(RE); // (5)\n' +
' var newRegExpValue= new RegExp( vs[0],vs[1]); // (6)\n' +
'\n' +
' when you would be need to get RE you should look for a property\n' +
' with string value, i.e. for (key,value) :\n' +
'\n' +
' (typeof value === \'string\') && three remarkable points:\n' +
' 1. For newly created property - property name and\n' +
' property string ciphered value contain the same pattern RE\n' +
' 2. the property name has it at the end of string\n' +
' 3. the value\'s body and mig string could be obtained splitting the\n' +
' valueString by RE pattern\n' +
' ...........................................\n' +
'\n\n' +
'\n' +
'\n' +
' ---- Decipher mehod concept and notions : -----\n' +
'\n' +
'Definitions and notions used below:\n' +
'\n' +
'parent object pO. Object or array having subobject(s) ciphered\n' +
'\n' +
' pO={..., o:{},...} or\n' +
' pO=[..., o, ...]\n' +
'\n' +
'object - entity containing cipher (cipher pair or cipher object)\n' +
'\n' +
'pO & o subordination keeps after deciphering\n' +
'\n' +
'Deciphering converts\n' +
'\n' +
'cipher pair (keyRe,v1ReV2) or cipher object {keyRe:v1ReV2}\n' +
'\n' +
'into RegExp objects integrated in appropriate structure\n' +
'(variable, object(or array), parent object (or array)\n' +
'\n' +
'cipher separator string RE\n' +
'\n' +
' RE="RE"+rndmN (1)\n' +
'\n' +
'rndmN - random part; string consisting only of N random digits (0-9)\n' +
'\n' +
'keyRe - key-cipher string composed of string key and string RE\n' +
'\n' +
' keyRe=key+RE (2)\n' +
'\n' +
'v1ReV2 - RegExp value ciphering string. Three parts string:\n' +
' v1ReV2=v1+RE+v2, (3)\n' +
'where RE string is used as separator\n' +
'to select v1 and v2 strings (body string and modifier strig) determining\n' +
'regular expression object by following way -\n' +
'\n' +
' rE= new RegExp(body,modifier) or\n' +
' rE= new RegExp(v1,v2) (4)\n' +
'\n' +
'keyRe string and RE separator string are used for ciphering Regular expression\n' +
'being property of object or element of array object\n' +
'\n' +
'object property case:\n' +
' o={key:RegExp} is ciphered as o={keyRe:v1Rev2} (5.1)\n' +
'or in opposite direction\n' +
' o={keyRe:v1Rev2} is deciphered in o={key:RegExp} (5)\n' +
'\n' +
' o={...,keyRe:v1ReV2,..} -> ={...,key:new RegExp(v1,v2)}, ...} (6)\n' +
'\n' +
'For ciphering naked regular expression as value of variable or array\'s element\n' +
'cipher object is used with key="". That is cipher pair is (RE,v1+RE+v2) or\n' +
'cipher object {RE:v1ReV2}={"\'RE\'+rndmN":v1+\'RE\'+rndmN+v2}\n' +
'\n' +
'RE is used instead of keyRE in key string part.\n' +
'\n' +
'So for array\n' +
'\n' +
' a=[...,{RE:v1ReV2},...] is deciphered into a=[...,rE,...], (7)\n' +
'\n' +
' where rE=new RegExp(v1,v2) (8)\n' +
'\n' +
'variable\n' +
'\n' +
' v={RE:v1ReV2} is deciphered into v=rE (9)\n' +
'\n' +
'subproperty o\n' +
'\n' +
' pO={...,o:{RE:v1ReV2},...} is converted in pO={...,o:rE,...} (10)\n' +
'\n' +
'at the same time if key is used\n' +
'\n' +
' pO={...,o:{keyRe:v1ReV2},...} is converted in pO={...,o:{key:rE},...} (11)\n' +
'\n' +
'for array element as an object:\n' +
'\n' +
' pO=[...,{keyRe:v1ReV2},...] -> pO=[...,{key:rE},...] (12)\n' +
'\n' +
'in the case of arrays key could have digital form key=n - interger, what in this case\n' +
'would mean index number of deciphered result.\n' +
'For example if we have cipher {nRE:v1ReV2} as element with index ind of array pO\n' +
'\n' +
' ind <-index of cipher\n' +
' pO=[...,...,{nRe:v1ReV2},...] is converted into pO=[...,rE,...,...] (13)\n' +
' index of rE element -> n\n' +
'\n' +
'cipher Objects are removed from resulting deciphered objects or arrays.\n' +
'\n' +
'Remark 1.\n' +
'nRE form of key-code used for ciphering objects is deciphered in \'n\' key letter string\n' +
'expressing digit(s) for ex. o={...,"23RE123":v1+\'RE123\'+v2},...} will be deciphered in\n' +
' o={...,"23":new RegExp(v1,v2),...}\n' +
'\n' +
'Remark 2.\n' +
'RE form of keyRe could be used for ciphering of object property only if object has\n' +
'single property, i.e.\n' +
'\n' +
' o={"RE12":v1+"RE12"+v2} (14)\n' +
'\n' +
'is pemissible and is converted into o=new RegExp(v1,v2) (14.1)\n' +
' but\n' +
' o={a:\'a\',...,"RE12":v1+"RE12"+v2, ...} is prohibited (15)\n' +
'\n' +
' and will throw Error!\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'The table below uses some abbreviations for shortness.\n' +
'\n' +
'abbreviations:\n' +
'k - key\n' +
'R - RE\n' +
'vRv2 - v1REv2\n' +
'pO - parent object\n' +
'rE - new RegExp(v1,v2)\n' +
'o - object containing cipher -\n' +
' or cipher pair (key,value) as object property with string value\n' +
' {...,kR:vRv2,..}\n' +
' or cipher object with single property {kR:vRv2}\n' +
'v - variable\n' +
'a - array\n' +
'\n' +
'\n' +
'different keys nomination:\n' +
'\n' +
'kR - keyRE - key ciphered = key+"RE"+rndmN\n' +
'nR - nRe - the same as kR but key part consists of digits only\n' +
'R - RE - when key part ="" or undefined\n' +
'\n' +
'Table. Algorithm explanation. Ciphered entities and their decipherings:\n' +
'\n' +
'entity | ciphered | deciphering |equation| comments \n' +
' | and actions\n' +
'variable:\n' +
' v={R:vRv2} | v=rE (T1) (rE= new RegExp(v,v2); )\n' +
'object:\n' +
' o={kR:vRv2} | o={k:rE}; (T2)\n' +
' | 1. delete o[kR]\n' +
' | 2. o[k]=rE before assignment checks if o already has\n' +
' | property k as instance of RegExp equivalent\n' +
' | to rE (see equation (3) item 2. ). If this is\n' +
' | the case nothing new is inserted.\n' +
' |\n' +
' o={...,kR:vRv2, ... } | o={..., k:rE, ...}; (T3)\n' +
' | 1. delete o[kR];\n' +
' | 2.\n' +
' | if(!o.hasOwnPrperty(k)||\n' +
' | o[k] instanceof RegExp!==true\n' +
' | || o[k]!==rE){ // (*)!! new RegExp(a,b)!== new RegExp(a,b)\n' +
' | o[k]=rE; // (o[k].source !== rE.source ||\n' +
' | } // regstr.migV(o[k])!==regstr.migV(rE));\n' +
' |\n' +
' o={...,nR:vRv2, ... } | o={...,"n":rE, ...}; (T4) property name consists of digits only\n' +
' | 1. delete o[nR];\n' +
' | 2. o["n"]=rE; !! peculiarities similar to (3) 2. !!\n' +
' |\n' +
' o={..., R:vRv2, ... } | !! PROHIBITED !! (X) only variable form (1) is possible\n' +
' | or for object containing ciphered pair\n' +
' | (Object.keys(o).length===1)===true\n' +
'or | like in the case when o is\n' +
'subObject of pO |\n' +
' | (Object.keys(o).length==1) ===true\n' +
' pO={...,o:{R:vRv2},...} | pO={ ... ,o:rE, ... } (T5) which is similar to case (T1)\n' +
' |\n' +
'Array is pO(parent |\n' +
' object): |\n' +
' ind | ind element of pO with index ind\n' +
' pO=[... ,{kR:vRv2},...] | pO=[...,{k:rE}, ... ] (T6)\n' +
' | 1. pO[ind]={k:rE};\n' +
' ind | index == ind\n' +
' pO=[... ,{nR:vRv2},...] | pO=[...,..,rE,...] (T7) new element of pO with index n\n' +
' | n index == n\n' +
' |\n' +
' | if((pO[n] instanceof RegExp)!==true) // has RegExp element with index n\n' +
' | ||( value equivalent to rE)!==true){\n' +
' | 1. pO.splice(n,0,rE);\n' +
' | }else{\n' +
' | then nothing is added and\n' +
' | 2. if(ind<n){\n' +
' | pO.splice(ind,1); // removes cipher element from array\n' +
' | }else{\n' +
' | pO.splice(ind+1,1);\n' +
' | }\n' +
' | }\n' +
' ind | ind\n' +
' pO=[... ,{R:vRv2},...] | pO=[... ,rE, ... ] (T8)\n' +
'\n' +
'\n');
/* Reconversion - deciphering scheme:
* Procedure verifies objects or arrays looking for "ciphered"
* properties or elements
* The Mark of \'cipher\' presence:
* - for Object\'s property:
* property name has form keyRE=key+RE,
* property value is string of the model: v1ReV2=v1+RE+v2,
* where key - is the name of RegExp property ciphered with
* value=new RegExp(v1,v2)
*
* "Ciphered" means that it is a "cipher-object" or "cipher"
* cipher={keyRE:vReV2} coded RegExp object property
* {...,key:new RegExp(v1,v2),...}
* or single property object={keyRE:vReV2}
*
* A.Ciphered properties of object;
* B.Element(s) of array "ciphered" in the form of single property object
* {keyRE:v1ReV2} or {nRe:v1Rev2} (see <Digital key practice> paragraph
* regarding nRe form of key;
* C.Variable being RegExp ciphered by means of cipher object without key, i.e.
* Cipher without key has format {RE:vReV2}, where RE=\'RE\'+rndmN,
* rndmN - string of N random digits\n. Deciphered RegExp will be:
* new RegExp(v1,v2);
*/
var decipheringScheme = '\n\n' +
' * ---- Reconversion - deciphering scheme: ---- *\n' +
' Procedure verifies objects or arrays looking for "ciphered"\n' +
' properties or elements\n' +
' The Mark of \'cipher\' presence:\n' +
' - for Object\'s property:\n' +
' property name has form keyRE=key+RE,\n' +
' property value is string of the model: v1ReV2=v1+RE+v2,\n' +
' where key - is the name of RegExp property ciphered with\n' +
' value=new RegExp(v1,v2)\n' +
'\n' +
' "Ciphered" means that it is a "cipher-object" or "cipher"\n' +
' cipher={keyRE:vReV2} coded RegExp object property\n' +
' {...,key:new RegExp(v1,v2),...}\n' +
' or single property object={keyRE:vReV2}\n' +
'\n' +
' A.Ciphered properties of object;\n' +
' B.Element(s) of array "ciphered" in the form of single property object\n' +
' {keyRE:v1ReV2} or {nRe:v1Rev2} (see <Digital key practice> paragraph\n' +
' regarding nRe form of key;\n' +
' C.Variable being RegExp ciphered by means of cipher object wihtout key, i.e.\n' +
' Cipher without key has format {RE:vReV2}, where RE=\'RE\'+rndmN,\n' +
' rndmN - string of N random digits. Deciphered RegExp will be:\n' +
' new RegExp(v1,v2)\n';
console.log(decipheringScheme);
var digitalKeys = ' --- "Digital keys practice": ---\n\n' +
' The notion "Digital key" means property name consisting only of digital\n' +
' characters. For ex.: \'1\',\'12\', \'234\' ... something conforms regular\n' +
' expression /^\d+$/.\n' +
' Let\'s use short variable form <n> as notation of a Digital key.\n' +
' Here is an example of digital key in single property object -\n' +
' {"n":new RegExp(v1,v2)} with value as RegExp object.\n' +
' Decipher converts cipher object into RegExp.\n' +
' Deciphering procedure uses single property digital key object as\n' +
' Intermediary in conversion. Cipher object like {nRe:v1ReV2} transforms\n' +
' into {n:new RegExp(v1,v2}, is stored in Depo and than converts into\n' +
' RegExp object. Depo keeps key-value pairs ordered by digital keys values.\n' +
' to fulfill final conversion.\n' +
' \n' +
' Decipher having found digital key single property object as an array\'s\n' +
' element will transfer it into an element with value new RegExp(v1,v2)\n' +
' and index n.\n' +
' i index n index\n' +
' pO=[...,{nRe:v1Rev1},... ] ==> [ ..., new RegExp,...]\n' +
' n could not be equal to i, but typically is when deciphering is reverse\n' +
' procedure of previous ciphering:\n' +
' [...,rE,...] ->cipher-> [...,{iRe:v1ReV2},..] ->decipher -> [...,rE,..]\n' +
' Due to some reasons parent array in ciphered form could have few\n' +
' cipher objects with\n' +
' - equal digital keys and equal/not equal regExp values\n' +
' - or has one object with key,value pairs as separate properties\n' +
' Decipher follows convention:\n' +
' 1.index number got from digital key prevails indices of existed elements,\n' +
' but, if parent array already has element with RegExp value and index\n' +
' coinciding that determined by digital key, new element is not added.\n' +
' 2.few cipher objects having equal digital keys combined in common array\n' +
' who itself becomes an element of parent array with index equal to digital\n' +
' key value, i.e. [..,{k1:rE1},{k1:rE2,...,{k1:rE3}] converts into ->\n' +
' [..., [rE1,rE2,rE3],...],where subarray with rE-s is an element of \n' +
' parent array and has index k1.\n' +
' 3.When cipher object being element of parent array has few cipher pairs\n' +
' properties [...{k1:re1,k2:re2,k3:re3},...] it will be converted into\n' +
' [...,re1,...,re2,re3], where elements re1,re2,re3 have indices k1,k2,k3\n' +
' appropriately.\n';
console.log(digitalKeys);
}());
var remarkRegardingDeletPropertyOfObject =
' * ---- this.property = null vs. delete this.property ---- *\n\n' +
' Google Style Guide \n' +
' https://google.github.io/styleguide/javascriptguide.xml#JSDoc_Tag_Reference \n' +
' prefferes \n' +
' this.property = null; \n' +
' to\n' +
' delete this.property; \n' +
' At the same time in regStr handler we use delete property; in the\n' +
' following cases:\n' +
' A. While deciphring cipher pair keyRe=vRev2 into property ]n' +
' {...,key:new RegExp(v,v2),..}\n' +
' keyRe property is not pertinent to original object so to leave it means\n' +
' changing initial object. \n' +
' @toDo To consider is it worthwhile the loss of productivity based on\n' +
' this supposition ( keeping original original shape )?\n' +
'\n' +
' B. The unCycle package uses same logic when uid property is deleted\n' +
' presuming that it\'s new one and was absent in original object\n' +
'\n' +
' C. While transforming cipher object being parent array element and \n' +
' and having the form { nRe:vRev2} into parent array\'s element with index\n' +
' n and value new RegExp(v,v2) -> [...,...,new RegExp(v,v2),...]\n' +
'\n' +
' Reason used: using o[p]null instead of delete o[p] save time but change\n' +
' the original which could don\'t like for public user. For internal use or\n' +
' external puclic user would accept appearance of new propertis like\n' +
' <uid> or <keyRe> ... it is possible to make extra code. But in the case\n' +
' of parent array extra element in the form of cipher object could be harmful\n';