Something for the weekend
Lot's of interesting UA research going on this week. Haven't caught up with all of it yet.
In the meantime, I've hacked together a sort of UA triangle editor / viewer inspired the UA_Draw tool by Anjin (and subsequent UA_Draw modifications by RedWizard).
Thought I'd share it here in case anyone finds it useful for investigating/verifying UA morse.
It's available on the following Paper.js sketch URL: here
DISCLAIMER: Only tested on Firefox
Screenshot of the tool in the spoiler below.
I've minified it purely for space reasons, but will put it up on GitHub someplace (or the Canonn GitHub we have one) once I've cleaned it up a bit. In the meantime suggestions via PM welcome!
The URL is rather large since it also contains the encoded script. You can also visit http://sketch.paperjs.org and paste in the code contained within the spoiler tag below.
Documentation in next spoiler tag:
Have fun!
Lot's of interesting UA research going on this week. Haven't caught up with all of it yet.
In the meantime, I've hacked together a sort of UA triangle editor / viewer inspired the UA_Draw tool by Anjin (and subsequent UA_Draw modifications by RedWizard).
Thought I'd share it here in case anyone finds it useful for investigating/verifying UA morse.
It's available on the following Paper.js sketch URL: here
DISCLAIMER: Only tested on Firefox
Screenshot of the tool in the spoiler below.
I've minified it purely for space reasons, but will put it up on GitHub someplace (or the Canonn GitHub we have one) once I've cleaned it up a bit. In the meantime suggestions via PM welcome!
The URL is rather large since it also contains the encoded script. You can also visit http://sketch.paperjs.org and paste in the code contained within the spoiler tag below.
Code:
// ----------------------------
// UA code editor / viewer
// by CMDR Eoran, for 'The Canonn' R&D.
// Version: 1.0
// ----------------------------
// Credits:
// code: CMDR Eoran
// presets: CMDR rizal72
// inspired by UA_Draw by: CMDR Anjin, and CMDR Red Wizard
// ----------------------------
// Paste in your UA code here, or leave blank to edit manually (default).
var startupDisplayCode = "";
var config = {
cellSize: 16,
pointRadius: 2,
gridLineOpacity: 0.05,
gridPointOpacity: 0.05,
allowToggleVertex: true
};
// These are from rizal72
// ref: https://forums.frontier.co.uk/showthread.php?t=175726&p=2932656&viewfull=1#post2932656
var presets = {
"ADDER":
"BTCQEQ BTEQFQ BTFQEU BTFQDV BTDVCV CQCNDM CQDMDQ DMHIMG DMGMDQ DQGMFQ EUFQHP EUHPKN EUKNPM EUPMIU EUIUGV"
+ "EUGVDV FQGMHP GMHIJH GMJHNF GMNFPF GMPFJL GMJLKN HIIGJH PJLKNN IGLEMF IGMFJH IUPMQO JHNFNF JLPFPG JLPGSG"
+ "JLSGKN KNSGPM PFQDPG PGQDSD PGSDSG PMSGVH PMVHVM PMVMQO SDTBSG SGTBTF SGTFVH VHXGVM VMXGYI XGYEYI",
"ANACONDA":
"NALBOB JGLBMG KIJGKM HPKMJS HTKSIW HWKSJZ JZKSMZ MTPZPS MZPSPZ KSNJLB LBOBNJ OBSPQS NJOBRT RSSTSV NJPSOZ"
+ "SVQZPZ NJPSPLS",
"ASP":
"AODJHM AOHMQT DJFIHM EHHHII EHIIFI FIIIHM HHJGKG HHKGNG HHNGMH HHMHII HMIILI HMLISR HMSRQT IIMHLI KFNGKG"
+ "LIMHWQ LIWQUQ LIUQSR MHNGOG MHOGWQ OGVIZN OGZNYO STSRST URUQST STUQUR UQWQWR UQWRVS UQVSUR WQYOYP WQYPWR",
"COBRA":
"FCAJBM FCHHBM FCLBHH BMHHHO LBHHQP HHHOQP LBQPVL QPVLWP",
"DBX":
"BUCQEV BUEVEX BUEXBW CQFNFR CQFREV EKIIGJ EVFRHT EVHTHV EVHVEX FNGKHL FNHLIO FNIOFR FRIOIQ FRIQHT GKIILM GKLMHL"
+ "HLLMKM HLKMIO HTIQIT HTITIW HTIWHV HVIWHW IIMGNK IINKLM IOKMIQ IQKMIS ISKMLM ISLMMR ISMRMS ISMSIW IWMSLV LMNKON"
+ "LMONMR MGTDSF MGSFRH MGRHNK MRONOP MROPMS MSOPPP MSPPPR NKRHPM NKPMON ONPMPO ONPOOP OPPOPP PMRHVK PMVKZP PMZPXS"
+ "PMXSPO POXSPP PPXSPR RHSFVF RHVFYI RHYIYJ RHYJVK VFXEYI",
"DBS":
"BOCMCQ BOCQCS BOCSBQ CMFKDO CMDOCQ CQDOFP CQFPGR CQGRCS DOFKGL DOGLHN DOHNFP FKHIGL FPHNJO FPJOJP FOJPGR GLHIKK"
+ "GLKKHN GRJPJR HIMGKK HNKKNM HNNMJO JONMNN JONNJP JPNNNP JPNPJR KKMGOI KKOINM MFPEOG MFOGOH MFOHMG MGOHOI NMOIPK"
+ "NMPKPN NMPNNN NNPNOP NNOPNP OGPESE OGSEQI OGQIOH OHQIOI OIQIPK OPPNQO PEUDSE PKQIXI PKXIWK PKWKZN PKZNWQ PKWQQO"
+ "QISEXI SEUDVE SEVEZH SEZHXI UDVCVE VEXEZH XEZDZH XIZHZI",
"COURIER":
"AQHLHM AQHLHM AQGOHO AQGOMO GKGJHL GKCKEJ BJCICK CIIGGJ IGKFLG JHLGKH GJKIMJ MJSHVK SHVIVK LLMJVK BRLLMO"
+ "BRMOLQ LLVKMO LQMORP LQQRRP PTPVQU PTXPYR QUYRXP PVPVXS QUYQXS QRRPVQ RPUOVQ MOVKYM VKXJYM MOUOYM ",
"CLIPPER":
"AQBPDN ARFQGR CQDOEP DNKKHN FLNIGM FLFJNI FJFINI FIHHJH CICHDH CHFFDH DHFFIF FFIEIF HHIGJH KKRHRI KKRIMN MNRISJ "
+ "FQMNGR GRMNLQ LQTLPP LQPPOR ORTLQS QSTMRS SSTMTT TMULUM URVSTT SVTUTV TUXRYS TUTVYS XRZSYS TVXUZS ",
"EAGLE":
"CMCRKO DRKNMY KNLDMK LDMAOD ODMKQN MKMYQN MYQNXR QNXRXM ",
"DROPSHIPS":
"AOFKHK FKFIHK FIHHHK HKHHKI HHJGLI JGNGKH FMGKJN HKLIJN JNLIRH GNFQHO IPJNJP GTIPJT IPJNMS INNKMT MTNIYR "
+ "NKZPYS NKRHZP",
"FDL":
"ATKIJM KILGMI JMKINH NHPFOI OITIQJ TIVITJ VIXGWI UKUIWI UKWIWJ ROUJXL WLZMUO BUROWO BUIMTJ BUTKRO KLNNRJ NIQNQJ ",
"HAULER":
"ASAOHP AOEKHP DKKLAO DKJGHK JGKFLG JGNGHK NGRHHK RHKLHK RHSFTI RHRNKL TIVMZN VMSPRN KLRNFQ CSRNSP ASHPCS",
"ORCA":
"CDFCFE CDFEEF CDEFGK CDGKCF CFGKEI CFEIDH CHDHEI CHEIDI EFFEGF EFGFIH EFIHIJ EFIJHK EFHKGK FCIDFE FEIDGF GFIDKI "
+ "GFKIIH GKHKJM HKIJJM IDNHKI IHKIKJ IHKJIJ JKJJMO JMKJOM JMOMTT JMTTTU JMTUTV JMTVPS JPLPPS JPPSLR JMPSLP KINHOM "
+ "KIOMKJ NHRLOM OMRLUQ OMUQTT TTUQVU TTVUTU TUVUWW TUWWTV UQVQXT UQXTXU UQXUVU VUXUWW WXXUXW XTYVXU XUYVXW ",
"PYTHON":
"AHG GAICHG HAMFHC ICMFJE JEMFKG JFKGJG MFNKRM NKRMTS LKTSPP PPTSTU PPTURX PPRXNU NURXOZ NUQZMX JPPPNU "
+ "HGMKLO MKPPLO HGLOIP GHKPIP ",
"SW":
"ACNALC LCNAPC NAZCPC ACLCDL DLNAWL PCZCWL LEPEMG",
"T6":
"CIEGON CIONEL CIELCO COELIP COIPHR COHRCQ CQHRHU EEEFGG EEGGFG EEFGEG EGEFON ELONIP FGGGON HRIPKS HRKSKT HRKTHU "
+ "HUKTJV IPONOQ IPOQKS KDKLKF KFLDMF KFMFQH KFQHMI MFRFXJ MIQHQM MIQMON ONQMSQ OQSQSS OQSSRT QHXJUL QHULQM QMULSQ "
+ "RTSSUS SQULVP SQVPVR SQVPSS SSVRUS ULXJXM ULXMVP XJYKXM XMYKYO ",
"T7":
"BVARGV ARAOEJ EJQIJL EJKHQI LMMGNG MGPERE NGRESF MHSFQI SFUFVG SFVGQI TIVGTJ JLTISK SKVIUL ULVIYG ULYGIP JLSKKO "
+ "IOJLKO GQIOKO ETGQMT ETMTGV KOMQLR LRRRMT LRRPRR RRSPVR SPWPVR RPUNSP TNWLWN WNWLYN WLZMYN ULVIYG ULYGYI ",
"T9":
"ANDPBP AMBLDN BIGKCK BIQNGL BICFGK CFGELH IFLELH LFPILH LFOHMH PHPFSG SGVGSH SHVGZN PHSGUL TGZNVJ MHIJLK MHQHPI "
+ "LHPILK LKPIUL LKULQO ULYNYR TMYQUT YRYTVU VTYRVU RNVUPT MORNPT IPMOPT MRPTNU JPNUKT JBIPKT ",
"VIPER":
"ANCKEL ANELEP CKEHEL EHJKEL EHFGJK EPJKVU JKWTVU FGOLON OLONRP RPTPVS QLYQWQ YOYQQL FGGFQL FGQLOL HGIFQL IFKFQL "
+ "KFQLYO KFOFYO ",
"VULTURE":
"APCJKR APKRER APERDR CJDIGJ CJGJPN CJPNKM CJKMKR ERKRLS ERLSGT FGGFHH GFKCOJ GFOJQL GFQLHH GJHHPM GJPMPN HHQLPM "
+ "KCNDOJ KMPNMN KMMNKR KRMNNS KRNSLS MNPNQO MNQOSQ MNSQNS NDQGOJ NSSQOT OJQGQH OJQHSL OJSLQL OTQLVT PMQLRM PMRMQO "
+ "PMQOPN PUVTVU QHTISL QLSLRM QORMUO QOUOSQ RMSLUO SLTIUI SLUIYN SLYNWN SQUOUR SQURVT UOWNYQ UOYQXR UOXRUR URWSVT "
+ "VTWSWT VTWTVU"
};
// ---------------------------
// Internals.. quick and hacky minified javascript: ignore :)
function coordToGridCode(e){return String.fromCharCode(97+e)}function createGrid(){for(var e=0;26>e;++e)for(var i=0;26>i;++i){var o=coordToGridCode(i)+coordToGridCode(e),t=origin+new Point(i*config.cellSize,e*config.cellSize),n=new Shape.Circle(t,config.pointRadius);n.fillColor="black",n.opacity=config.gridPointOpacity,n.gridCode=o,grid[o]=n}for(var r=0;26>r;++r){var s=coordToGridCode(r),P=origin+new Point(0,r*config.cellSize),l=origin+new Point(0,config.cellSize*r),M=new PointText(l);M.content=s,M.justification="center",M.position+=new Point(.75*-config.cellSize,.25*M.bounds.height);var a=origin+new Point(25*config.cellSize,r*config.cellSize),I=origin+new Point(26*config.cellSize,.125*config.cellSize+config.cellSize*r),H=new PointText(I);H.content=s,H.justification="center",H.position+=new Point(0,.25*H.bounds.height);var c=new Path.Line(P,a);c.strokeColor="black",c.strokeWidth=1,c.opacity=config.gridLineOpacity,axisY[s]=[M,H,c];var K=origin+new Point(r*config.cellSize,0),S=origin+new Point(config.cellSize*r,0),d=new PointText(S);d.content=s,d.justification="center",d.position-=new Point(0,.5*d.bounds.height);var L=origin+new Point(r*config.cellSize,25*config.cellSize),O=origin+new Point(config.cellSize*r,26*config.cellSize),G=new PointText(O);G.content=s,G.justification="center";var N=new Path.Line(K,L);N.strokeColor="black",N.strokeWidth=1,N.opacity=config.gridLineOpacity,axisX[s]=[d,G,N]}}function onMouseMove(e){var i=null,o=e.point.x-origin.x,t=e.point.y-origin.y,n=Math.round(o/config.cellSize),r=Math.round(t/config.cellSize),s=coordToGridCode(n)+coordToGridCode(r);i=grid[s],null!=i?(i.radius=2*config.pointRadius,i.opacity=1,gridPoint!=i&&null!=gridPoint&&(gridPoint.radius=config.pointRadius,gridPoint.opacity=config.gridPointOpacity),gridPoint=i):null!=gridPoint&&(gridPoint.radius=config.pointRadius,gridPoint.opacity=config.gridPointOpacity,gridPoint=null)}function getTextPosition(e){return new Point(32+50*(e%8),30*config.cellSize+24*Math.floor(e/8))}function getMarkerPosition(e){return getTextPosition(e)+new Point(-24,0)}function displayStyleHighlighted(e){var i=e.shapeIndex;codes[i].strokeColor="red",shapes[i].strokeColor="red",shapes[i].strokeWidth=3,shapes[i].bringToFront()}function displayStyleNormal(e){var i=e.shapeIndex;codes[i].strokeColor="black",shapes[i].strokeColor="black",shapes[i].strokeWidth=1}function removeEntry(e){var i=[],o=[],t=[],n=[];null!=highlighted&&(displayStyleNormal(highlighted),highlighted=null);for(var r=0,s=0;s<codes.length;++s)s!=e?(codes[s].shapeIndex=r,codes[s].position=getTextPosition(i.length),i.push(codes[s]),sequence[s].shapeIndex=r,o.push(sequence[s]),shapes[s].shapeIndex=r,t.push(shapes[s]),markers[s].shapeIndex=r,markers[s].position=getMarkerPosition(n.length),n.push(markers[s]),++r):(codes[s].visible=!1,codes[s].onMouseEnter=null,codes[s].onMouseLeave=null,shapes[s].visible=!1,markers[s].visible=!1,delete codes[s],delete shapes[s],delete markers[s]);codes=i,sequence=o,shapes=t,markers=n}function insertItem(e,i,o,t,n){for(var r=[],s=[],P=[],l=[],M=0,a=0;a<codes.length;++a)a==e&&(t.shapeIndex=M,t.position=getTextPosition(M),r.push(t),i.shapeIndex=M,i.position=getMarkerPosition(M),l.push(i),n.shapeIndex=M,s.push(n),o.shapeIndex=M,P.push(o),++M),a>=e?(codes[a].shapeIndex=M,codes[a].position=getTextPosition(M),r.push(codes[a]),sequence[a].shapeIndex=M,s.push(sequence[a]),shapes[a].shapeIndex=M,P.push(shapes[a]),markers[a].shapeIndex=M,markers[a].position=getMarkerPosition(M),l.push(markers[a])):(r.push(codes[a]),s.push(sequence[a]),P.push(shapes[a]),l.push(markers[a])),++M;codes=r,sequence=s,shapes=P,markers=l}function processTriangle(e){var i=new Path,o=(e[0].gridCode+e[1].gridCode+e[2].gridCode).toUpperCase();i.add(e[0].position),i.add(e[1].position),i.add(e[2].position),i.strokeColor="black",i.closed=!0,i.shapeIndex=shapes.length;var t=codes.length;null!=caret&&(t=caret.shapeIndex);var n=new PointText(getTextPosition(t));n.content=o,n.fontFamily="courier",n.strokeColor="black",n.shapeIndex=codes.length,n.position=getTextPosition(codes.length),n.justification="left",n.onMouseEnter=function(){null!=highlighted&&displayStyleNormal(highlighted),highlighted=this,displayStyleHighlighted(this)},n.onMouseLeave=function(){displayStyleNormal(this)},n.onMouseDown=function(){null!=highlighted&&removeEntry(this.shapeIndex)};var r=getMarkerPosition(t),s=r+new Point(0,20),P=new Path.Line(r,s);P.strokeWidth=2,P.strokeColor="silver",P.shapeIndex=codes.length,P.position=r,P.onMouseEnter=function(){caret!=this&&(null!=highlightedCaret&&highlightedCaret!=this&&highlightedCaret!=caret&&(highlightedCaret.strokeColor="silver",highlightedCaret.strokeWidth=1),highlightedCaret=this,this.strokeColor="red",this.strokeWidth=2)},P.onMouseLeave=function(){highlightedCaret==this&&(highlightedCaret=null),caret!=this&&(this.strokeColor="silver",this.strokeWidth=2)},null==caret?(markers.push(P),shapes.push(i),codes.push(n),sequence.push(o)):insertItem(t,P,i,n,o)}function onMouseDown(e){e.point;if(null==gridPoint&&(null==highlightedCaret?null!=caret&&(caret.strokeColor="silver",caret.strokeWidth=2,caret=null):caret!=highlightedCaret&&(null!=caret&&(caret.strokeColor="silver"),caret=highlightedCaret,caret.strokeColor="red")),null!=gridPoint){if(gridPoint.selected=!gridPoint.selected,gridPoint.selected)gridPoint.selectedColor="red";else if(config.allowToggleVertex&&null!=triangle){remaining=[];for(var i=0;i<triangle.length;++i)triangle[i]!=gridPoint&&remaining.push(triangle[i]);return void(triangle=remaining.length>0?remaining:null)}if(null==triangle)triangle=[gridPoint];else if(triangle.length<2)triangle.push(gridPoint);else{triangle.push(gridPoint);for(var i=0;i<triangle.length;++i)triangle[i].selected=!1;processTriangle(triangle),triangle=null}}}function addPresetButton(e,i,o,t){var n=new PointText(e+new Point(0,32*i));n.content=o,n.strokeColor="black",n.onMouseDown=function(){displayShape(t)},n.onMouseEnter=function(){this.strokeColor="red"},n.onMouseLeave=function(){this.strokeColor="black"}}function createPresets(){var e=new Point(30*config.cellSize,2*config.cellSize),i=0,o="<< CLEAR >>";presets[o]="_clear_",addPresetButton(e,i,o,"_clear_"),++i;for(var t in presets)if(presets.hasOwnProperty(t)){if(t==o)continue;addPresetButton(e,i,t,presets[t]),++i}}function clearGrid(){for(var e=0;e<codes.length;++e)codes[e].visible=!1,markers[e].visible=!1,shapes[e].visible=!1;codes=[],markers=[],shapes=[],sequence=[],caret=null}function displayShape(e){if(!(null==e||e.length<6)&&(clearGrid(),"_clear_"!==e)){e=e.replace(/ /g,"");for(var i=0;i<e.length;i+=6){var o=e.substr(i,6).toLowerCase();if(!(o.length<3)){t=[];for(var n=0;3>n;++n)t.push(grid[o.substr(2*n,2)]);processTriangle(t)}}}}var grid={},axisX={},axisY={},origin=new Point(2*config.cellSize,2*config.cellSize),gridPoint=null,triangle=null,markers=[],shapes=[],codes=[],sequence=[],caret=null,highlightedCaret=null,highlighted=null;createPresets(),createGrid(),displayShape(startupDisplayCode);
Documentation in next spoiler tag:
The inital view shows presets on the right-hand side, and the code window on the left. The console is on the bottom left, which is where your current edited code will be echod so you can copy/paste it elsewhere.
Click within the grid to place dots. The first two dots can be toggled, the third commits the triangle. This assumes you're drawing triangles, but of course you can disable this by setting allowToggleVertex to false in the config and it'll draw a triangle with any points you give it (even if two share the same vertex). If you change the vertex setting you'll need to run the code again for it to take effect.
Each completed triangle generates a code entry below the grid. By default these are appended to the sequence.
Highlighting the code highlights the corresponding triangle in the sketch. Clicking on the code removes the triangle.
To insert a code, click on the appropriate vertical bar between the codes to it activate that as the insert point for the next code. This allows you to insert/remove triangles to your heart's content. Clicking anywhere in blank space clears the active insert point and codes will be appended to the end of the sequence as before.
Each time you complete a code, the entire sequence so far is echod to the console on the lower left. This is so you can copy the text there and paste it elsewhere.
Hit the "<< CLEAR >>" button to clear the grid.
Clicking on any of the presets will clear the grid and insert the pre-canned squence (these are from rizal72's post here).
If you make any changes to the code, such as presets or otherwise, hit the run button at the top right of the code window. This is also handy for resetting the view and script state.
Click within the grid to place dots. The first two dots can be toggled, the third commits the triangle. This assumes you're drawing triangles, but of course you can disable this by setting allowToggleVertex to false in the config and it'll draw a triangle with any points you give it (even if two share the same vertex). If you change the vertex setting you'll need to run the code again for it to take effect.
Each completed triangle generates a code entry below the grid. By default these are appended to the sequence.
Highlighting the code highlights the corresponding triangle in the sketch. Clicking on the code removes the triangle.
To insert a code, click on the appropriate vertical bar between the codes to it activate that as the insert point for the next code. This allows you to insert/remove triangles to your heart's content. Clicking anywhere in blank space clears the active insert point and codes will be appended to the end of the sequence as before.
Each time you complete a code, the entire sequence so far is echod to the console on the lower left. This is so you can copy the text there and paste it elsewhere.
Hit the "<< CLEAR >>" button to clear the grid.
Clicking on any of the presets will clear the grid and insert the pre-canned squence (these are from rizal72's post here).
If you make any changes to the code, such as presets or otherwise, hit the run button at the top right of the code window. This is also handy for resetting the view and script state.
Have fun!
Last edited: