 
     if Number.isNaN(m) or m <= 0
       throw new Error "Parameter M is bad"
-    if 1/n + 1/m >= 1
-      throw new Error "Tessellation {#{n}; #{m}} is not hyperbolic."
-
+    #if 1/n + 1/m <= 1/2
+    if 2*(n+m) >= n*m
+      throw new Error "Tessellation {#{n}; #{m}} is not hyperbolic and not supported."
     setGridImpl n, m
-
     doReset()
-    
   catch e
-    alert "Failed to set grid parameters: #{e}"
+    alert ""+e
 
 setGridImpl = (n, m)->
-  tessellation = new Tessellation n,m
-  console.log "Running knuth-bendix algorithm for #{n}, #{m}...."
+  tessellation = new Tessellation n, m
+  console.log "Running knuth-bendix algorithm for {#{n}, #{m}}...."
   rewriteRuleset = knuthBendix vdRule tessellation.group.n, tessellation.group.m
   console.log "Finished"
   appendRewrite = makeAppendRewrite rewriteRuleset
-
   getNeighbors = mooreNeighborhood tessellation.group.n, tessellation.group.m, appendRewrite
   xytFromCell = xyt2cell tessellation.group, appendRewrite
 
-  transitionFunc = parseTransitionFunction "B 3 S 2 3", tessellation.group.n, tessellation.group.m
+  transitionFunc = parseTransitionFunction transitionFunc.toString(), tessellation.group.n, tessellation.group.m
   visibleCells = visibleNeighborhood tessellation, appendRewrite, minVisibleSize
 ###
 #
 ###
-moveView = (dx, dy) ->
+modifyViewMatrix = (m) ->
+  tfm = M.mul m, tfm
+  redraw()
+
+translationMatrix = (dx, dy) ->
+  #Formulae obtained with Maxima,
+  # as combination of (inverse rotate) * (shift by x) * (rotate)
+  # distance is acosh( sqrt( dx^2 + dy^2 + 1 ))
   r2 = dx*dx+dy*dy
   dt = Math.sqrt(r2+1)
   k = (dt-1)/r2

  dx = x-cx
  dy = y-cy
  if dx*dx + dy*dy <= r*r*0.8*0.8
    dragHandler = new MovingDragger x, y
  else
    dragHandler = new RotatingDragger x, y

doCanvasMouseMove = (e) ->
  if dragHandler isnt null

            
doSetRule =  ->
  try
    transitionFunc = parseTransitionFunction E('rule-entry').value, tessellation.group.n, tessellation.group.m
  catch e
    alert "Failed to parse function: #{e}"

