// Javascript zum Lösen linearer diophantischer Gleichungen
// (c) Arndt Brünner, Gelnhausen, 2. 1. 2003
// Version: 8. 8. 2003


var k=new Array(20),a=new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
var p_v=new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
var Erkl=(1==1);
var te="",GGT,Z=new Array(),pe="",ERR1,ERR2;
var vd=new Array("","","","","","","",""),vl,rek,iic;
var optMP=(0==0);

function test(nn)
{
	var i,j,n;
	for(j=0;j<1;j++)
	{
	n=(isNaN(nn))?Math.floor(Math.random()*5+2):nn;
	do{
	for(i=0;i<=n;i++)do{a[i]=Math.floor(Math.random()*20-10);}while(a[i]==0);
	}while(!testLoesbarkeit(a,n));
	v=new Array("x","y","z","w","u","v","q");
	var t="";
	document.f.g.value=t=getGlStr1(n,a,v);
	document.f.t1.value=run(t);
	}
}

function test2()
{
	var v=new Array("","x","y","z","u","v","w");
	var a=new Array(3,-4,5,-6,7,-8);
	var p=new Array("","a","b","c","d","e","f");
	var c=new Array(0,1,0,-9,17,-8);
	var t=getGlStr1(5,a,v)+"\n\n"+getGlStr2_(2,5,a,v,4,c,p)+"\n\n"+getGlStr3_(2,5,a,v,4,c,p).join("\n")+"\n\n"+getGlStr4_(2,5,a,v,4,c,p).join("\n");
	document.f.t1.value=t;
}

function run(g)
{
	var gMerk=g;
	var rat=document.f.rational.checked;
	if(!eingabetest(g,"()[]²³^°!§$%&~'´ß?<>|<._:;#@\\\"}{"+((rat)?"":"/,")))return "fehlerhafte Eingabe\n\nGebrochene Koeffizienten können optional aktiviert werden (siehe unten)";
	g=g.replace(/ /g,"").replace(/—/g,"-").replace(/–/g,"-").replace(/\*/g,"").replace(/·/g,"");
	g=g.replace(/\-/g," -").replace(/\+/g," +");
	tt=g.split("=");
	if(tt.length!=2){alert("Fehler: Keine Gleichung");return "fehlerhafte Eingabe";}
	t1=tt[0].split(" ");
	t2=tt[1].split(" ");
	var i,j,n,v=new Array(),c=new Array(10);
	v[0]="",t="";
	te="";ERR1=0;ERR2=0;
	for(i=0;i<40;i++){a[i]=0;p_v[i]=0;Z[i]=1;vd[i]="";}
	k[26]=k[1];
	GGT=1;
	for(var i=0;i<k.length;i++)k[i]=new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
	for(i=0;i<t1.length;i++){n=regkoeffvar(a,t1[i],v,1,rat);}
	for(i=0;i<t2.length;i++){n=regkoeffvar(a,t2[i],v,-1,rat);}
	if(GGT>1)
	{
		var GGTmerk=GGT;
		for(i=0;i<=n;i++)a[i]*=GGT/Z[i];
		for(i=0;i<=n;i++){if(a[i]!=0){GGT=Math.abs(ggT(GGT,a[i]));}}
		for(i=0;i<=n;i++)a[i]/=GGT;
		//alert(Z+"\n"+GGT+"  "+GGTmerk);
		if(GGTmerk/GGT>1)
		{
			te+=" \nDie Koeffizienten der eingegebenen Gleichung "+gMerk+"\n";
			te+="werden zunächst durch Multiplikation mit "+GGTmerk/GGT+" ganzzahlig gemacht.\n";
			te+="Die Lösungsmenge ändert sich dadurch nicht.\n";
		}
	}
	document.f.g.value=getGlStr1(n,a,v);
	GGT=Math.abs(a[1]);
	Erkl=document.f.erkl.checked;
	te+=" \nEs soll die diophantische Gleichung  "+document.f.g.value+"  gelöst werden.\n\n";
	if(document.f.ggtcheck.checked)
	{
	if(!testLoesbarkeit(a,n))
		{te+=(" \n\n   Der ggT der Koeffizienten teilt die Konstante "+(-a[0])+" nicht. (ggT = "+GGT+")\n\n       ===> Die Gleichung hat keine ganzzahligen Lösungen!\n\n\n");if(!Erkl)return te;}
	else
		te+="(Die Gleichung ist in Z lösbar, da der ggT der Koeffizienten "+GGT+" die Konstante "+(-a[0])+" teilt.)\n\n";
	}	
	aa=new Array(a.length);
	for(i=0;i<a.length;i++)aa[i]=a[i];
	P=getP(v);
	te+="Das von Euler entwickelte Verfahren ist eng verwandt mit dem euklidischen Algorithmus.\n";
	te+="Man betrachtet nur die jeweiligen Reste bei der Division durch einen der Koeffizienten, \n";
	te+="geeigneterweise den mit dem kleinsten Betrag, und reduziert die Reste dadurch solange, \nbis nur noch ein ganzzahliger Rest bleibt.\n\n";
	rek=0;iic=0;
	var Q=solveDiophant(n,a,0,c,k,v,P);
	if(Q!="")
	{
		var ERR="",err=(0==0);
		if(ERR1>0)ERR=" - Ganzzahlüberlauf bei Multiplikation: "+ERR1+" mal\n";if(ERR2>0)ERR+=" - Division geht nicht ganzzahlig auf: "+ERR2+"mal\n";
		if(ERR=="")ERR="keine";else ERR+="\n\nDetails siehe Erläuterungen.";
		if((err=!probe(aa,k,n,10,v,P)))alert("Die Lösung ist laut Probe falsch!\n\n\nErkannte Fehler während der Rechnung:\n\n"+ERR);
		if(iic>1)te+="\nDamit hängen alle Variablen nur noch von freien Parametern ab, die unabhängig \nvoneinander die Menge der ganzen Zahlen durchlaufen können:\n\n";
		if(iic==1)te+="\nDamit hängen alle Variablen nur noch von einem Parameter ab, der die Menge der ganzen \nZahlen durchlaufen kann:\n\n";
		if(iic==0)te+="\nDamit sind die Variablen zahlenmäßig festgelegt:\n\n";
		for(i=1;i<=n;i++)t+="     "+getLStr(n, k, v[i], P, i)+"\n";
		if(document.f.probe.checked)t+="\n\nProben:\n\n"+pe;
		if((err)&&(ERR!="keine"))t+="\n\n     ACHTUNG:   DIE LÖSUNGEN SIND FALSCH!!!";
		if((err)&&(ERR=="keine"))t+="\n\n     ACHTUNG:   DIE LÖSUNGEN SIND MÖGLICHERWEISE FALSCH\n                (Eine Probe ging nicht auf - möglicherweise wegen Ganzzahlüberlaufs)";
	}
	t+="\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n".substr(0,(16-((((Erkl)?te:" \n")+t).split("\n")).length));
	t+="\n\n\n\n\n_________________________________________________________________";
	t+="__________________________\n                               Javascript von Arndt Brünner";
	return ((Erkl)?te:"Die diophantische Gleichung  "+document.f.g.value+"  besitzt diese Lösungen:\n\n")+t;
}

function solveDiophant(n, a, ci, c, k, v, p)
{
	//alert(v+"\n"+p);
	//alert(a+"\n"+c)
	var b=new Array(n+1), d=new Array(n+1);
	var ai=0, i, z=0, j, zz=0, zzz=0, ic=0, sai, tt;

	for(i=0;i<n+5;i++){b[i]=0;d[i]=0;}

	//Suche Variable mit kleinstem Koeffizienten
	ai = getMinIndex(a, n);

	if(ai==-1)
	{
		alert("Keine Variable enthalten!\nUnerwarteter Fehler");
		return false;
	}

	if(Erkl)
	{
		te+="Die Variable mit dem kleinsten Koeffizienten ist "+v[ai];
		te+=". Die Gleichung wird nach "+v[ai]+" umgeformt:\n\n";
		te+=(tt=vd[ai]=getGlStr2_(ai,n,a,v,ci,c,p,5))+"\n\n";
		if(Math.abs(a[ai])!=1)
		{
			te+=(vd[ai]=getGlStr3_(ai,n,a,v,ci,c,p,5).join("\n"))+"\n\n";
			if(true)
			{
				var ttt;
				tt=(getGlStr4_(ai,n,a,v,ci,c,p,5)).join("\n");
				if((tt.indexOf("—")>-1)&&(tt.indexOf("=  +")==-1))
				{
					te+="Nun wird der Bruch durch komponentenweise Division ";
					te+="mit Rest in einen Teil mit ganzzahligen \n";
					te+="Koeffizienten und den Rest zerlegt:\n\n";
				}
				else
				{
					vd[ai]=tt;
				}
				if(tt.indexOf("=  +")==-1)te+=tt+"\n\n";
			}
		}
	}
	    
	sai=Sgn(a[ai]);

	for(i=0;i<=n;i++)
	{
        // Berechne nicht-ganzzahlige Anteile
		/*if(i!=ai)*/ a[i]*=-sai;
		b[i] = Sgn(a[i]) * (Math.abs(a[i])%Math.abs(a[ai]));
		if((b[i]!=0)&&(i>0))z++;
		if((b[i]!=0)&&(i==0))zzz++;
		if((i>0)&(i<=ci))
		{
			c[i]*=-sai;
			d[i]=Sgn(c[i]) * (Math.abs(c[i])%Math.abs(a[ai]));
			if(d[i]!=0){zz++;ic=i;} // merken, für den Fall, daß nur Rest bei Parameter(n) bleibt
			if(c[i]!=0)k[ai][i]=c[i];  
		}


        // Wandle ganzzahlig enthaltene Variablen
        // in freie Parameter um
		if((i>0)&&(a[i]!=0)&&(ai!=i)&&(a[i]%(-a[ai])==0))
		{
			ci++;
			iic++;
			k[ai][ci]=a[i];
			a[i]=0;
			k[i][ci]=1;

			if(Erkl)
			{
				te+="Da die Variable "+v[i]+" nur noch im ganzzahligen Teil vorkommt, ";
				te+="setze den Parameter "+p[ci]+" = "+v[i]+".\n\n";
				var R=new RegExp(v[i]),l1=tt.length,l2;
				tt=tt.replace(R,p[ci]);l2=tt.length;
				var i2=tt.lastIndexOf("\n");
				if(i2>-1)
				{
					tt=tt.substr(0,i2+1)+space.substr(0,l2-l1)+tt.substring(i2+1,tt.length);
					tt=space.substr(0,l2-l1)+tt;
				}
				te+=(tt)+"\n\n\n";
				vd[i]=p[ci];
			}

		}
	}


	if((z>0)||(zz>0))
	{
        // Noch nicht-ganzzahliger Teil enthalten,
        // welcher als nächster freier Parameter
        // deklariert wird
		ci++;
		iic++;
		d[ci]= -Math.abs(a[ai]);
		if(Erkl)
		{
			te+="Da alle anderen Summanden ganzzahlig sind, muß auch der Restbruch ganzzahlig sein.\n";
			te+="Der ganzzahlige Parameter "+p[ci]+" wird eingeführt und dem Bruch gleichgesetzt:\n\n";
			te+=getGlStr3_(-ci,n,b,v,ci,d,p,5).join("\n")+"\n\n";
			te+=getGlStr2_(-ci,n,b,v,ci,d,p,5)+"\n\n\n";
		}
        
        // Falls im Rest keine Variable mehr enthalten ist,
        // deklariere einen enthaltenen Parameter als Variable
        	if(z==0)
		{
			n++;
			b[n]=d[ic];
			a[n]=c[ic];
			d[ic]=0;
			c[ic]=0;
			k[ai][ic]=0;
			v[n]=p[ic];
			//alert("setze "+p[ic]+" als neue Variable);
			p_v[ic]=n;

		}        

        	// Reduzierte Gleichung lösen
		rek++;
        	var Q = solveDiophant(n, b, ci, d, k, v, p).split(",");
		if(Q.length==1)return "";
		n=Q[0];ci=Q[1];

		// Überprüfe, ob früherer Koeffizient neue Variable geworden ist
		for(i=1;i<p_v.length;i++)
		{if(isNaN(a[p_v[i]]))a[p_v[i]]=0;
		if((p_v[i]>0)&&(a[p_v[i]]==0)){a[p_v[i]]=k[ai][i];k[ai][i]=0;/*te+=i+". Koeff. wurde "+p_v[i]+". Var.\n\n";*/}}

        
        	// Berechne Koeffizienten
		k[ai][0]=a[0];

		for(i=1;i<=n;i++)
			if(i!=ai)
			{
				if(i>=a.length)a[i]=0;
				for(j=0;j<=ci;j++)
				{
//					if(isNaN(k[ai][j]+a[i]*k[i][j])){alert("ai="+ai+"  j="+j+"   i="+i+"\nk[ai][j]="+k[ai][j]+"\na[i]="+a[i]+"\na = "+a+"\nk = "+k);return;}
					var pr=a[i]*k[i][j];
					if(pr!=0){if((Math.abs(pr)%100)-(Math.abs(k[i][j])%100)*(Math.abs(a[i])%100)%100!=0)
					{	te+="-------------------------------------\nFehler bei Multiplikation: "+a[i]+"·"+k[i][j]+" != "+pr+"\n-------------------------------------\n\n";
						ERR1++;}}
					k[ai][j]+=Math.round(pr);
					
				}
			}
		for(j=0;j<n;j++)
		{
			if(k[ai][j]%(-a[ai])!=0)
			{	te+="\n-------------------------------------\nFehler: Nicht ohne Rest teilbar: (1) Var "+ai+": ("+v[ai]+")    Koeff "+j+": "+p[j]+"\n"+k[ai][j]+" / "+(-a[ai])+"\n-------------------------------------\n\n";
				ERR2++;
			}
			k[ai][j]/=Math.abs(a[ai]);
		//	k[ai][j]=Math.round(k[ai][j]);
		}

		if(Erkl)
		{
			te+="Eliminiere die Unbekannte(n) durch Einsetzen in die Gleichung für "+v[ai]+":\n\n\n";
			te+=getGlStr5_(ai,v,vd,k,p,3)+"\n\n\n";
		}
	//	te+=a+"\n\n";
	}
	else
	{
        // Alle Variablen ganzzahlig

		if((zz==0)&&(zzz>0))
		{
            // auch bei Parametern kein Rest,
            // aber bei Konstante!
            	//Stop
            	//unlösbar
			if(Erkl)
			{
				te+="Der Bruch ist definitiv nicht ganzzahlig. \n\n       ===>  Es existiert keine ganzzahlige Lösung!\n\n\n";
			}
			return "";
		}
		if(zz==1)
		{
            //... aber Rest bei Parameter(n) und/oder Konstante
            // (Fall wurde oben abgefangen)
        	}
		if(zz>1)
		{
            //'... Rest bei mehreren Parametern!
		}

		if(a[0]%(-a[ai])!=0){ te+="\n-------------------------------------\nFehler - nicht ohne Rest  teilbar (2)\n"+a[0]+" / "+(-a[ai])+"\n-------------------------------------\n\n";
					ERR2++;}
		if(isNaN(k[ai][0]))k[ai][0]=0;
		k[ai][0]=a[0]/Math.abs(a[ai]);
		for(i=1;i<=ci;i++)
		{
			if(isNaN(k[ai][i]))k[ai][i]=0;
			if(k[ai][i]%a[ai]!=0){te+="\n-------------------------------------\nFehler - nicht ohne Rest teilbar (3)\n"+k[ai][i]+" / "+(-a[ai])+"\n-------------------------------------\n\n";
							ERR2++;}
			k[ai][i]/=Math.abs(a[ai]);
		}

		if(Erkl)
		{
			te+="Nun ist auf der rechten Seite der Gleichung kein Bruch und keine der Variablen mehr \nenthalten. ";
			if(rek>0)
			{
				te+="Durch Einsetzen in umgekehrter Reihenfolge werden nun in allen Gleichungen,\n";
				te+="in denen eine Variable isoliert wurde, die anderen Variablen eliminiert.\n\n";
			}
			else
			{
				te+="\n\n";
			}
			removeLS(vd);
			vl=ai;
		}

	}
		//te+=a+"\n\n";

	return n+","+ci;
}


function probe(a,k,n,m,V,P)
{
	var i,x,y=new Array(),j,ii,iii,t="",e=document.f.probe.checked;
	var p=new Array(n);
	for(i=1;i<=m;i++)
	{
		if(e)t+="  "+i+". Zufallswert(e):  ";
		for(ii=1;ii<k[1].length;ii++)
		{
			p[ii]=Math.floor(Math.random()*40)-20;
			if(e)
			{
				for(iii=1;iii<=n;iii++){if(k[iii][ii]!=0){t+=P[ii]+" = "+p[ii]+"     ";break;}}
			}
		}
		if(e)t+="\n    ";
		p[0]=1;
		x=0;
		for(ii=1;ii<=n;ii++)
		{
			if(e){y[ii]=0;t+=V[ii]+" = ";}
			for(j=0;j<k[1].length;j++)
			{
				x+=a[ii]*k[ii][j]*p[j];
				if(e){y[ii]+=p[j]*k[ii][j];if(k[ii][j]!=0)t+=k[ii][j]+"·"+((p[j]<0)?"(":"")+p[j]+((p[j]<0)?")":"")+" + ";}
			}
			if(e)t+="= "+y[ii]+"\n    ";
		}
		if(e)
		{
			for(ii=1;ii<=n;ii++)t+=a[ii]+"·"+((y[ii]<0)?"(":"")+y[ii]+((y[ii]<0)?")":"")+" + ";t+="= "+x;
			if(x==-a[0])t+="       OK"; else t+="       F E H L E R";
			t+="\n\n";
			t=t.replace(/\+-/g,"-").replace(/\+ =/g,"=").replace(/\+ -/g,"- ");
		}
		if(x!=-a[0]){pe=t;return false;}
	}
	if(e)pe=t;
	return true;
}


function Sgn(x){return (x>0)?1:((x<0)?-1:1);}
function ggT(a,b){if(a*b==0)return 1;var c;do{c=a%b;a=b;b=c;}while(c!=0);return Math.abs(a);}

function getMinIndex(a, n)
{
	var i, i0=-1;
	for(i=1;i<=n;i++)
	{
		if(i0==-1)
			{if(a[i]!=0)i0 = i;}
		else
			{if((Math.abs(a[i])<Math.abs(a[i0]))&&(a[i]!=0)) i0 = i;}
	}
	return i0;
}

function testLoesbarkeit(a, n)
{
	var i, g, b;
	g=Math.abs(a[1]);
	for(i=2;i<=n;i++)
	{
		b=Math.abs(a[i]);
		g=ggT(g,b);
		GGT=g;
		if(g==1)return true;
	}
	return (a[0]%g==0);
}


function regkoeffvar(a,t,v,s,rat)
{
	var j,V,n,i,S=1,t0,z=1;
	t0=t.substr(0,1);
	if(t0=="-"){S=-1;t=t.substring(1,t.length);}
	if(t0=="+"){S=1;t=t.substring(1,t.length);}
	if(rat)
	{
		if((j=t.indexOf(","))>-1)
		{
			for(i=j+1;i<t.length;i++)if(isNaN(t.charAt(i)))break;
			t=t.substr(0,j)+t.substring(j+1,i)+"/100000000000000000000".substr(0,i-j+1)+t.substring(i,t.length);
		}
		if((j=t.indexOf("/"))>-1)
		{
			for(i=j+1;i<t.length;i++)if(isNaN(t.charAt(i)))break;
			GGT*=(z=Number(t.substring(j+1,i)));
			t=t.substr(0,j)+t.substring(i,t.length);
		}
	}
	j=t.search(/\D/);
	if(j==0)n=1;
	else if(j==-1)n=Number(t);
	else n=Number(t.substr(0,j));
	if(j==-1){a[0]*=z;a[0]+=n*s*S;Z[0]*=z;}
	else
	{
	V=t.substring(j,t.length);
	for(i=0;(i<v.length)&&(v[i]!=V);i++);
	v[i]=V;if(i>=a.length)a[i]=0;
	a[i]*=z;a[i]+=s*S*n*Z[i];
	Z[i]*=z;
	}
	for(i=a.length-1;i>=0;i--)if(a[i]!=0)break;
	return i;
}

function eingabetest(g,t)
{
	for(var i=0;i<t.length;i++)
	{
		var T=t.substr(i,1);
		if (g.indexOf(T)>-1){alert("unzulässiges Zeichen: "+T); return false;}
	}
	return true;
}

function getLStr(n, k, v, p,i)
{
	var t="",j,K,d=(1==9),MP="";
	for(j=0;j<k[i].length;j++)
	{
		if(p[j]==null)p[j]="?";
		MP=(optMP&&(j>0)&&(p[j].indexOf("P[")>-1))?"·":"";
		K=k[i][j];
		if(K!=0)t+=((K>0)?"+":"-")+(((Math.abs(K)!=1)||(j==0))?Math.abs(K)+MP:"")+((j>0)?p[j]:"");
	}
	t=t.replace(/-/g," - ").replace(/\+/g," + ");
	if(t=="")t=" 0";
	t=v+" ="+t; 
	t=t.replace(/= \+/,"=").replace(/ +/g," ").replace(/= - /,"= -").replace(/=-/,"= -");
	if(v=="")t=t.substring(3,t.length);
	return t;
}

function getGlStr1(n,a,v)
{
	return getTStr(1,n,a,v)+" = "+(-a[0]);
}

function getTStr(i0,n,a,v)
{
	var t="",j,A,vd=(v[0]=="")?1:0,optM=(8==7);
	for(i=i0;i<=n;i++)
	{
		optM=(v[i].indexOf("P[")>-1)&&optMP;
		A=a[i];
		if(A!=0)t+=((A>0)?"+":"-")+(((Math.abs(A)!=1)||(i==0))?Math.abs(A)+(((optM)&&(i>0))?"·":""):"")+((i>0)?v[i-1+vd]:"");
	}
	t=t.replace(/-/g," - ").replace(/\+/g," + ");
	if(t.substr(0,3)==" - ")t="-"+t.substring(3,t.length);
	if(t.substr(0,3)==" - ")t="-"+t.substring(3,t.length);
	if(t.substr(0,3)==" + ")t=t.substring(3,t.length);
	return t;
}

var space="                                                                     ";
var brstr="—————————————————————————————————————————————————————————————————————";
space+=space;brstr+=brstr;brstr+=brstr;;space+=space;

function getGlStr4(il,n,a,v,sp)
{
	var a1=new Array(n),a2=new Array(n),v1=new Array(n),t=new Array(3),s=-Sgn(a[il]);
	var i,j=0,l0,l1,tt;
	if(isNaN(sp))sp=0;var SP=space.substr(0,sp);
	for(i=0;i<=n;i++)
	{if(i!=il){v1[j]=v[i];a1[j]=s*Math.floor(Math.abs(a[i]/a[il]))*Sgn(a[i]);
	a2[j++]=s*a[i]%Math.abs(a[il]);}}
	tt=getTStr(0,n-1,a1,v1);if(tt=="")tt="0";
	t[1]=v[il]+" = "+tt+" +  ";
	l1=t[1].length;
	t[0]=getTStr(0,n-1,a2,v1);l2=t[0].length;
	if(l2==0)return new Array(SP+t[1].substr(0,l1-4));
	t[0]=space.substr(0,l1+1)+t[0];t[2]=space.substr(0,l1+1+l2/2-String(Math.abs(a[il])).length/2+.5)+Math.abs(a[il]);
	t[1]+=brstr.substr(0,l2+2);
	t[0]=SP+t[0]+" ";t[1]=SP+t[1];t[2]=SP+t[2];
	return t;
}

function getGlStr2(il,n,a,v,sp)
{
	var a1=new Array(n),v1=new Array(n),s=-Sgn(a[il]);
	var i,j=0,l0,l1,t,tt,optM=(v[il].indexOf("P[")>-1)&&(optMP);
	if(isNaN(sp))sp=0;var SP=space.substr(0,sp);
	for(i=0;i<=n;i++){if(i!=il){v1[j]=v[i];a1[j++]=s*a[i];}}
	t=((s==-100)?"-":"")+((Math.abs(a[il])!=1)?Math.abs(a[il])+((optM)?"·":""):"")+v[il];
	tt=getTStr(0,n-1,a1,v1);if(tt=="")tt="0";
	return SP+t+" = "+tt;
}

function getGlStr3(il,n,a,v,sp)
{
	var a1=new Array(n),v1=new Array(n),s=-Sgn(a[il]),t=new Array(3);
	var i,j=0,l0,l1;
	if(isNaN(sp))sp=0;var SP=space.substr(0,sp);
	for(i=0;i<=n;i++){if(i!=il){v1[j]=v[i];a1[j++]=s*a[i];}}
	t[1]=v[il]+" =";l1=t[1].length;
	t[0]=getTStr(0,n-1,a1,v1);if(t[0]=="")t[0]="0";
	l2=t[0].length;
	t[2]=space.substr(0,l1+2+l2/2-String(Math.abs(a[il])).length/2+.5)+Math.abs(a[il]);
	t[1]+=" "+brstr.substr(0,l2+2);t[0]=space.substr(0,l1+2)+t[0];
	t[0]=SP+t[0]+" ";t[1]=SP+t[1];t[2]=SP+t[2];
	return t;
}

function getGlStr2_(il,n,a,v,m,c,p,sp)
{
	var A=new Array(n+m+2),V=new Array(n+m+2);
	concatArrays(n,a,v,m,c,p,A,V);
	if(il<0){il=n-il;if(isNaN(A[il]))A[il]=1;}
	return getGlStr2(il,n+m,A,V,sp);
}
function getGlStr3_(il,n,a,v,m,c,p,sp)
{
	var A=new Array(n+m+2),V=new Array(n+m+2);
	concatArrays(n,a,v,m,c,p,A,V);
	if(il<0)il=n-il;
	return getGlStr3(il,n+m,A,V,sp);
}
function getGlStr4_(il,n,a,v,m,c,p,sp)
{
	var A=new Array(n+m+2),V=new Array(n+m+2);
	concatArrays(n,a,v,m,c,p,A,V);
	if(il<0)il=n-il;
	return getGlStr4(il,n+m,A,V,sp);
}

function removeLS(vd)
{
	var i,t,j,l,ig;
	for(i=0;i<vd.length;i++)
	{
		t=vd[i].split("\n");
		j=((l=t.length)==1)?0:1;
		ig=t[j].indexOf("=");
		for(j=0;j<l;j++){if(ig>-1)t[j]=t[j].substring(ig+2,t[j].length);}
		vd[i]=t.join("\n");
	}
}

function getGlStr5_(ai,v,vd,k,p,sp)
{
	if(isNaN(sp))sp=0;var SP=space.substr(0,sp);
	var t1=vd[ai].split("\n");
	var t2=new Array(t1.length),i,d,V=SP+v[ai]+"  =  ",t;
	SP=space.substr(0,V.length);
	for(i=0;i<t1.length;i++)t2[i]=t1[i];
	for(i=1;i<vd.length;i++)
	{
		if(v[i]==null)v[i]="";
		if(v[i]!="")
		t2[0]=t2[0].replace(/\[/,"L").replace(/\]/,"R").replace(new RegExp(v[i].replace(/\[/,"L").replace(/\]/,"R")),(vd[i].length<3)?((vd[i].search(/\d/)!=0)?vd[i]:"·"+vd[i]):"·("+vd[i]+")");
	}
	if(t1.length>1)
	{
		d=t2[0].length-t1[0].length;
		if(d>=0)
		{
			t2[1]+=brstr.substr(0,d);t2[2]=space.substr(0,d/2)+t2[2];
			t2[1]+="  =  "+(vd[ai]=getLStr(k[ai].length,k,"",p,ai))+"   ";
		}
		else
		{
			t2[1]=t2[1].substring(-d,t2[1].length);
			t2[2]=t2[2].substring(-d/2,t2[2].length);
			t2[1]+="  =  "+(vd[ai]=getLStr(k[ai].length,k,"",p,ai))+"   ";
		}
		t=SP+t1[0]+"     "+t2[0]+"\n";
		t+=V+t1[1]+"  =  "+t2[1]+"\n";
		t+=SP+t1[2]+space.substr(0,t1[1].length-t1[2].length+5)+t2[2];
	}
	else t=V+t1[0]+t2[0]+"  =  "+(vd[ai]=getLStr(k[ai].length,k,"",p,ai));
	return t.replace(/R/g,"]").replace(/L/g,"[");
}

function concatArrays(n,a,v,m,c,p,A,V)
{
	var j=0,i;
	for(i=0;i<=n;i++){A[j]=a[i];V[j++]=v[i];}
	for(i=1;i<=m;i++){A[j]=c[i];V[j++]=p[i];}
}

function getP(v)
{
	var i,j,pp="P[01],P[02],P[03],P[04],P[05],P[06],P[07],P[08],P[09],P[10],P[11],P[12],P[13],P[14],P[15],P[16],P[17],P[18],P[19],P[20]";
	var t="a,b,c,d,e,f,g,h,i,j,";
	for(i=1;i<v.length;i++){if(t.indexOf(v[i].toLowerCase())>-1)break;}
	if(i==v.length)return (","+t+pp).split(",");
	t="p,q,r,s,t,u,v,w,";
	for(i=1;i<v.length;i++){if(t.indexOf(v[i].toLowerCase())>-1)break;}
	if(i==v.length)return (","+t+pp).split(",");
	t="x,y,z,t,u,v,w,";
	for(i=1;i<v.length;i++){if(t.indexOf(v[i].toLowerCase())>-1)break;}
	if(i==v.length)return (","+t.toUpperCase()).split(",");
	return (","+pp).split(",");
}


//8423423a - 353453y - 1034564565p = -73453454
