diff --git a/panther.js b/panther.js
index 5734e167435352aee21e0db91790c607696c1f72..0f8d990186abbf4aeade1b8b2f28834deae1c3f7 100644
--- a/panther.js
+++ b/panther.js
@@ -7,6 +7,7 @@
 	import {EffectComposer} from 'three/addons/postprocessing/EffectComposer.js';
 	import {RenderPass} from 'three/addons/postprocessing/RenderPass.js';
 	import {OutlinePass} from 'three/addons/postprocessing/OutlinePass.js';
+	// 
 	import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';
 
 	import {ellipticaltubeGeometry} from 'components/ellipticaltube.js';
@@ -108,7 +109,7 @@
 	gui.title('PAnTHer - controls');
 	gui.add(params, 'search'); // .onKeyup(function() {console.log('search');});
 	gui.addColor(params, 'backgroundColor').onChange(function() {toggleParam('backgroundColor');});
-	params.far = typeof conf.default_far[machine]!='undefined'? conf.default_far[machine]: 120;
+	params.far = typeof conf.default_far[machine]!='undefined'? conf.default_far[machine]: conf.default_far.default;
 	gui.add(params, 'far', 50, 400).onChange(function() {setFar(params.far);});
 	const debugcamera = document.location.search.indexOf('debugcamera')>-1;
 	if (debugcamera) $('body').append('<div class="debug" style="top: 0; position: fixed;"> x: <input size="5" id="x"/>, y: <input size="5" id="y"/>, z: <input size="5" id="z"/>, cx: <input size="5" id="cx"/>, cy: <input size="5" id="cy"/>, cz: <input size="5" id="cz"/>');
@@ -180,13 +181,13 @@
 		const bpmCurve = [];
 		const bpmFactor = conf.bpmFactor[facility];
 		for (let i=0; i<len; i++) {
-			const j = (i + 1) % len;
-			const tx = bpmPoints[facility][i][0].x * (1+(data.Hor? data.Hor[j]*0.02*bpmFactor*params.bpmZoomH: 0));
+			const j = (i) % len;
+			const tx = bpmPoints[facility][i][0].x + Math.cos(bpmPoints[facility][i][1])*(data.Hor? data.Hor[j]*1000*bpmFactor*params.bpmZoomH: 0);
 			const ty = Ydefault + bpmPoints[facility][i][0].y + (data.Ver? data.Ver[j]*1000*bpmFactor*params.bpmZoomV: 0);
-			const tz = bpmPoints[facility][i][0].z * (1+(data.Hor? data.Hor[j]*0.02*bpmFactor*params.bpmZoomH: 0));
+			const tz = bpmPoints[facility][i][0].z - Math.sin(bpmPoints[facility][i][1])*(data.Hor? data.Hor[j]*1000*bpmFactor*params.bpmZoomH: 0);
 			if (!isNaN(tx) && !isNaN(ty) && !isNaN(tz)) bpmCurve.push(new THREE.Vector3(tx, ty, tz));
 		}
-		console.log(facility, bpmCurve);
+		// console.log(facility, bpmCurve);
 		return new THREE.CatmullRomCurve3(bpmCurve);
 	}
 	let bpmInited = false;
@@ -621,12 +622,12 @@
 				pushComponent(facility, i, m, tang, direction, y);
 				if (flattice[i].components[m].type=='bpm' && (document.location.search.indexOf('&bpm')>-1 || document.location.search.indexOf('?bpm')>-1) && lattice[facility].bpm) {
 					if (lattice[facility].bpm.skip && (lattice[facility].bpm.skip.indexOf(flattice[i].components[m].name)>-1)) {bpmSkip[facility].push(bpmPoints[facility].length);}
-					else bpmPoints[facility].push([position.clone(), tang, direction]);
+					else bpmPoints[facility].push([position.clone(), Math.atan(tang), direction]);
 				}
 			}
 			envelopeAdd(flattice, i, j, facility, direction);
 		}
-		console.log('compBuffer', compBuffer);
+		// console.log('compBuffer', compBuffer);
 		if (real) for (let i in conf.real) {loadreal(i);}
 
 		// console.log('vlvs', vlvs); console.log('facilities', facilities, 'names', window.names.join(';'));
@@ -685,7 +686,7 @@
 		outlinePass.selectedObjects = [];
 		for (let facility in scene.children) {
 			for (let comp in scene.children[facility].children) {
-				if (scene.children[facility].children[magnet].name==name) {
+				if (scene.children[facility].children[comp].name==name) {
 					const dist = scene.children[facility].name=='servicearea'? 7000: 1000;
 					facilities[scene.children[facility].name].visible = true; // make facility visible
 					// transverse lil menu and check facility checkbox
@@ -704,23 +705,23 @@
 						}
 					}
 					found = true;
-					const selectedObject = scene.children[facility].children[magnet];
+					const selectedObject = scene.children[facility].children[comp];
 					if (outline) {outlinePass.selectedObjects = [selectedObject]; addSelectedObject(selectedObject);}
 					renderer.render(scene, camera);
 					x1 = camera.position.x;
 					y1 = camera.position.y;
 					z1 = camera.position.z;
-					x2 = scene.children[facility].children[magnet].position.x+dist*Math.sign(scene.children[facility].children[magnet].position.x);
-					y2 = scene.children[facility].children[magnet].position.y+dist*Math.sign(scene.children[facility].children[magnet].position.y);
-					z2 = scene.children[facility].children[magnet].position.z+dist*Math.sign(scene.children[facility].children[magnet].position.z);
-					console.log("findComponent()", name, selectedObject, x1, x2, scene.children[facility].children[magnet].position, scene.children[facility]);
+					x2 = scene.children[facility].children[comp].position.x+dist*Math.sign(scene.children[facility].children[comp].position.x);
+					y2 = scene.children[facility].children[comp].position.y+dist*Math.sign(scene.children[facility].children[comp].position.y);
+					z2 = scene.children[facility].children[comp].position.z+dist*Math.sign(scene.children[facility].children[comp].position.z);
+					console.log("findComponent()", name, selectedObject, x1, x2, scene.children[facility].children[comp].position, scene.children[facility]);
 					const lookat = (new THREE.Vector3(0, 0, -20000)).applyQuaternion(camera.quaternion).add(camera.position); // https://stackoverflow.com/questions/27957645/three-js-find-the-current-lookat-of-a-camera
 					rx1 = lookat.x;
 					ry1 = lookat.y;
 					rz1 = lookat.z;
-					rx2 = scene.children[facility].children[magnet].position.x;
-					ry2 = scene.children[facility].children[magnet].position.y;
-					rz2 = scene.children[facility].children[magnet].position.z;
+					rx2 = scene.children[facility].children[comp].position.x;
+					ry2 = scene.children[facility].children[comp].position.y;
+					rz2 = scene.children[facility].children[comp].position.z;
 					if (debugcamera) {$('#x').val(x1); $('#y').val(y1); $('#z').val(z1); $('#cx').val(rx1); $('#cy').val(ry1); $('#cz').val(rz1);}
 					cameraStep = numSteps;
 					updateCamera();
@@ -1007,6 +1008,36 @@ window.setFar = setFar;
 		outlinePass.hiddenEdgeColor.set('#400050');
 		composer.addPass(outlinePass);
 		console.log('scene', scene, 'controls', controls, 'camera', camera);
+		if (debugcamera) {
+				// axis grid
+				const redmaterial = new THREE.LineBasicMaterial({ color: 0xff0000 });
+				const redgeometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(-3000, 0, 0), new THREE.Vector3(3000, 0, 0)]);
+				const redline = new THREE.Line( redgeometry, redmaterial );
+				scene.add(redline);
+				for (let k=-30; k<=30; k++) {
+					const c = redline.clone();
+					c.position.set(0, k*100, 0);
+					scene.add(c);
+				}
+				const greenmaterial = new THREE.LineBasicMaterial({ color: 0x00ff00 });
+				const greengeometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0, -3000, 0), new THREE.Vector3(0, 3000, 0)]);
+				const greenline = new THREE.Line( greengeometry, greenmaterial );
+				scene.add(greenline);
+				for (let k=-30; k<=30; k++) {
+					const c = greenline.clone();
+					c.position.set(0, 0, k*100);
+					scene.add(c);
+				}
+				const bluematerial = new THREE.LineBasicMaterial({ color: 0x0000ff });
+				const bluegeometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0, 0, -3000), new THREE.Vector3(0, 0, 3000)]);
+				const blueline = new THREE.Line( bluegeometry, bluematerial );
+				scene.add(blueline);
+				for (let k=-30; k<=30; k++) {
+					const c = blueline.clone();
+					c.position.set(k*100, 0, 0);
+					scene.add(c);
+				}
+		}
 	}
 	function onWindowResize() {
 		camera.aspect = window.innerWidth / window.innerHeight;