github.com/janelia-flyem/dvid@v1.0.0/datatype/labelmap/mutate_test.go (about)

     1  package labelmap
     2  
     3  import (
     4  	"bytes"
     5  	"compress/gzip"
     6  	"encoding/binary"
     7  	"encoding/json"
     8  	"fmt"
     9  	"io"
    10  	"math/rand"
    11  	"net/http"
    12  	"reflect"
    13  	"runtime"
    14  	"strings"
    15  	"sync"
    16  	"testing"
    17  	"time"
    18  
    19  	pb "google.golang.org/protobuf/proto"
    20  
    21  	"github.com/janelia-flyem/dvid/datastore"
    22  	"github.com/janelia-flyem/dvid/datatype/common/downres"
    23  	"github.com/janelia-flyem/dvid/datatype/common/labels"
    24  	"github.com/janelia-flyem/dvid/datatype/common/proto"
    25  	"github.com/janelia-flyem/dvid/dvid"
    26  	"github.com/janelia-flyem/dvid/server"
    27  
    28  	lz4 "github.com/janelia-flyem/go/golz4-updated"
    29  )
    30  
    31  func checkSparsevolsCoarse(t *testing.T, encoding []byte) {
    32  	length := len(encoding)
    33  	var i int
    34  	for label := uint64(1); label <= 3; label++ {
    35  		if i+28 >= length {
    36  			t.Fatalf("Expected label %d but only %d bytes remain in encoding\n", label, len(encoding[i:]))
    37  		}
    38  		gotLabel := binary.LittleEndian.Uint64(encoding[i : i+8])
    39  		if gotLabel != label {
    40  			t.Errorf("Expected label %d, got label %d in returned coarse sparsevols\n", label, gotLabel)
    41  		}
    42  		i += 8
    43  		var spans dvid.Spans
    44  		if err := spans.UnmarshalBinary(encoding[i:]); err != nil {
    45  			t.Errorf("Error in decoding coarse sparse volume: %v\n", err)
    46  			return
    47  		}
    48  		i += 4 + len(spans)*16
    49  		b := bodies[label-1]
    50  		if !reflect.DeepEqual(spans, b.blockSpans) {
    51  			_, fn, line, _ := runtime.Caller(1)
    52  			t.Errorf("Expected coarse spans for label %d:\n%s\nGot spans [%s:%d]:\n%s\n", b.label, b.blockSpans, fn, line, spans)
    53  		}
    54  	}
    55  }
    56  
    57  func checkNoSparsevol(t *testing.T, uuid dvid.UUID, label uint64) {
    58  	headReq := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, label)
    59  	resp := server.TestHTTPResponse(t, "HEAD", headReq, nil)
    60  	if resp.Code != http.StatusNoContent {
    61  		_, fn, line, _ := runtime.Caller(1)
    62  		t.Fatalf("HEAD on %s did not return 204 (No Content).  Status = %d [%s:%d]\n", headReq, resp.Code, fn, line)
    63  	}
    64  }
    65  
    66  func checkSparsevolAPIs(t *testing.T, uuid dvid.UUID) {
    67  	for _, label := range []uint64{1, 2, 3, 4} {
    68  		bodies[label-1].checkSparsevolAPIs(t, uuid, label)
    69  	}
    70  
    71  	reqStr := fmt.Sprintf("%snode/%s/labels/sparsevols-coarse/1/3", server.WebAPIPath, uuid)
    72  	encoding := server.TestHTTP(t, "GET", reqStr, nil)
    73  	checkSparsevolsCoarse(t, encoding)
    74  
    75  	reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol-size/1", server.WebAPIPath, uuid)
    76  	sizeResp := server.TestHTTP(t, "GET", reqStr, nil)
    77  	if string(sizeResp) != `{"voxels": 32000, "numblocks": 3, "minvoxel": [0, 32, 0], "maxvoxel": [31, 63, 95]}` {
    78  		t.Errorf("bad response to sparsevol-size endpoint: %s\n", string(sizeResp))
    79  	}
    80  
    81  	// Make sure non-existent bodies return proper HEAD responses.
    82  	headReq := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 10)
    83  	resp := server.TestHTTPResponse(t, "HEAD", headReq, nil)
    84  	if resp.Code != http.StatusNoContent {
    85  		t.Errorf("HEAD on %s did not return 204 (No Content).  Status = %d\n", headReq, resp.Code)
    86  	}
    87  }
    88  
    89  func ingestIndex(t *testing.T, uuid dvid.UUID, idx *labels.Index) {
    90  	serialization, err := pb.Marshal(idx)
    91  	if err != nil {
    92  		t.Fatal(err)
    93  	}
    94  	ingestReq := fmt.Sprintf("%snode/%s/labels/index/%d", server.WebAPIPath, uuid, idx.Label)
    95  	server.TestHTTP(t, "POST", ingestReq, bytes.NewBuffer(serialization))
    96  }
    97  
    98  type testBody struct {
    99  	label        uint64
   100  	offset, size dvid.Point3d // these are just to give ROI of voxelSpans
   101  	blockSpans   dvid.Spans
   102  	voxelSpans   dvid.Spans // in DVID coordinates, not relative coordinates
   103  }
   104  
   105  var emptyBody = testBody{
   106  	label:      0,
   107  	offset:     dvid.Point3d{},
   108  	size:       dvid.Point3d{},
   109  	blockSpans: dvid.Spans{},
   110  	voxelSpans: dvid.Spans{},
   111  }
   112  
   113  func (b testBody) add(b2 testBody) (merged testBody) {
   114  	blockSpans := make(dvid.Spans, len(b.blockSpans)+len(b2.blockSpans))
   115  	i := 0
   116  	for _, span := range b.blockSpans {
   117  		blockSpans[i] = span
   118  		i++
   119  	}
   120  	for _, span := range b2.blockSpans {
   121  		blockSpans[i] = span
   122  		i++
   123  	}
   124  
   125  	voxelSpans := make(dvid.Spans, len(b.voxelSpans)+len(b2.voxelSpans))
   126  	i = 0
   127  	for _, span := range b.voxelSpans {
   128  		voxelSpans[i] = span
   129  		i++
   130  	}
   131  	for _, span := range b2.voxelSpans {
   132  		voxelSpans[i] = span
   133  		i++
   134  	}
   135  	offset, size := voxelSpans.Extents()
   136  	merged = testBody{
   137  		label:      b.label,
   138  		offset:     offset,
   139  		size:       size,
   140  		blockSpans: blockSpans.Normalize(),
   141  		voxelSpans: voxelSpans.Normalize(),
   142  	}
   143  	return
   144  }
   145  
   146  func (b testBody) checkSparsevolAPIs(t *testing.T, uuid dvid.UUID, label uint64) {
   147  	// Check coarse sparsevol
   148  	reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol-coarse/%d", server.WebAPIPath, uuid, label)
   149  	encoding := server.TestHTTP(t, "GET", reqStr, nil)
   150  	b.checkCoarse(t, encoding)
   151  
   152  	// Check fast HEAD requests
   153  	reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, label)
   154  	resp := server.TestHTTPResponse(t, "HEAD", reqStr, nil)
   155  	if resp.Code != http.StatusOK {
   156  		t.Errorf("HEAD on %s did not return OK.  Status = %d\n", reqStr, resp.Code)
   157  	}
   158  
   159  	// Check full sparse volumes
   160  	encoding = server.TestHTTP(t, "GET", reqStr, nil)
   161  	lenEncoding := len(encoding)
   162  	b.checkSparseVol(t, encoding, dvid.OptionalBounds{})
   163  
   164  	// check one downres
   165  	encoding = server.TestHTTP(t, "GET", reqStr+"?scale=1", nil)
   166  	b.checkScaledSparseVol(t, encoding, 1, dvid.OptionalBounds{})
   167  
   168  	// check two downres
   169  	encoding = server.TestHTTP(t, "GET", reqStr+"?scale=2", nil)
   170  	b.checkScaledSparseVol(t, encoding, 2, dvid.OptionalBounds{})
   171  
   172  	// Check with lz4 compression
   173  	uncompressed := make([]byte, lenEncoding)
   174  	compressed := server.TestHTTP(t, "GET", reqStr+"?compression=lz4", nil)
   175  	if err := lz4.Uncompress(compressed, uncompressed); err != nil {
   176  		t.Fatalf("error uncompressing lz4 for sparsevol %d GET: %v\n", label, err)
   177  	}
   178  	b.checkSparseVol(t, uncompressed, dvid.OptionalBounds{})
   179  
   180  	// Check with gzip compression
   181  	compressed = server.TestHTTP(t, "GET", reqStr+"?compression=gzip", nil)
   182  	buf := bytes.NewBuffer(compressed)
   183  	var err error
   184  	r, err := gzip.NewReader(buf)
   185  	if err != nil {
   186  		t.Fatalf("error creating gzip reader: %v\n", err)
   187  	}
   188  	var buffer bytes.Buffer
   189  	_, err = io.Copy(&buffer, r)
   190  	if err != nil {
   191  		t.Fatalf("error copying gzip data: %v\n", err)
   192  	}
   193  	err = r.Close()
   194  	if err != nil {
   195  		t.Fatalf("error closing gzip: %v\n", err)
   196  	}
   197  	encoding = buffer.Bytes()
   198  	b.checkSparseVol(t, encoding, dvid.OptionalBounds{})
   199  
   200  	// Check Y/Z restriction
   201  	miny := int32(30)
   202  	maxy := int32(50)
   203  	minz := int32(20)
   204  	maxz := int32(40)
   205  	for scale := uint8(0); scale < 3; scale++ {
   206  		reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d?scale=%d&miny=%d&maxy=%d&minz=%d&maxz=%d",
   207  			server.WebAPIPath, uuid, label, scale, miny, maxy, minz, maxz)
   208  		if label != 4 {
   209  			encoding = server.TestHTTP(t, "GET", reqStr, nil)
   210  			var bound dvid.OptionalBounds
   211  			bound.SetMinY(miny)
   212  			bound.SetMaxY(maxy)
   213  			bound.SetMinZ(minz)
   214  			bound.SetMaxZ(maxz)
   215  			b.checkScaledSparseVol(t, encoding, scale, bound)
   216  		} else {
   217  			encoding = server.TestHTTP(t, "GET", reqStr, nil) // Should be 200 with no bytes
   218  			if len(encoding) != 0 {
   219  				t.Fatalf("expected 0 bytes, got %d for %s\n", len(encoding), reqStr)
   220  			}
   221  		}
   222  		miny >>= 1
   223  		maxy >>= 1
   224  		minz >>= 1
   225  		maxz >>= 1
   226  	}
   227  
   228  	// Check X restriction
   229  	minx := int32(20)
   230  	maxx := int32(47)
   231  	reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d?minx=%d&maxx=%d", server.WebAPIPath, uuid, label, minx, maxx)
   232  	if label != 4 {
   233  		encoding = server.TestHTTP(t, "GET", reqStr, nil)
   234  		checkSpans(t, encoding, minx, maxx)
   235  	} else {
   236  		server.TestBadHTTP(t, "GET", reqStr, nil) // Should be not found
   237  	}
   238  }
   239  
   240  func (b testBody) getIndex(t *testing.T) *labels.Index {
   241  	idx := new(labels.Index)
   242  	idx.Label = b.label
   243  	idx.Blocks = make(map[uint64]*proto.SVCount)
   244  	voxelCounts := b.voxelSpans.VoxelCounts(dvid.Point3d{32, 32, 32})
   245  	for izyxStr, count := range voxelCounts {
   246  		zyx, err := labels.IZYXStringToBlockIndex(izyxStr)
   247  		if err != nil {
   248  			t.Fatal(err)
   249  		}
   250  		svc := new(proto.SVCount)
   251  		svc.Counts = map[uint64]uint32{b.label: count}
   252  		idx.Blocks[zyx] = svc
   253  	}
   254  	return idx
   255  }
   256  
   257  func (b testBody) postIndex(t *testing.T, uuid dvid.UUID) {
   258  	idx := b.getIndex(t)
   259  	serialization, err := pb.Marshal(idx)
   260  	if err != nil {
   261  		t.Fatal(err)
   262  	}
   263  	indexReq := fmt.Sprintf("%snode/%s/labels/index/%d", server.WebAPIPath, uuid, b.label)
   264  	server.TestHTTP(t, "POST", indexReq, bytes.NewBuffer(serialization))
   265  }
   266  
   267  // Makes sure the coarse sparse volume encoding matches the body.
   268  func (b testBody) checkCoarse(t *testing.T, encoding []byte) {
   269  	// Get to the  # spans and RLE in encoding
   270  	spansEncoding := encoding[8:]
   271  	var spans dvid.Spans
   272  	if err := spans.UnmarshalBinary(spansEncoding); err != nil {
   273  		t.Errorf("Error in decoding coarse sparse volume: %v\n", err)
   274  		return
   275  	}
   276  
   277  	// Check those spans match the body voxels.
   278  	if !reflect.DeepEqual(spans, b.blockSpans) {
   279  		_, fn, line, _ := runtime.Caller(1)
   280  		t.Errorf("Expected coarse spans for label %d:\n%s\nGot spans [%s:%d]:\n%s\n", b.label, b.blockSpans, fn, line, spans)
   281  	}
   282  }
   283  
   284  // Makes sure the sparse volume encoding matches the actual body voxels.
   285  func (b testBody) checkSparseVol(t *testing.T, encoding []byte, bounds dvid.OptionalBounds) {
   286  	if len(encoding) < 12 {
   287  		t.Fatalf("Bad encoded sparsevol received.  Only %d bytes\n", len(encoding))
   288  	}
   289  
   290  	// Get to the  # spans and RLE in encoding
   291  	spansEncoding := encoding[8:]
   292  	var spans dvid.Spans
   293  	if err := spans.UnmarshalBinary(spansEncoding); err != nil {
   294  		t.Fatalf("Error in decoding sparse volume: %v\n", err)
   295  	}
   296  
   297  	// Create potentially bounded spans
   298  	expected := dvid.Spans{}
   299  	if bounds.IsSet() {
   300  		for _, span := range b.voxelSpans {
   301  			if bounds.OutsideY(span[1]) || bounds.OutsideZ(span[0]) {
   302  				continue
   303  			}
   304  			expected = append(expected, span)
   305  		}
   306  	} else {
   307  		expected = b.voxelSpans
   308  	}
   309  
   310  	// Check those spans match the body voxels.
   311  	gotNorm := spans.Normalize()
   312  	expectNorm := expected.Normalize()
   313  	if !reflect.DeepEqual(gotNorm, expectNorm) {
   314  		for _, got := range gotNorm {
   315  			bad := true
   316  			for _, expect := range expectNorm {
   317  				if reflect.DeepEqual(got, expect) {
   318  					bad = false
   319  				}
   320  			}
   321  			if bad {
   322  				fmt.Printf("Got unexpected span: %s\n", got)
   323  			}
   324  		}
   325  		for _, expect := range expectNorm {
   326  			bad := true
   327  			for _, got := range gotNorm {
   328  				if reflect.DeepEqual(got, expect) {
   329  					bad = false
   330  				}
   331  			}
   332  			if bad {
   333  				fmt.Printf("Never got expected span: %s\n", expect)
   334  			}
   335  		}
   336  		_, fn, line, _ := runtime.Caller(1)
   337  		t.Fatalf("Expected %d fine spans for label %d [%s:%d]:\n%s\nGot %d spans:\n%s\nAfter Norm:%s\n", len(expectNorm), b.label, fn, line, expectNorm, len(spans), spans, gotNorm)
   338  	}
   339  }
   340  
   341  // Makes sure the sparse volume encoding matches a downres of actual body voxels.
   342  func (b testBody) checkScaledSparseVol(t *testing.T, encoding []byte, scale uint8, bounds dvid.OptionalBounds) {
   343  	if scale == 0 {
   344  		b.checkSparseVol(t, encoding, bounds)
   345  		return
   346  	}
   347  	// Make down-res volume of body
   348  	vol := newTestVolume(128, 128, 128)
   349  	vol.addBody(b, 1)
   350  	vol.downres(scale)
   351  
   352  	if len(encoding) < 12 {
   353  		if vol.containsLabel(1) {
   354  			t.Fatalf("Bad encoded sparsevol received at scale %d.  Only %d bytes when label 1 found\n", scale, len(encoding))
   355  		}
   356  		return
   357  	}
   358  
   359  	// Get to the  # spans and RLE in encoding
   360  	spansEncoding := encoding[8:]
   361  	var spans dvid.Spans
   362  	if err := spans.UnmarshalBinary(spansEncoding); err != nil {
   363  		t.Fatalf("Error in decoding sparse volume: %v\n", err)
   364  	}
   365  
   366  	// Check those spans are within the body voxels.
   367  	for _, span := range spans {
   368  		z, y, x0, x1 := span.Unpack()
   369  		if x1 >= vol.size[0] || y >= vol.size[1] || z >= vol.size[2] {
   370  			t.Fatalf("Span %s is outside bound of scale %d volume of size %s\n", span, scale, vol.size)
   371  		}
   372  		pos := z*vol.size[0]*vol.size[1] + y*vol.size[0] + x0
   373  		for x := x0; x <= x1; x++ {
   374  			label := binary.LittleEndian.Uint64(vol.data[pos*8 : pos*8+8])
   375  			if label != 1 {
   376  				t.Fatalf("Received body at scale %d has voxel at (%d,%d,%d) but that voxel is label %d, not in body %d\n", scale, x, y, z, label, b.label)
   377  				return
   378  			}
   379  			pos++
   380  		}
   381  	}
   382  }
   383  
   384  // checks use of binary blocks format
   385  func (b testBody) checkBinarySparseVol(t *testing.T, r io.Reader) {
   386  	binBlocks, err := labels.ReceiveBinaryBlocks(r)
   387  	if err != nil {
   388  		_, fn, line, _ := runtime.Caller(1)
   389  		t.Fatalf("Error trying to decode binary blocks for body %d [%s:%d]: %v\n", b.label, fn, line, err)
   390  	}
   391  
   392  	expected := newTestVolume(128, 128, 128)
   393  	expected.addBody(b, 1)
   394  
   395  	got := newTestVolume(128, 128, 128)
   396  	got.addBlocks(t, binBlocks, 1)
   397  
   398  	if err := expected.equals(got); err != nil {
   399  		_, fn, line, _ := runtime.Caller(1)
   400  		t.Fatalf("error getting binary blocks for body %d [%s:%d]: %v\n", b.label, fn, line, err)
   401  	}
   402  }
   403  
   404  // checks use of binary blocks format + scaling
   405  func (b testBody) checkScaledBinarySparseVol(t *testing.T, r io.Reader, scale uint8) {
   406  	binBlocks, err := labels.ReceiveBinaryBlocks(r)
   407  	if err != nil {
   408  		t.Fatalf("Error trying to decode binary blocks for body %d: %v\n", b.label, err)
   409  	}
   410  
   411  	expected := newTestVolume(128, 128, 128)
   412  	expected.addBody(b, 1)
   413  	expected.downres(scale)
   414  
   415  	n := int32(128 >> scale)
   416  	got := newTestVolume(n, n, n)
   417  	got.addBlocks(t, binBlocks, 1)
   418  
   419  	if err := expected.equals(got); err != nil {
   420  		_, fn, line, _ := runtime.Caller(1)
   421  		t.Fatalf("error getting binary blocks for body %d, scale %d [%s:%d]: %v\n", b.label, scale, fn, line, err)
   422  	}
   423  }
   424  
   425  // Sees if the given block span has any of this test body label in it.
   426  func (b testBody) isDeleted(t *testing.T, encoding []byte, bspan dvid.Span) bool {
   427  	// Get to the  # spans and RLE in encoding
   428  	spansEncoding := encoding[8:]
   429  	var spans dvid.Spans
   430  	if err := spans.UnmarshalBinary(spansEncoding); err != nil {
   431  		t.Fatalf("Error in decoding sparse volume: %v\n", err)
   432  		return false
   433  	}
   434  
   435  	// Iterate true spans to see if any are in the blocks given.
   436  	for _, span := range spans {
   437  		bx0 := span[2] / 32
   438  		bx1 := span[3] / 32
   439  		by := span[1] / 32
   440  		bz := span[0] / 32
   441  
   442  		withinX := (bx0 >= bspan[2] && bx0 <= bspan[3]) || (bx1 >= bspan[2] && bx1 <= bspan[3])
   443  		if bz == bspan[0] && by == bspan[1] && withinX {
   444  			return false
   445  		}
   446  	}
   447  	return true
   448  }
   449  
   450  func checkSpans(t *testing.T, encoding []byte, minx, maxx int32) {
   451  	// Get to the  # spans and RLE in encoding
   452  	spansEncoding := encoding[8:]
   453  	var spans dvid.Spans
   454  	if err := spans.UnmarshalBinary(spansEncoding); err != nil {
   455  		t.Errorf("Error in decoding coarse sparse volume: %v\n", err)
   456  		return
   457  	}
   458  	for _, span := range spans {
   459  		if span[2] < minx {
   460  			t.Errorf("Found span violating min x %d: %s\n", minx, span)
   461  			return
   462  		}
   463  		if span[3] > maxx {
   464  			t.Errorf("Found span violating max x %d: %s\n", maxx, span)
   465  		}
   466  	}
   467  }
   468  
   469  // Sets voxels in body to given label.
   470  func (v *testVolume) addBody(body testBody, label uint64) {
   471  	nx := v.size[0]
   472  	nxy := nx * v.size[1]
   473  	for _, span := range body.voxelSpans {
   474  		z, y, x0, x1 := span.Unpack()
   475  		p := (z*nxy + y*nx) * 8
   476  		for i := p + x0*8; i <= p+x1*8; i += 8 {
   477  			binary.LittleEndian.PutUint64(v.data[i:i+8], label)
   478  		}
   479  	}
   480  }
   481  
   482  // Returns true if all voxels in test volume for given body has label.
   483  func (v *testVolume) isLabel(label uint64, body *testBody) bool {
   484  	nx := v.size[0]
   485  	nxy := nx * v.size[1]
   486  	for _, span := range body.voxelSpans {
   487  		z, y, x0, x1 := span.Unpack()
   488  		p := (z*nxy + y*nx) * 8
   489  		for i := p + x0*8; i <= p+x1*8; i += 8 {
   490  			curLabel := binary.LittleEndian.Uint64(v.data[i : i+8])
   491  			if curLabel != label {
   492  				return false
   493  			}
   494  		}
   495  	}
   496  	return true
   497  }
   498  
   499  // Returns true if any voxel in test volume has given label.
   500  func (v *testVolume) hasLabel(label uint64, body *testBody) bool {
   501  	nx := v.size[0]
   502  	nxy := nx * v.size[1]
   503  	for _, span := range body.voxelSpans {
   504  		z, y, x0, x1 := span.Unpack()
   505  		p := (z*nxy + y*nx) * 8
   506  		for i := p + x0*8; i <= p+x1*8; i += 8 {
   507  			curLabel := binary.LittleEndian.Uint64(v.data[i : i+8])
   508  			if curLabel == label {
   509  				return true
   510  			}
   511  		}
   512  	}
   513  	return false
   514  }
   515  
   516  func createLabelTestVolume(t *testing.T, uuid dvid.UUID, name string) *testVolume {
   517  	// Setup test label blocks that are non-intersecting.
   518  	volume := newTestVolume(128, 128, 128)
   519  	volume.addBody(body1, 1)
   520  	volume.addBody(body2, 2)
   521  	volume.addBody(body3, 3)
   522  	volume.addBody(body4, 4)
   523  
   524  	// Send data over HTTP to populate a data instance
   525  	volume.put(t, uuid, name)
   526  	return volume
   527  }
   528  
   529  func createLabelTest2Volume(t *testing.T, uuid dvid.UUID, name string) *testVolume {
   530  	// Setup test label blocks that are non-intersecting.
   531  	volume := newTestVolume(128, 128, 128)
   532  	volume.addBody(body6, 6)
   533  	volume.addBody(body7, 7)
   534  
   535  	// Send data over HTTP to populate a data instance using mutable flag
   536  	volume.putMutable(t, uuid, name)
   537  	return volume
   538  }
   539  
   540  func TestSparseVolumes(t *testing.T) {
   541  	if err := server.OpenTest(); err != nil {
   542  		t.Fatalf("can't open test server: %v\n", err)
   543  	}
   544  	defer server.CloseTest()
   545  
   546  	// Create testbed volume and data instances
   547  	uuid, _ := initTestRepo()
   548  	var config dvid.Config
   549  	config.Set("MaxDownresLevel", "2")
   550  	config.Set("BlockSize", "32,32,32") // Previous test data was on 32^3 blocks
   551  	server.CreateTestInstance(t, uuid, "labelmap", "labels", config)
   552  	labelVol := createLabelTestVolume(t, uuid, "labels")
   553  
   554  	gotVol := newTestVolume(128, 128, 128)
   555  	gotVol.get(t, uuid, "labels", false)
   556  	if err := gotVol.equals(labelVol); err != nil {
   557  		t.Fatalf("Couldn't get back simple 128x128x128 label volume that was written: %v\n", err)
   558  	}
   559  
   560  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
   561  		t.Fatalf("Error blocking on labels updating: %v\n", err)
   562  	}
   563  	if err := downres.BlockOnUpdating(uuid, "labels"); err != nil {
   564  		t.Fatalf("Error blocking on update for labels: %v\n", err)
   565  	}
   566  	time.Sleep(1 * time.Second)
   567  
   568  	dataservice, err := datastore.GetDataByUUIDName(uuid, "labels")
   569  	if err != nil {
   570  		t.Fatalf("couldn't get labels data instance from datastore: %v\n", err)
   571  	}
   572  	labels, ok := dataservice.(*Data)
   573  	if !ok {
   574  		t.Fatalf("Returned data instance for 'labels' instance was not labelmap.Data!\n")
   575  	}
   576  	if labels.MaxRepoLabel != 4 {
   577  		t.Errorf("Expected max repo label to be 4, got %d\n", labels.MaxRepoLabel)
   578  	}
   579  	v, err := datastore.VersionFromUUID(uuid)
   580  	if err != nil {
   581  		t.Errorf("couldn't get version id from uuid %s: %v\n", uuid, err)
   582  	}
   583  	if len(labels.MaxLabel) != 1 || labels.MaxLabel[v] != 4 {
   584  		t.Errorf("bad MaxLabels: %v\n", labels.MaxLabel)
   585  	}
   586  	maxLabelResp := server.TestHTTP(t, "GET", fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid), nil)
   587  	if string(maxLabelResp) != `{"maxlabel": 4}` {
   588  		t.Errorf("bad response to maxlabel endpoint: %s\n", string(maxLabelResp))
   589  	}
   590  
   591  	server.TestHTTP(t, "POST", fmt.Sprintf("%snode/%s/labels/maxlabel/8", server.WebAPIPath, uuid), nil)
   592  	maxLabelResp = server.TestHTTP(t, "GET", fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid), nil)
   593  	if string(maxLabelResp) != `{"maxlabel": 8}` {
   594  		t.Errorf("bad response to maxlabel endpoint: %s\n", string(maxLabelResp))
   595  	}
   596  
   597  	nextLabelResp := server.TestHTTP(t, "GET", fmt.Sprintf("%snode/%s/labels/nextlabel", server.WebAPIPath, uuid), nil)
   598  	if string(nextLabelResp) != `{"nextlabel": 9}` {
   599  		t.Errorf("bad response to nextlabel endpoint: %s\n", string(nextLabelResp))
   600  	}
   601  	nextLabelResp = server.TestHTTP(t, "POST", fmt.Sprintf("%snode/%s/labels/nextlabel/5", server.WebAPIPath, uuid), nil)
   602  	if string(nextLabelResp) != `{"start": 9, "end": 13}` {
   603  		t.Errorf("bad response to POST /nextlabel: %s\n", string(maxLabelResp))
   604  	}
   605  	maxLabelResp = server.TestHTTP(t, "GET", fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid), nil)
   606  	if string(maxLabelResp) != `{"maxlabel": 13}` {
   607  		t.Errorf("bad response to maxlabel endpoint: %s\n", string(maxLabelResp))
   608  	}
   609  	nextLabelResp = server.TestHTTP(t, "GET", fmt.Sprintf("%snode/%s/labels/nextlabel", server.WebAPIPath, uuid), nil)
   610  	if string(nextLabelResp) != `{"nextlabel": 14}` {
   611  		t.Errorf("bad response to nextlabel endpoint: %s\n", string(nextLabelResp))
   612  	}
   613  
   614  	badReqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/0", server.WebAPIPath, uuid)
   615  	server.TestBadHTTP(t, "GET", badReqStr, nil)
   616  
   617  	checkSparsevolAPIs(t, uuid)
   618  }
   619  
   620  func Test16x16x16SparseVolumes(t *testing.T) {
   621  	if err := server.OpenTest(); err != nil {
   622  		t.Fatalf("can't open test server: %v\n", err)
   623  	}
   624  	defer server.CloseTest()
   625  
   626  	// Create testbed volume and data instances
   627  	uuid, _ := initTestRepo()
   628  	var config dvid.Config
   629  	config.Set("BlockSize", "16,16,16") // Since RLE encoding spans blocks now, should work for smaller block size.
   630  	server.CreateTestInstance(t, uuid, "labelmap", "labels", config)
   631  	labelVol := createLabelTestVolume(t, uuid, "labels")
   632  
   633  	gotVol := newTestVolume(128, 128, 128)
   634  	gotVol.get(t, uuid, "labels", false)
   635  	if err := gotVol.equals(labelVol); err != nil {
   636  		t.Fatalf("Couldn't get back simple 128x128x128 label volume that was written: %v\n", err)
   637  	}
   638  
   639  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
   640  		t.Fatalf("Error blocking on labels updating: %v\n", err)
   641  	}
   642  	time.Sleep(1 * time.Second)
   643  
   644  	for _, label := range []uint64{1, 2, 3, 4} {
   645  		// Check fast HEAD requests
   646  		reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, label)
   647  		resp := server.TestHTTPResponse(t, "HEAD", reqStr, nil)
   648  		if resp.Code != http.StatusOK {
   649  			t.Errorf("HEAD on %s did not return OK.  Status = %d\n", reqStr, resp.Code)
   650  		}
   651  
   652  		// Check full sparse volumes
   653  		encoding := server.TestHTTP(t, "GET", reqStr, nil)
   654  		fmt.Printf("Got %d bytes back from %s\n", len(encoding), reqStr)
   655  		bodies[label-1].checkSparseVol(t, encoding, dvid.OptionalBounds{})
   656  
   657  		// Check with lz4 compression
   658  		compressed := server.TestHTTP(t, "GET", reqStr+"?compression=lz4", nil)
   659  		if err := lz4.Uncompress(compressed, encoding); err != nil {
   660  			t.Fatalf("error uncompressing lz4: %v\n", err)
   661  		}
   662  		bodies[label-1].checkSparseVol(t, encoding, dvid.OptionalBounds{})
   663  
   664  		// Check with gzip compression
   665  		compressed = server.TestHTTP(t, "GET", reqStr+"?compression=gzip", nil)
   666  		b := bytes.NewBuffer(compressed)
   667  		var err error
   668  		r, err := gzip.NewReader(b)
   669  		if err != nil {
   670  			t.Fatalf("error creating gzip reader: %v\n", err)
   671  		}
   672  		var buffer bytes.Buffer
   673  		_, err = io.Copy(&buffer, r)
   674  		if err != nil {
   675  			t.Fatalf("error copying gzip data: %v\n", err)
   676  		}
   677  		err = r.Close()
   678  		if err != nil {
   679  			t.Fatalf("error closing gzip: %v\n", err)
   680  		}
   681  		encoding = buffer.Bytes()
   682  		bodies[label-1].checkSparseVol(t, encoding, dvid.OptionalBounds{})
   683  
   684  		// Check Y/Z restriction
   685  		reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d?miny=30&maxy=50&minz=20&maxz=40", server.WebAPIPath, uuid, label)
   686  		if label != 4 {
   687  			encoding = server.TestHTTP(t, "GET", reqStr, nil)
   688  			var bound dvid.OptionalBounds
   689  			bound.SetMinY(30)
   690  			bound.SetMaxY(50)
   691  			bound.SetMinZ(20)
   692  			bound.SetMaxZ(40)
   693  			bodies[label-1].checkSparseVol(t, encoding, bound)
   694  		} else {
   695  			server.TestBadHTTP(t, "GET", reqStr, nil) // Should be not found
   696  		}
   697  
   698  		// Check X restriction
   699  		minx := int32(20)
   700  		maxx := int32(47)
   701  		reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d?minx=%d&maxx=%d", server.WebAPIPath, uuid, label, minx, maxx)
   702  		if label != 4 {
   703  			encoding = server.TestHTTP(t, "GET", reqStr, nil)
   704  			checkSpans(t, encoding, minx, maxx)
   705  		} else {
   706  			server.TestBadHTTP(t, "GET", reqStr, nil) // Should be not found
   707  		}
   708  	}
   709  
   710  	// Make sure non-existent bodies return proper HEAD responses.
   711  	headReq := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 10)
   712  	resp := server.TestHTTPResponse(t, "HEAD", headReq, nil)
   713  	if resp.Code != http.StatusNoContent {
   714  		t.Errorf("HEAD on %s did not return 204 (No Content).  Status = %d\n", headReq, resp.Code)
   715  	}
   716  }
   717  
   718  // func TestMergeLog(t *testing.T) {
   719  // 	if err := server.OpenTest(); err != nil {
   720  // 		t.Fatalf("can't open test server: %v\n", err)
   721  // 	}
   722  // 	defer server.CloseTest()
   723  
   724  // 	// Create testbed volume and data instances
   725  // 	uuid, _ := initTestRepo()
   726  // 	var config dvid.Config
   727  // 	server.CreateTestInstance(t, uuid, "labelmap", "labels", config)
   728  
   729  // 	data, err := GetByUUIDName(uuid, "labels")
   730  // 	if err != nil {
   731  // 		t.Fatalf("can't get labels instance of labelmap: %v\n", err)
   732  // 	}
   733  // }
   734  
   735  func TestMergeLabels(t *testing.T) {
   736  	if err := server.OpenTest(); err != nil {
   737  		t.Fatalf("can't open test server: %v\n", err)
   738  	}
   739  	defer server.CloseTest()
   740  
   741  	// Create testbed volume and data instances
   742  	uuid, _ := initTestRepo()
   743  	var config dvid.Config
   744  	server.CreateTestInstance(t, uuid, "labelmap", "labels", config)
   745  
   746  	expected := createLabelTestVolume(t, uuid, "labels")
   747  	expected.addBody(body3, 2)
   748  
   749  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
   750  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
   751  	}
   752  
   753  	// Make sure max label is consistent
   754  	reqStr := fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid)
   755  	r := server.TestHTTP(t, "GET", reqStr, nil)
   756  	jsonVal := make(map[string]uint64)
   757  	if err := json.Unmarshal(r, &jsonVal); err != nil {
   758  		t.Errorf("Unable to get maxlabel from server.  Instead got: %v\n", jsonVal)
   759  	}
   760  	maxlabel, ok := jsonVal["maxlabel"]
   761  	if !ok {
   762  		t.Errorf("The maxlabel query did not yield max label.  Instead got: %v\n", jsonVal)
   763  	}
   764  	if maxlabel != 4 {
   765  		t.Errorf("Expected max label to be 4, instead got %d\n", maxlabel)
   766  	}
   767  
   768  	// Check /supervoxels
   769  	reqStr = fmt.Sprintf("%snode/%s/labels/supervoxels/2", server.WebAPIPath, uuid)
   770  	r = server.TestHTTP(t, "GET", reqStr, nil)
   771  	var supervoxels []uint64
   772  	if err := json.Unmarshal(r, &supervoxels); err != nil {
   773  		t.Errorf("Unable to parse supervoxels from server.  Got: %v\n", supervoxels)
   774  	}
   775  	if len(supervoxels) != 1 || supervoxels[0] != 2 {
   776  		t.Errorf("expected [2] for supervoxels in body 2, got %v\n", supervoxels)
   777  	}
   778  
   779  	// Check /supervoxel-sizes
   780  	reqStr = fmt.Sprintf("%snode/%s/labels/supervoxel-sizes/2", server.WebAPIPath, uuid)
   781  	r = server.TestHTTP(t, "GET", reqStr, nil)
   782  	svsizes := struct {
   783  		Supervoxels []uint64
   784  		Sizes       []uint64
   785  	}{}
   786  	if err := json.Unmarshal(r, &svsizes); err != nil {
   787  		t.Errorf("Unable to parse supervoxel-sizes from server.  Got: %s\n", string(r))
   788  	}
   789  	if len(svsizes.Supervoxels) != 1 || svsizes.Supervoxels[0] != 2 {
   790  		t.Errorf("expected [2] for supervoxels in body 2, got %v\n", svsizes.Supervoxels)
   791  	}
   792  	if len(svsizes.Sizes) != 1 || svsizes.Sizes[0] != 50000 {
   793  		t.Errorf("expected [2] for supervoxel sizes in body 2, got %v\n", svsizes.Sizes)
   794  	}
   795  
   796  	// Make sure /label and /labels endpoints work.
   797  	apiStr := fmt.Sprintf("%snode/%s/%s/label/94_58_89", server.WebAPIPath, uuid, "labels")
   798  	jsonResp := server.TestHTTP(t, "GET", apiStr, nil)
   799  	var jsonVal2 struct {
   800  		Label uint64
   801  	}
   802  	if err := json.Unmarshal(jsonResp, &jsonVal2); err != nil {
   803  		t.Errorf("Unable to parse 'label' endpoint response: %s\n", jsonResp)
   804  	}
   805  	if jsonVal2.Label != 4 {
   806  		t.Errorf("Expected label 4, got label %d\n", jsonVal2.Label)
   807  	}
   808  	apiStr = fmt.Sprintf("%snode/%s/%s/labels", server.WebAPIPath, uuid, "labels")
   809  	payload := `[[20,46,39],[30,25,50],[48,56,39],[80,55,60]]`
   810  	jsonResp = server.TestHTTP(t, "GET", apiStr, bytes.NewBufferString(payload))
   811  	var labels [4]uint64
   812  	if err := json.Unmarshal(jsonResp, &labels); err != nil {
   813  		t.Fatalf("Unable to parse 'labels' endpoint response: %s\n", jsonResp)
   814  	}
   815  	if labels[0] != 1 {
   816  		t.Errorf("Expected label 1, got label %d\n", labels[0])
   817  	}
   818  	if labels[1] != 2 {
   819  		t.Errorf("Expected label 2, got label %d\n", labels[1])
   820  	}
   821  	if labels[2] != 3 {
   822  		t.Errorf("Expected label 3, got label %d\n", labels[2])
   823  	}
   824  	if labels[3] != 4 {
   825  		t.Errorf("Expected label 4, got label %d\n", labels[3])
   826  	}
   827  
   828  	// Test merge of 3 into 2
   829  	testMerge := mergeJSON(`[2, 3]`)
   830  	testMerge.send(t, uuid, "labels")
   831  
   832  	// Make sure label 3 sparsevol has been removed.
   833  	reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 3)
   834  	server.TestBadHTTP(t, "GET", reqStr, nil)
   835  
   836  	// Check /supervoxels
   837  	reqStr = fmt.Sprintf("%snode/%s/labels/supervoxels/2", server.WebAPIPath, uuid)
   838  	r = server.TestHTTP(t, "GET", reqStr, nil)
   839  	if err := json.Unmarshal(r, &supervoxels); err != nil {
   840  		t.Errorf("Unable to parse supervoxels from server.  Got: %v\n", supervoxels)
   841  	}
   842  	if len(supervoxels) != 2 {
   843  		t.Errorf("expected [2,3] for supervoxels in body 2, got %v\n", supervoxels)
   844  	}
   845  	sv := make(map[uint64]struct{}, 2)
   846  	for _, supervoxel := range supervoxels {
   847  		sv[supervoxel] = struct{}{}
   848  	}
   849  	if _, found := sv[2]; !found {
   850  		t.Errorf("expected supervoxel 2 within body 2 but didn't find it\n")
   851  	}
   852  	if _, found := sv[3]; !found {
   853  		t.Errorf("expected supervoxel 3 within body 3 but didn't find it\n")
   854  	}
   855  
   856  	reqStr = fmt.Sprintf("%snode/%s/labels/supervoxel-sizes/2", server.WebAPIPath, uuid)
   857  	r = server.TestHTTP(t, "GET", reqStr, nil)
   858  	if err := json.Unmarshal(r, &svsizes); err != nil {
   859  		t.Errorf("Unable to parse supervoxel-sizes from server.  Got: %s\n", string(r))
   860  	}
   861  	expectedSizes := map[uint64]uint64{
   862  		2: 50000,
   863  		3: 12000,
   864  	}
   865  	if len(svsizes.Supervoxels) != 2 {
   866  		t.Fatalf("expected 2 sv return from supervoxel-sizes, got %d\n", len(svsizes.Supervoxels))
   867  	}
   868  	if len(svsizes.Sizes) != 2 {
   869  		t.Fatalf("expected 2 sv size return from supervoxel-sizes, got %d\n", len(svsizes.Sizes))
   870  	}
   871  	for i := 0; i < 2; i++ {
   872  		svlabel := svsizes.Supervoxels[i]
   873  		expectedSize, found := expectedSizes[svlabel]
   874  		if !found {
   875  			t.Fatalf("bad /supervoxel-sizes return. Got unexpected supervoxel %d\n", svlabel)
   876  		}
   877  		if expectedSize != svsizes.Sizes[i] {
   878  			t.Fatalf("bad /supervoxel-sizes return. Got unexpected size %d for supervoxel %d, expected %d\n",
   879  				svsizes.Sizes[i], svlabel, expectedSize)
   880  		}
   881  	}
   882  
   883  	// Make sure the index metadata is correct
   884  	indexURL := fmt.Sprintf("%snode/%s/labels/index/2?metadata-only=true", server.WebAPIPath, uuid)
   885  	respData := server.TestHTTP(t, "GET", indexURL, nil)
   886  	respJSON := struct {
   887  		NumVoxels   uint64 `json:"num_voxels"`
   888  		LastMutID   uint64 `json:"last_mutid"`
   889  		LastModTime string `json:"last_mod_time"`
   890  		LastModUser string `json:"last_mod_user"`
   891  		LastModApp  string `json:"last_mod_app"`
   892  	}{}
   893  	if err := json.Unmarshal(respData, &respJSON); err != nil {
   894  		t.Errorf("Expected JSON response.  Got %s\n", string(respData))
   895  	}
   896  	if respJSON.NumVoxels != 62000 {
   897  		t.Errorf("Expected num voxels %d, got %d\n", 50000, respJSON.NumVoxels)
   898  	}
   899  	if respJSON.LastModUser != "tester" {
   900  		t.Errorf("Expected LastModUser 'tester', got %v\n", respJSON)
   901  	}
   902  
   903  	// Make sure label changes are correct after completion
   904  	apiStr = fmt.Sprintf("%snode/%s/%s/labels", server.WebAPIPath, uuid, "labels")
   905  	jsonResp = server.TestHTTP(t, "GET", apiStr, bytes.NewBufferString(payload))
   906  	if err := json.Unmarshal(jsonResp, &labels); err != nil {
   907  		t.Fatalf("Unable to parse 'labels' endpoint response: %s\n", jsonResp)
   908  	}
   909  	if labels[0] != 1 {
   910  		t.Errorf("Expected label 1, got label %d\n", labels[0])
   911  	}
   912  	if labels[1] != 2 {
   913  		t.Errorf("Expected label 2, got label %d\n", labels[1])
   914  	}
   915  	if labels[2] != 2 {
   916  		t.Errorf("Expected label 2, got label %d\n", labels[2])
   917  	}
   918  	if labels[3] != 4 {
   919  		t.Errorf("Expected label 4, got label %d\n", labels[3])
   920  	}
   921  
   922  	apiStr = fmt.Sprintf("%snode/%s/%s/label/59_56_20", server.WebAPIPath, uuid, "labels")
   923  	jsonResp = server.TestHTTP(t, "GET", apiStr, nil)
   924  	if err := json.Unmarshal(jsonResp, &jsonVal2); err != nil {
   925  		t.Errorf("Unable to parse 'label' endpoint response: %s\n", jsonResp)
   926  	}
   927  	if jsonVal2.Label != 2 {
   928  		t.Errorf("Expected label 2, got label %d\n", jsonVal2.Label)
   929  	}
   930  
   931  	retrieved := newTestVolume(128, 128, 128)
   932  	retrieved.get(t, uuid, "labels", false)
   933  	if len(retrieved.data) != 8*128*128*128 {
   934  		t.Errorf("Retrieved labelvol volume is incorrect size\n")
   935  	}
   936  	if !retrieved.isLabel(2, &body2) {
   937  		t.Errorf("Expected label 2 original voxels to remain.  Instead some were removed.\n")
   938  	}
   939  	if retrieved.hasLabel(3, &body3) {
   940  		t.Errorf("Found label 3 when all label 3 should have been merged into label 2!\n")
   941  	}
   942  	if !retrieved.isLabel(2, &body3) {
   943  		t.Errorf("Incomplete merging.  Label 2 should have taken over full extent of label 3\n")
   944  	}
   945  	if err := retrieved.equals(expected); err != nil {
   946  		t.Errorf("Merged label volume: %v\n", err)
   947  	}
   948  }
   949  
   950  func TestSplitLabel(t *testing.T) {
   951  	if err := server.OpenTest(); err != nil {
   952  		t.Fatalf("can't open test server: %v\n", err)
   953  	}
   954  	defer server.CloseTest()
   955  
   956  	// Create testbed volume and data instances
   957  	uuid, _ := initTestRepo()
   958  	var config dvid.Config
   959  	config.Set("MaxDownresLevel", "2")
   960  	config.Set("BlockSize", "32,32,32") // Previous test data was on 32^3 blocks
   961  	server.CreateTestInstance(t, uuid, "labelmap", "labels", config)
   962  
   963  	// Post label volume and setup expected volume after split.
   964  	expected := createLabelTestVolume(t, uuid, "labels")
   965  	expected.addBody(bodysplit, 5)
   966  
   967  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
   968  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
   969  	}
   970  
   971  	// Make sure sparsevol for original body 4 is correct
   972  	reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 4)
   973  	encoding := server.TestHTTP(t, "GET", reqStr, nil)
   974  	fmt.Printf("Checking original body 4 is correct\n")
   975  	body4.checkSparseVol(t, encoding, dvid.OptionalBounds{})
   976  
   977  	// Create the sparsevol encoding for split area
   978  	numspans := len(bodysplit.voxelSpans)
   979  	rles := make(dvid.RLEs, numspans, numspans)
   980  	for i, span := range bodysplit.voxelSpans {
   981  		start := dvid.Point3d{span[2], span[1], span[0]}
   982  		length := span[3] - span[2] + 1
   983  		rles[i] = dvid.NewRLE(start, length)
   984  	}
   985  
   986  	// Create the split sparse volume binary
   987  	buf := new(bytes.Buffer)
   988  	buf.WriteByte(dvid.EncodingBinary)
   989  	binary.Write(buf, binary.LittleEndian, uint8(3))         // # of dimensions
   990  	binary.Write(buf, binary.LittleEndian, byte(0))          // dimension of run (X = 0)
   991  	buf.WriteByte(byte(0))                                   // reserved for later
   992  	binary.Write(buf, binary.LittleEndian, uint32(0))        // Placeholder for # voxels
   993  	binary.Write(buf, binary.LittleEndian, uint32(numspans)) // Placeholder for # spans
   994  	rleBytes, err := rles.MarshalBinary()
   995  	if err != nil {
   996  		t.Errorf("Unable to serialize RLEs: %v\n", err)
   997  	}
   998  	buf.Write(rleBytes)
   999  
  1000  	// Verify the max label is 4
  1001  	reqStr = fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid)
  1002  	jsonStr := server.TestHTTP(t, "GET", reqStr, nil)
  1003  	expectedJSON := `{"maxlabel": 4}`
  1004  	if string(jsonStr) != expectedJSON {
  1005  		t.Errorf("Expected this JSON returned from maxlabel:\n%s\nGot:\n%s\n", expectedJSON, string(jsonStr))
  1006  	}
  1007  
  1008  	// Submit the split sparsevol for body 4 using RLES "bodysplit"
  1009  	reqStr = fmt.Sprintf("%snode/%s/labels/split/%d", server.WebAPIPath, uuid, 4)
  1010  	r := server.TestHTTP(t, "POST", reqStr, buf)
  1011  	jsonVal := make(map[string]uint64)
  1012  	if err := json.Unmarshal(r, &jsonVal); err != nil {
  1013  		t.Errorf("Unable to get new label from split.  Instead got: %v\n", jsonVal)
  1014  	}
  1015  	newlabel, ok := jsonVal["label"]
  1016  	if !ok {
  1017  		t.Errorf("The split request did not yield label value.  Instead got: %v\n", jsonVal)
  1018  	}
  1019  	if newlabel != 5 {
  1020  		t.Errorf("Expected split label to be 5, instead got %d\n", newlabel)
  1021  	}
  1022  
  1023  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
  1024  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
  1025  	}
  1026  
  1027  	retrieved := newTestVolume(128, 128, 128)
  1028  	retrieved.get(t, uuid, "labels", false)
  1029  	if len(retrieved.data) != 8*128*128*128 {
  1030  		t.Errorf("Retrieved post-split volume is incorrect size\n")
  1031  	}
  1032  	if err := retrieved.equals(expected); err != nil {
  1033  		t.Errorf("Split label volume not equal to expected volume: %v\n", err)
  1034  	}
  1035  	downres1 := newTestVolume(64, 64, 64)
  1036  	downres1.getScale(t, uuid, "labels", 1, false)
  1037  	if err := downres1.equalsDownres(expected); err != nil {
  1038  		t.Errorf("Split label volume failed level 1 down-scale: %v\n", err)
  1039  	}
  1040  	downres2 := newTestVolume(32, 32, 32)
  1041  	downres2.getScale(t, uuid, "labels", 2, false)
  1042  	if err := downres2.equalsDownres(downres1); err != nil {
  1043  		t.Errorf("Split label volume failed level 2 down-scale: %v\n", err)
  1044  	}
  1045  
  1046  	retrieved.get(t, uuid, "labels", true)
  1047  	downres1.getScale(t, uuid, "labels", 1, true)
  1048  	if err := downres1.equalsDownres(retrieved); err != nil {
  1049  		t.Errorf("Split label supervoxel volume failed level 1 down-scale: %v\n", err)
  1050  	}
  1051  	downres2.getScale(t, uuid, "labels", 2, true)
  1052  	if err := downres2.equalsDownres(downres1); err != nil {
  1053  		t.Errorf("Split label supervoxel volume failed level 2 down-scale: %v\n", err)
  1054  	}
  1055  
  1056  	// Check split body 5 usine legacy RLEs
  1057  	reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 5)
  1058  	encoding = server.TestHTTP(t, "GET", reqStr, nil)
  1059  	bodysplit.checkSparseVol(t, encoding, dvid.OptionalBounds{})
  1060  
  1061  	reqStr = fmt.Sprintf("%snode/%s/labels/size/5", server.WebAPIPath, uuid)
  1062  	r = server.TestHTTP(t, "GET", reqStr, nil)
  1063  	var jsonVal2 struct {
  1064  		Voxels uint64 `json:"voxels"`
  1065  	}
  1066  	if err := json.Unmarshal(r, &jsonVal2); err != nil {
  1067  		t.Fatalf("unable to get size: %v", err)
  1068  	}
  1069  	voxelsIn4 := body4.voxelSpans.Count()
  1070  	expectedVoxels := bodysplit.voxelSpans.Count()
  1071  	if jsonVal2.Voxels != expectedVoxels {
  1072  		t.Errorf("thought split body would have %d voxels, got %d\n", expectedVoxels, jsonVal2.Voxels)
  1073  	}
  1074  	dvid.Infof("body split had %d voxels\n", expectedVoxels)
  1075  
  1076  	reqStr = fmt.Sprintf("%snode/%s/labels/size/4?supervoxels=true", server.WebAPIPath, uuid)
  1077  	server.TestBadHTTP(t, "GET", reqStr, nil)
  1078  
  1079  	reqStr = fmt.Sprintf("%snode/%s/labels/size/6?supervoxels=true", server.WebAPIPath, uuid)
  1080  	r = server.TestHTTP(t, "GET", reqStr, nil)
  1081  	if err := json.Unmarshal(r, &jsonVal2); err != nil {
  1082  		t.Fatalf("unable to get size for supervoxel 6: %v", err)
  1083  	}
  1084  	if jsonVal2.Voxels != expectedVoxels {
  1085  		t.Errorf("expected split supervoxel to be %d voxels, got %d voxels\n", expectedVoxels, jsonVal2.Voxels)
  1086  	}
  1087  	reqStr = fmt.Sprintf("%snode/%s/labels/sizes?supervoxels=true", server.WebAPIPath, uuid)
  1088  	bodystr := "[4, 6]"
  1089  	r = server.TestHTTP(t, "GET", reqStr, bytes.NewBufferString(bodystr))
  1090  	if string(r) != fmt.Sprintf("[%d,%d]", 0, expectedVoxels) {
  1091  		t.Errorf("bad batch sizes result.  got: %s\n", string(r))
  1092  	}
  1093  
  1094  	reqStr = fmt.Sprintf("%snode/%s/labels/size/7?supervoxels=true", server.WebAPIPath, uuid)
  1095  	r = server.TestHTTP(t, "GET", reqStr, nil)
  1096  	if err := json.Unmarshal(r, &jsonVal2); err != nil {
  1097  		t.Fatalf("unable to get size for supervoxel 7: %v", err)
  1098  	}
  1099  	if jsonVal2.Voxels != voxelsIn4-expectedVoxels {
  1100  		t.Errorf("thought remnant supervoxel 7 would have %d voxels remaining, got %d\n", voxelsIn4-expectedVoxels, jsonVal2.Voxels)
  1101  	}
  1102  
  1103  	reqStr = fmt.Sprintf("%snode/%s/labels/supervoxel-splits", server.WebAPIPath, uuid)
  1104  	r = server.TestHTTP(t, "GET", reqStr, nil)
  1105  	if string(r) != fmt.Sprintf(`["%s",[[%d,4,7,6]]]`, uuid, datastore.InitialMutationID+1) {
  1106  		t.Fatalf("bad supervoxel-splits JSON return: %s\n", string(r))
  1107  	}
  1108  
  1109  	// Make sure sparsevol for original body 4 is correct
  1110  	reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 4)
  1111  	encoding = server.TestHTTP(t, "GET", reqStr, nil)
  1112  	bodyleft.checkSparseVol(t, encoding, dvid.OptionalBounds{})
  1113  
  1114  	// make sure we verified supervoxel list works in /mapping.
  1115  	reqStr = fmt.Sprintf("%snode/%s/labels/mapping", server.WebAPIPath, uuid)
  1116  	svlist := "[1, 2, 3, 4, 5, 6, 7, 8, 1000]"
  1117  	r = server.TestHTTP(t, "GET", reqStr, bytes.NewBufferString(svlist))
  1118  	if string(r) != "[1,2,3,0,0,5,4,0,0]" {
  1119  		t.Errorf("bad verified /mapping result after split.  got: %s\n", string(r))
  1120  	}
  1121  
  1122  	// Do a merge of two after the split
  1123  	testMerge := mergeJSON(`[4, 5]`)
  1124  	testMerge.send(t, uuid, "labels")
  1125  
  1126  	// Make sure we wind up with original body 4
  1127  	reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/4", server.WebAPIPath, uuid)
  1128  	encoding = server.TestHTTP(t, "GET", reqStr, nil)
  1129  	body4.checkSparseVol(t, encoding, dvid.OptionalBounds{})
  1130  
  1131  	// make sure we verified supervoxel list works in /mapping.
  1132  	reqStr = fmt.Sprintf("%snode/%s/labels/mapping", server.WebAPIPath, uuid)
  1133  	r = server.TestHTTP(t, "GET", reqStr, bytes.NewBufferString(svlist))
  1134  	if string(r) != "[1,2,3,0,0,4,4,0,0]" {
  1135  		t.Errorf("bad verified /mapping result after split and merge.  got: %s\n", string(r))
  1136  	}
  1137  }
  1138  
  1139  func getSVMapping(t *testing.T, uuid dvid.UUID, name string, supervoxel uint64) (mappedSV uint64) {
  1140  	url := fmt.Sprintf("%snode/%s/%s/mapping", server.WebAPIPath, uuid, name)
  1141  	svlist := fmt.Sprintf("[%d]", supervoxel)
  1142  	r := server.TestHTTP(t, "GET", url, bytes.NewBufferString(svlist))
  1143  	mapResp := []uint64{}
  1144  	if err := json.Unmarshal(r, &mapResp); err != nil {
  1145  		t.Fatalf("Unable to get mapping.  Instead got: %v, err: %v\n", mapResp, err)
  1146  	}
  1147  	if len(mapResp) != 1 {
  1148  		t.Fatalf("Expected 1 uint64 response from /mapping, got: %v\n", mapResp)
  1149  	}
  1150  	return mapResp[0]
  1151  }
  1152  
  1153  func getIndex(t *testing.T, uuid dvid.UUID, name string, label uint64) *labels.Index {
  1154  	url := fmt.Sprintf("http://%snode/%s/%s/index/%d", server.WebAPIPath, uuid, name, label)
  1155  	data := server.TestHTTP(t, "GET", url, nil)
  1156  	if len(data) == 0 {
  1157  		t.Fatalf("Read label index %d returned no bytes\n", label)
  1158  	}
  1159  	idx := new(labels.Index)
  1160  	if err := pb.Unmarshal(data, idx); err != nil {
  1161  		t.Fatalf("couldn't unmarshal index: %v\n", err)
  1162  	}
  1163  	return idx
  1164  }
  1165  
  1166  type blockCounts struct {
  1167  	bcoord dvid.ChunkPoint3d
  1168  	counts map[uint64]uint32
  1169  }
  1170  
  1171  func checkIndex(t *testing.T, desc string, idx *labels.Index, blocks []blockCounts) {
  1172  	if len(idx.Blocks) != len(blocks) {
  1173  		t.Fatalf("Expected %d blocks for index %d (%s), got %d blocks: %s\n", len(blocks), idx.Label, desc, len(idx.Blocks), idx.StringDump(false))
  1174  	}
  1175  	seen := make(map[uint64]struct{})
  1176  	for _, block := range blocks {
  1177  		zyx, err := labels.IZYXStringToBlockIndex(block.bcoord.ToIZYXString())
  1178  		if err != nil {
  1179  			t.Fatalf("bad block coord (%s): %s\n", desc, block.bcoord)
  1180  		}
  1181  		seen[zyx] = struct{}{}
  1182  		svc, found := idx.Blocks[zyx]
  1183  		if !found {
  1184  			t.Fatalf("expected %s block %s to be in index %d but found none\n", desc, block.bcoord, idx.Label)
  1185  		}
  1186  		if len(svc.Counts) != len(block.counts) {
  1187  			t.Fatalf("expected %s block %s counts %v and got this instead: %v\n", desc, block.bcoord, block.counts, svc.Counts)
  1188  		}
  1189  		for supervoxel, count := range block.counts {
  1190  			actual, found := svc.Counts[supervoxel]
  1191  			if !found {
  1192  				t.Fatalf("expected label %d (%s) to have %d voxels, but label not in the retrieved index for block %s\n", supervoxel, desc, count, block.bcoord)
  1193  			}
  1194  			if actual != count {
  1195  				t.Fatalf("expected label %d (%s) to have %d voxels in block %s, but got %d voxels\n", supervoxel, desc, count, block.bcoord, actual)
  1196  			}
  1197  		}
  1198  	}
  1199  }
  1200  
  1201  func TestArbitrarySplit(t *testing.T) {
  1202  	if err := server.OpenTest(); err != nil {
  1203  		t.Fatalf("can't open test server: %v\n", err)
  1204  	}
  1205  	defer server.CloseTest()
  1206  
  1207  	uuid, _ := datastore.NewTestRepo()
  1208  	server.CreateTestInstance(t, uuid, "labelmap", "labels", dvid.Config{})
  1209  
  1210  	labelA := uint64(1000)
  1211  	labelB := uint64(2000)
  1212  
  1213  	data := make([]byte, 128*128*128*8)
  1214  	var x, y, z int32
  1215  	for z = 32; z < 96; z++ {
  1216  		for y = 32; y < 96; y++ {
  1217  			for x = 32; x < 96; x++ {
  1218  				i := (z*128*128 + y*128 + x) * 8
  1219  				binary.LittleEndian.PutUint64(data[i:i+8], labelA)
  1220  			}
  1221  		}
  1222  	}
  1223  	for z = 32; z < 96; z++ {
  1224  		for y = 96; y < 112; y++ {
  1225  			for x = 32; x < 112; x++ {
  1226  				i := (z*128*128 + y*128 + x) * 8
  1227  				binary.LittleEndian.PutUint64(data[i:i+8], labelB)
  1228  			}
  1229  		}
  1230  	}
  1231  	for z = 32; z < 96; z++ {
  1232  		for y = 32; y < 96; y++ {
  1233  			for x = 96; x < 112; x++ {
  1234  				i := (z*128*128 + y*128 + x) * 8
  1235  				binary.LittleEndian.PutUint64(data[i:i+8], labelB)
  1236  			}
  1237  		}
  1238  	}
  1239  
  1240  	apiStr := fmt.Sprintf("%snode/%s/labels/raw/0_1_2/128_128_128/0_0_0", server.WebAPIPath, uuid)
  1241  	server.TestHTTP(t, "POST", apiStr, bytes.NewBuffer(data))
  1242  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
  1243  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
  1244  	}
  1245  
  1246  	// Get the original body indices
  1247  	origIndexA := getIndex(t, uuid, "labels", labelA)
  1248  	blocksA := []blockCounts{
  1249  		{
  1250  			bcoord: dvid.ChunkPoint3d{0, 0, 0},
  1251  			counts: map[uint64]uint32{labelA: 32768},
  1252  		},
  1253  		{
  1254  			bcoord: dvid.ChunkPoint3d{1, 0, 0},
  1255  			counts: map[uint64]uint32{labelA: 32768},
  1256  		},
  1257  		{
  1258  			bcoord: dvid.ChunkPoint3d{0, 1, 0},
  1259  			counts: map[uint64]uint32{labelA: 32768},
  1260  		},
  1261  		{
  1262  			bcoord: dvid.ChunkPoint3d{1, 1, 0},
  1263  			counts: map[uint64]uint32{labelA: 32768},
  1264  		},
  1265  		{
  1266  			bcoord: dvid.ChunkPoint3d{0, 0, 1},
  1267  			counts: map[uint64]uint32{labelA: 32768},
  1268  		},
  1269  		{
  1270  			bcoord: dvid.ChunkPoint3d{1, 0, 1},
  1271  			counts: map[uint64]uint32{labelA: 32768},
  1272  		},
  1273  		{
  1274  			bcoord: dvid.ChunkPoint3d{0, 1, 1},
  1275  			counts: map[uint64]uint32{labelA: 32768},
  1276  		},
  1277  		{
  1278  			bcoord: dvid.ChunkPoint3d{1, 1, 1},
  1279  			counts: map[uint64]uint32{labelA: 32768},
  1280  		},
  1281  	}
  1282  	checkIndex(t, "original index A", origIndexA, blocksA)
  1283  
  1284  	origIndexB := getIndex(t, uuid, "labels", labelB)
  1285  	blocksB := []blockCounts{
  1286  		{
  1287  			bcoord: dvid.ChunkPoint3d{1, 0, 0},
  1288  			counts: map[uint64]uint32{labelB: 16384},
  1289  		},
  1290  		{
  1291  			bcoord: dvid.ChunkPoint3d{0, 1, 0},
  1292  			counts: map[uint64]uint32{labelB: 16384},
  1293  		},
  1294  		{
  1295  			bcoord: dvid.ChunkPoint3d{1, 1, 0},
  1296  			counts: map[uint64]uint32{labelB: 16384 + 24576},
  1297  		},
  1298  		{
  1299  			bcoord: dvid.ChunkPoint3d{1, 0, 1},
  1300  			counts: map[uint64]uint32{labelB: 16384},
  1301  		},
  1302  		{
  1303  			bcoord: dvid.ChunkPoint3d{0, 1, 1},
  1304  			counts: map[uint64]uint32{labelB: 16384},
  1305  		},
  1306  		{
  1307  			bcoord: dvid.ChunkPoint3d{1, 1, 1},
  1308  			counts: map[uint64]uint32{labelB: 16384 + 24576},
  1309  		},
  1310  	}
  1311  	checkIndex(t, "original index B", origIndexB, blocksB)
  1312  
  1313  	// merge the two supervoxels into one body
  1314  	mergeJSON := fmt.Sprintf("[%d,%d]", labelA, labelB)
  1315  	apiStr = fmt.Sprintf("%snode/%s/labels/merge", server.WebAPIPath, uuid)
  1316  	server.TestHTTP(t, "POST", apiStr, bytes.NewBufferString(mergeJSON))
  1317  
  1318  	mergeIndex := getIndex(t, uuid, "labels", labelA)
  1319  	blocksAB := []blockCounts{
  1320  		{
  1321  			bcoord: dvid.ChunkPoint3d{0, 0, 0},
  1322  			counts: map[uint64]uint32{labelA: 32768},
  1323  		},
  1324  		{
  1325  			bcoord: dvid.ChunkPoint3d{1, 0, 0},
  1326  			counts: map[uint64]uint32{labelA: 32768, labelB: 16384},
  1327  		},
  1328  		{
  1329  			bcoord: dvid.ChunkPoint3d{0, 1, 0},
  1330  			counts: map[uint64]uint32{labelA: 32768, labelB: 16384},
  1331  		},
  1332  		{
  1333  			bcoord: dvid.ChunkPoint3d{1, 1, 0},
  1334  			counts: map[uint64]uint32{labelA: 32768, labelB: 16384 + 24576},
  1335  		},
  1336  		{
  1337  			bcoord: dvid.ChunkPoint3d{0, 0, 1},
  1338  			counts: map[uint64]uint32{labelA: 32768},
  1339  		},
  1340  		{
  1341  			bcoord: dvid.ChunkPoint3d{1, 0, 1},
  1342  			counts: map[uint64]uint32{labelA: 32768, labelB: 16384},
  1343  		},
  1344  		{
  1345  			bcoord: dvid.ChunkPoint3d{0, 1, 1},
  1346  			counts: map[uint64]uint32{labelA: 32768, labelB: 16384},
  1347  		},
  1348  		{
  1349  			bcoord: dvid.ChunkPoint3d{1, 1, 1},
  1350  			counts: map[uint64]uint32{labelA: 32768, labelB: 16384 + 24576},
  1351  		},
  1352  	}
  1353  	checkIndex(t, "merged index", mergeIndex, blocksAB)
  1354  
  1355  	// do a split
  1356  	var split dvid.RLEs
  1357  	x = 56
  1358  	for z = 32; z < 96; z++ {
  1359  		for y = 32; y < 64; y++ {
  1360  			split = append(split, dvid.NewRLE(dvid.Point3d{x, y, z}, 40))
  1361  		}
  1362  	}
  1363  	x = 50 // 10 x 10 x 10 notch in (0, 1, 0) block just in LabelA area
  1364  	for z = 32; z < 42; z++ {
  1365  		for y = 64; y < 74; y++ {
  1366  			split = append(split, dvid.NewRLE(dvid.Point3d{x, y, z}, 10))
  1367  		}
  1368  	}
  1369  	x = 80
  1370  	for z = 32; z < 48; z++ {
  1371  		for y = 64; y < 100; y++ {
  1372  			split = append(split, dvid.NewRLE(dvid.Point3d{x, y, z}, 8))
  1373  		}
  1374  	}
  1375  	splitVoxels, splitRuns := split.Stats()
  1376  	dvid.Infof("split has %d voxels, %d runs\n", splitVoxels, splitRuns)
  1377  
  1378  	buf := new(bytes.Buffer)
  1379  	buf.WriteByte(dvid.EncodingBinary)
  1380  	binary.Write(buf, binary.LittleEndian, uint8(3))          // # of dimensions
  1381  	binary.Write(buf, binary.LittleEndian, byte(0))           // dimension of run (X = 0)
  1382  	buf.WriteByte(byte(0))                                    // reserved for later
  1383  	binary.Write(buf, binary.LittleEndian, uint32(0))         // Placeholder for # voxels
  1384  	binary.Write(buf, binary.LittleEndian, uint32(splitRuns)) // Placeholder for # spans
  1385  	splitBytes, err := split.MarshalBinary()
  1386  	if err != nil {
  1387  		t.Errorf("Unable to serialize RLEs: %v\n", err)
  1388  	}
  1389  	buf.Write(splitBytes)
  1390  
  1391  	apiStr = fmt.Sprintf("%snode/%s/labels/split/%d", server.WebAPIPath, uuid, labelA)
  1392  	r := server.TestHTTP(t, "POST", apiStr, buf)
  1393  	var splitResp struct {
  1394  		Label uint64 `json:"label"`
  1395  	}
  1396  	if err := json.Unmarshal(r, &splitResp); err != nil {
  1397  		t.Errorf("Unable to get new label from split.  Instead got: %v\n", splitResp)
  1398  	}
  1399  	dvid.Infof("Test split produced new label %d\n", splitResp.Label)
  1400  
  1401  	splitIndex := getIndex(t, uuid, "labels", splitResp.Label)
  1402  	remainIndex := getIndex(t, uuid, "labels", labelA)
  1403  
  1404  	zyx110, _ := labels.IZYXStringToBlockIndex(dvid.ChunkPoint3d{1, 1, 0}.ToIZYXString())
  1405  	svc, found := splitIndex.Blocks[zyx110]
  1406  	if !found {
  1407  		t.Fatalf("expected split index block (1,1,0) but not found\n")
  1408  	}
  1409  	if len(svc.Counts) != 2 {
  1410  		t.Fatalf("expected two supervoxels in split block (1,1,0), got: %v\n", svc.Counts)
  1411  	}
  1412  	var labelSplitA, labelSplitB, labelRemainA, labelRemainB uint64
  1413  	for label, count := range svc.Counts {
  1414  		switch count {
  1415  		case 512:
  1416  			labelSplitB = label
  1417  		case 4096:
  1418  			labelSplitA = label
  1419  		default:
  1420  			t.Fatalf("bad split block (1,1,0): %v\n", svc.Counts)
  1421  		}
  1422  	}
  1423  	svc, found = remainIndex.Blocks[zyx110]
  1424  	if !found {
  1425  		t.Fatalf("expected remain index block (1,1,0) but not found\n")
  1426  	}
  1427  	if len(svc.Counts) != 2 {
  1428  		t.Fatalf("expected two supervoxels in remain block (1,1,0), got: %v\n", svc.Counts)
  1429  	}
  1430  	for label, count := range svc.Counts {
  1431  		switch count {
  1432  		case 16384 + 24576 - 512:
  1433  			labelRemainB = label
  1434  		case 32768 - 4096:
  1435  			labelRemainA = label
  1436  		default:
  1437  			t.Fatalf("bad remain block (1,1,0): %v\n", svc.Counts)
  1438  		}
  1439  	}
  1440  	dvid.Infof("Supervoxel %d -> split %d, remain %d\n", labelA, labelSplitA, labelRemainA)
  1441  	dvid.Infof("Supervoxel %d -> split %d, remain %d\n", labelB, labelSplitB, labelRemainB)
  1442  
  1443  	blocksSplit := []blockCounts{
  1444  		{
  1445  			bcoord: dvid.ChunkPoint3d{0, 0, 0},
  1446  			counts: map[uint64]uint32{labelSplitA: 8192},
  1447  		},
  1448  		{
  1449  			bcoord: dvid.ChunkPoint3d{1, 0, 0},
  1450  			counts: map[uint64]uint32{labelSplitA: 32768},
  1451  		},
  1452  		{
  1453  			bcoord: dvid.ChunkPoint3d{0, 1, 0},
  1454  			counts: map[uint64]uint32{labelSplitA: 1000},
  1455  		},
  1456  		{
  1457  			bcoord: dvid.ChunkPoint3d{1, 1, 0},
  1458  			counts: map[uint64]uint32{labelSplitA: 4096, labelSplitB: 512},
  1459  		},
  1460  		{
  1461  			bcoord: dvid.ChunkPoint3d{0, 0, 1},
  1462  			counts: map[uint64]uint32{labelSplitA: 8192},
  1463  		},
  1464  		{
  1465  			bcoord: dvid.ChunkPoint3d{1, 0, 1},
  1466  			counts: map[uint64]uint32{labelSplitA: 32768},
  1467  		},
  1468  	}
  1469  	checkIndex(t, "split index", splitIndex, blocksSplit)
  1470  
  1471  	blocksRemain := []blockCounts{
  1472  		{
  1473  			bcoord: dvid.ChunkPoint3d{0, 0, 0},
  1474  			counts: map[uint64]uint32{labelRemainA: 32768 - 8192},
  1475  		},
  1476  		{
  1477  			bcoord: dvid.ChunkPoint3d{1, 0, 0},
  1478  			counts: map[uint64]uint32{labelRemainB: 16384},
  1479  		},
  1480  		{
  1481  			bcoord: dvid.ChunkPoint3d{0, 1, 0},
  1482  			counts: map[uint64]uint32{labelRemainA: 31768, labelRemainB: 16384},
  1483  		},
  1484  		{
  1485  			bcoord: dvid.ChunkPoint3d{1, 1, 0},
  1486  			counts: map[uint64]uint32{labelRemainA: 32768 - 4096, labelRemainB: 16384 + 24576 - 512},
  1487  		},
  1488  		{
  1489  			bcoord: dvid.ChunkPoint3d{0, 0, 1},
  1490  			counts: map[uint64]uint32{labelRemainA: 32768 - 8192},
  1491  		},
  1492  		{
  1493  			bcoord: dvid.ChunkPoint3d{1, 0, 1},
  1494  			counts: map[uint64]uint32{labelRemainB: 16384},
  1495  		},
  1496  		{
  1497  			bcoord: dvid.ChunkPoint3d{0, 1, 1},
  1498  			counts: map[uint64]uint32{labelRemainA: 32768, labelRemainB: 16384},
  1499  		},
  1500  		{
  1501  			bcoord: dvid.ChunkPoint3d{1, 1, 1},
  1502  			counts: map[uint64]uint32{labelRemainA: 32768, labelRemainB: 16384 + 24576},
  1503  		},
  1504  	}
  1505  	checkIndex(t, "remain index", remainIndex, blocksRemain)
  1506  
  1507  	blocks := testGetVolumeBlocks(t, uuid, "labels", true, dvid.Point3d{128, 128, 128}, dvid.Point3d{0, 0, 0})
  1508  	checkVoxels(t, blocks, blocksSplit, blocksRemain)
  1509  }
  1510  
  1511  func checkVoxels(t *testing.T, blocks []labels.PositionedBlock, blocksSplit, blocksRemain []blockCounts) {
  1512  	expected := make(map[uint64]map[uint64]int32)
  1513  	for _, blockSplit := range blocksSplit {
  1514  		zyx, _ := labels.IZYXStringToBlockIndex(blockSplit.bcoord.ToIZYXString())
  1515  		counts, found := expected[zyx]
  1516  		if !found {
  1517  			counts = make(map[uint64]int32)
  1518  		}
  1519  		for sv, count := range blockSplit.counts {
  1520  			counts[sv] = int32(count)
  1521  		}
  1522  		expected[zyx] = counts
  1523  	}
  1524  	for _, blockRemain := range blocksRemain {
  1525  		zyx, _ := labels.IZYXStringToBlockIndex(blockRemain.bcoord.ToIZYXString())
  1526  		counts, found := expected[zyx]
  1527  		if !found {
  1528  			counts = make(map[uint64]int32)
  1529  		}
  1530  		for sv, count := range blockRemain.counts {
  1531  			counts[sv] = int32(count)
  1532  		}
  1533  		expected[zyx] = counts
  1534  	}
  1535  	actual := make(map[uint64]map[uint64]int32)
  1536  	for _, block := range blocks {
  1537  		zyx, _ := labels.IZYXStringToBlockIndex(block.BCoord)
  1538  		got := block.CalcNumLabels(nil)
  1539  		actual[zyx] = got
  1540  		want, found := expected[zyx]
  1541  		if !found {
  1542  			t.Fatalf("Received block %s but wasn't expected block\n", block.BCoord)
  1543  		}
  1544  		for sv, count := range got {
  1545  			wantcount, found := want[sv]
  1546  			if !found {
  1547  				t.Fatalf("got supervoxel %d in block %s but not expected\n", sv, block.BCoord)
  1548  			}
  1549  			if wantcount != count {
  1550  				t.Fatalf("expected supervoxel %d to have %d voxels in block %s, got %d\n", sv, wantcount, block.BCoord, count)
  1551  			}
  1552  		}
  1553  	}
  1554  	for zyx, counts := range expected {
  1555  		bcoord := labels.BlockIndexToIZYXString(zyx)
  1556  		got, found := actual[zyx]
  1557  		if !found {
  1558  			t.Fatalf("Expected to get block %s but not found\n", bcoord)
  1559  		}
  1560  		for sv, count := range counts {
  1561  			gotcount, found := got[sv]
  1562  			if !found {
  1563  				t.Fatalf("expected supervoxel %d in block %s but not received\n", sv, bcoord)
  1564  			}
  1565  			if gotcount != count {
  1566  				t.Fatalf("expected supervoxel %d to have %d voxels in block %s, got %d\n", sv, count, bcoord, gotcount)
  1567  			}
  1568  		}
  1569  	}
  1570  }
  1571  
  1572  func TestSupervoxelSplit2(t *testing.T) {
  1573  	if err := server.OpenTest(); err != nil {
  1574  		t.Fatalf("can't open test server: %v\n", err)
  1575  	}
  1576  	defer server.CloseTest()
  1577  
  1578  	uuid, _ := datastore.NewTestRepo()
  1579  	server.CreateTestInstance(t, uuid, "labelmap", "labels", dvid.Config{})
  1580  
  1581  	labelA := uint64(1000)
  1582  	labelB := uint64(2000)
  1583  
  1584  	data := make([]byte, 128*128*128*8)
  1585  	var x, y, z int32
  1586  	for z = 32; z < 96; z++ {
  1587  		for y = 32; y < 96; y++ {
  1588  			for x = 32; x < 96; x++ {
  1589  				i := (z*128*128 + y*128 + x) * 8
  1590  				binary.LittleEndian.PutUint64(data[i:i+8], labelA)
  1591  			}
  1592  		}
  1593  	}
  1594  	for z = 32; z < 96; z++ {
  1595  		for y = 96; y < 112; y++ {
  1596  			for x = 32; x < 112; x++ {
  1597  				i := (z*128*128 + y*128 + x) * 8
  1598  				binary.LittleEndian.PutUint64(data[i:i+8], labelB)
  1599  			}
  1600  		}
  1601  	}
  1602  	for z = 32; z < 96; z++ {
  1603  		for y = 32; y < 96; y++ {
  1604  			for x = 96; x < 112; x++ {
  1605  				i := (z*128*128 + y*128 + x) * 8
  1606  				binary.LittleEndian.PutUint64(data[i:i+8], labelB)
  1607  			}
  1608  		}
  1609  	}
  1610  	origdata := make([]byte, 128*128*128*8)
  1611  	copy(origdata, data)
  1612  
  1613  	apiStr := fmt.Sprintf("%snode/%s/labels/raw/0_1_2/128_128_128/0_0_0", server.WebAPIPath, uuid)
  1614  	server.TestHTTP(t, "POST", apiStr, bytes.NewBuffer(data))
  1615  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
  1616  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
  1617  	}
  1618  
  1619  	// Get the original body indices
  1620  	origIndexB := getIndex(t, uuid, "labels", labelB)
  1621  	blocksB := []blockCounts{
  1622  		{
  1623  			bcoord: dvid.ChunkPoint3d{1, 0, 0},
  1624  			counts: map[uint64]uint32{labelB: 16384},
  1625  		},
  1626  		{
  1627  			bcoord: dvid.ChunkPoint3d{0, 1, 0},
  1628  			counts: map[uint64]uint32{labelB: 16384},
  1629  		},
  1630  		{
  1631  			bcoord: dvid.ChunkPoint3d{1, 1, 0},
  1632  			counts: map[uint64]uint32{labelB: 16384 + 24576},
  1633  		},
  1634  		{
  1635  			bcoord: dvid.ChunkPoint3d{1, 0, 1},
  1636  			counts: map[uint64]uint32{labelB: 16384},
  1637  		},
  1638  		{
  1639  			bcoord: dvid.ChunkPoint3d{0, 1, 1},
  1640  			counts: map[uint64]uint32{labelB: 16384},
  1641  		},
  1642  		{
  1643  			bcoord: dvid.ChunkPoint3d{1, 1, 1},
  1644  			counts: map[uint64]uint32{labelB: 16384 + 24576},
  1645  		},
  1646  	}
  1647  	checkIndex(t, "original index B", origIndexB, blocksB)
  1648  
  1649  	// do a bad split
  1650  	var split dvid.RLEs
  1651  	x = 56
  1652  	for z = 32; z < 96; z++ {
  1653  		for y = 32; y < 64; y++ {
  1654  			split = append(split, dvid.NewRLE(dvid.Point3d{x, y, z}, 40))
  1655  		}
  1656  	}
  1657  	x = 80
  1658  	for z = 32; z < 48; z++ {
  1659  		for y = 64; y < 100; y++ {
  1660  			split = append(split, dvid.NewRLE(dvid.Point3d{x, y, z}, 8))
  1661  		}
  1662  	}
  1663  	_, splitRuns := split.Stats()
  1664  
  1665  	buf := new(bytes.Buffer)
  1666  	buf.WriteByte(dvid.EncodingBinary)
  1667  	binary.Write(buf, binary.LittleEndian, uint8(3))          // # of dimensions
  1668  	binary.Write(buf, binary.LittleEndian, byte(0))           // dimension of run (X = 0)
  1669  	buf.WriteByte(byte(0))                                    // reserved for later
  1670  	binary.Write(buf, binary.LittleEndian, uint32(0))         // Placeholder for # voxels
  1671  	binary.Write(buf, binary.LittleEndian, uint32(splitRuns)) // Placeholder for # spans
  1672  	splitBytes, err := split.MarshalBinary()
  1673  	if err != nil {
  1674  		t.Errorf("Unable to serialize RLEs: %v\n", err)
  1675  	}
  1676  	buf.Write(splitBytes)
  1677  
  1678  	apiStr = fmt.Sprintf("%snode/%s/labels/split-supervoxel/%d?split=189417&remain=8506273", server.WebAPIPath, uuid, labelB)
  1679  	server.TestBadHTTP(t, "POST", apiStr, buf)
  1680  
  1681  	// make sure indices and volume is not changed
  1682  	afterBadSplit := getIndex(t, uuid, "labels", labelB)
  1683  	checkIndex(t, "label B after bad split", afterBadSplit, blocksB)
  1684  
  1685  	postvol := newTestVolume(128, 128, 128)
  1686  	postvol.get(t, uuid, "labels", true)
  1687  	oldvol := testVolume{
  1688  		data: origdata,
  1689  		size: dvid.Point3d{128, 128, 128},
  1690  	}
  1691  	if err := oldvol.equals(postvol); err != nil {
  1692  		t.Fatalf("bad supervoxel volume get after aborted supervoxel split: %v\n", err)
  1693  	}
  1694  	postvol.get(t, uuid, "labels", false)
  1695  	if err := oldvol.equals(postvol); err != nil {
  1696  		t.Fatalf("bad label volume get after aborted supervoxel split: %v\n", err)
  1697  	}
  1698  
  1699  	// run valid split
  1700  	split = nil
  1701  	x = 96
  1702  	for z = 32; z < 96; z++ {
  1703  		for y = 32; y < 96; y++ {
  1704  			split = append(split, dvid.NewRLE(dvid.Point3d{x, y, z}, 16))
  1705  		}
  1706  	}
  1707  	_, splitRuns = split.Stats()
  1708  
  1709  	buf = new(bytes.Buffer)
  1710  	buf.WriteByte(dvid.EncodingBinary)
  1711  	binary.Write(buf, binary.LittleEndian, uint8(3))          // # of dimensions
  1712  	binary.Write(buf, binary.LittleEndian, byte(0))           // dimension of run (X = 0)
  1713  	buf.WriteByte(byte(0))                                    // reserved for later
  1714  	binary.Write(buf, binary.LittleEndian, uint32(0))         // Placeholder for # voxels
  1715  	binary.Write(buf, binary.LittleEndian, uint32(splitRuns)) // Placeholder for # spans
  1716  	splitBytes, err = split.MarshalBinary()
  1717  	if err != nil {
  1718  		t.Errorf("Unable to serialize RLEs: %v\n", err)
  1719  	}
  1720  	buf.Write(splitBytes)
  1721  
  1722  	r := server.TestHTTP(t, "POST", apiStr, buf)
  1723  	var resp struct {
  1724  		Split  uint64 `json:"SplitSupervoxel"`
  1725  		Remain uint64 `json:"RemainSupervoxel"`
  1726  	}
  1727  	if err := json.Unmarshal(r, &resp); err != nil {
  1728  		t.Errorf("Unable to get new labels from supervoxel split.  Instead got: %v\n", resp)
  1729  	}
  1730  	dvid.Infof("supervoxel split %d -> split %d, remain %d\n", labelB, resp.Split, resp.Remain)
  1731  	if resp.Split != 189417 || resp.Remain != 8506273 {
  1732  		t.Errorf("bad split/remain supervoxel labels: %v\n", resp)
  1733  	}
  1734  
  1735  	// label B index shouldn't have changed
  1736  	splitIndexB := getIndex(t, uuid, "labels", labelB)
  1737  	blocksSplitB := []blockCounts{
  1738  		{
  1739  			bcoord: dvid.ChunkPoint3d{1, 0, 0},
  1740  			counts: map[uint64]uint32{resp.Split: 16384},
  1741  		},
  1742  		{
  1743  			bcoord: dvid.ChunkPoint3d{0, 1, 0},
  1744  			counts: map[uint64]uint32{resp.Remain: 16384},
  1745  		},
  1746  		{
  1747  			bcoord: dvid.ChunkPoint3d{1, 1, 0},
  1748  			counts: map[uint64]uint32{resp.Split: 16384, resp.Remain: 24576},
  1749  		},
  1750  		{
  1751  			bcoord: dvid.ChunkPoint3d{1, 0, 1},
  1752  			counts: map[uint64]uint32{resp.Split: 16384},
  1753  		},
  1754  		{
  1755  			bcoord: dvid.ChunkPoint3d{0, 1, 1},
  1756  			counts: map[uint64]uint32{resp.Remain: 16384},
  1757  		},
  1758  		{
  1759  			bcoord: dvid.ChunkPoint3d{1, 1, 1},
  1760  			counts: map[uint64]uint32{resp.Split: 16384, resp.Remain: 24576},
  1761  		},
  1762  	}
  1763  	checkIndex(t, "split index B", splitIndexB, blocksSplitB)
  1764  
  1765  	// supervoxels should have changed
  1766  	blocksA := []blockCounts{
  1767  		{
  1768  			bcoord: dvid.ChunkPoint3d{0, 0, 0},
  1769  			counts: map[uint64]uint32{labelA: 32768},
  1770  		},
  1771  		{
  1772  			bcoord: dvid.ChunkPoint3d{1, 0, 0},
  1773  			counts: map[uint64]uint32{labelA: 32768},
  1774  		},
  1775  		{
  1776  			bcoord: dvid.ChunkPoint3d{0, 1, 0},
  1777  			counts: map[uint64]uint32{labelA: 32768},
  1778  		},
  1779  		{
  1780  			bcoord: dvid.ChunkPoint3d{1, 1, 0},
  1781  			counts: map[uint64]uint32{labelA: 32768},
  1782  		},
  1783  		{
  1784  			bcoord: dvid.ChunkPoint3d{0, 0, 1},
  1785  			counts: map[uint64]uint32{labelA: 32768},
  1786  		},
  1787  		{
  1788  			bcoord: dvid.ChunkPoint3d{1, 0, 1},
  1789  			counts: map[uint64]uint32{labelA: 32768},
  1790  		},
  1791  		{
  1792  			bcoord: dvid.ChunkPoint3d{0, 1, 1},
  1793  			counts: map[uint64]uint32{labelA: 32768},
  1794  		},
  1795  		{
  1796  			bcoord: dvid.ChunkPoint3d{1, 1, 1},
  1797  			counts: map[uint64]uint32{labelA: 32768},
  1798  		},
  1799  	}
  1800  	blocks := testGetVolumeBlocks(t, uuid, "labels", true, dvid.Point3d{128, 128, 128}, dvid.Point3d{0, 0, 0})
  1801  	checkVoxels(t, blocks, blocksSplitB, blocksA)
  1802  }
  1803  
  1804  func testSplitSupervoxel(t *testing.T, testEnclosing bool) {
  1805  	if err := server.OpenTest(); err != nil {
  1806  		t.Fatalf("can't open test server: %v\n", err)
  1807  	}
  1808  	defer server.CloseTest()
  1809  
  1810  	// Create testbed volume and data instances
  1811  	uuid, _ := initTestRepo()
  1812  	var config dvid.Config
  1813  	config.Set("MaxDownresLevel", "2")
  1814  	config.Set("BlockSize", "32,32,32") // Previous test data was on 32^3 blocks
  1815  	server.CreateTestInstance(t, uuid, "labelmap", "labels", config)
  1816  
  1817  	// Post supervoxel volume
  1818  	original := createLabelTestVolume(t, uuid, "labels")
  1819  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
  1820  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
  1821  	}
  1822  
  1823  	reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/4", server.WebAPIPath, uuid)
  1824  	encoding := server.TestHTTP(t, "GET", reqStr, nil)
  1825  	body4.checkSparseVol(t, encoding, dvid.OptionalBounds{})
  1826  
  1827  	if testEnclosing {
  1828  		testMerge := mergeJSON(`[3, 4]`)
  1829  		testMerge.send(t, uuid, "labels")
  1830  
  1831  		reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/3", server.WebAPIPath, uuid)
  1832  		encoding = server.TestHTTP(t, "GET", reqStr, nil)
  1833  	}
  1834  
  1835  	// Create the sparsevol encoding for split area
  1836  	numspans := len(bodysplit.voxelSpans)
  1837  	rles := make(dvid.RLEs, numspans, numspans)
  1838  	for i, span := range bodysplit.voxelSpans {
  1839  		start := dvid.Point3d{span[2], span[1], span[0]}
  1840  		length := span[3] - span[2] + 1
  1841  		rles[i] = dvid.NewRLE(start, length)
  1842  	}
  1843  
  1844  	// Create the split sparse volume binary
  1845  	buf := new(bytes.Buffer)
  1846  	buf.WriteByte(dvid.EncodingBinary)
  1847  	binary.Write(buf, binary.LittleEndian, uint8(3))         // # of dimensions
  1848  	binary.Write(buf, binary.LittleEndian, byte(0))          // dimension of run (X = 0)
  1849  	buf.WriteByte(byte(0))                                   // reserved for later
  1850  	binary.Write(buf, binary.LittleEndian, uint32(0))        // Placeholder for # voxels
  1851  	binary.Write(buf, binary.LittleEndian, uint32(numspans)) // Placeholder for # spans
  1852  	rleBytes, err := rles.MarshalBinary()
  1853  	if err != nil {
  1854  		t.Errorf("Unable to serialize RLEs: %v\n", err)
  1855  	}
  1856  	buf.Write(rleBytes)
  1857  
  1858  	// Verify the max label is 4
  1859  	reqStr = fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid)
  1860  	jsonStr := server.TestHTTP(t, "GET", reqStr, nil)
  1861  	expectedJSON := `{"maxlabel": 4}`
  1862  	if string(jsonStr) != expectedJSON {
  1863  		t.Errorf("Expected this JSON returned from maxlabel:\n%s\nGot:\n%s\n", expectedJSON, string(jsonStr))
  1864  	}
  1865  
  1866  	// Submit the split sparsevol for supervoxel 4 using RLES "bodysplit"
  1867  	reqStr = fmt.Sprintf("%snode/%s/labels/split-supervoxel/4", server.WebAPIPath, uuid)
  1868  	r := server.TestHTTP(t, "POST", reqStr, buf)
  1869  	var jsonVal struct {
  1870  		SplitSupervoxel  uint64
  1871  		RemainSupervoxel uint64
  1872  	}
  1873  	if err := json.Unmarshal(r, &jsonVal); err != nil {
  1874  		t.Errorf("Unable to get new label from split.  Instead got: %v\n", jsonVal)
  1875  	}
  1876  	if jsonVal.SplitSupervoxel != 5 {
  1877  		t.Errorf("Expected split label to be 5, instead got %d\n", jsonVal.SplitSupervoxel)
  1878  	}
  1879  	if jsonVal.RemainSupervoxel != 6 {
  1880  		t.Errorf("Expected remain label to be 6, instead got %d\n", jsonVal.RemainSupervoxel)
  1881  	}
  1882  	reqStr = fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid)
  1883  	jsonStr = server.TestHTTP(t, "GET", reqStr, nil)
  1884  	expectedJSON = `{"maxlabel": 6}`
  1885  	if string(jsonStr) != expectedJSON {
  1886  		t.Errorf("Expected this JSON returned from maxlabel:\n%s\nGot:\n%s\n", expectedJSON, string(jsonStr))
  1887  	}
  1888  
  1889  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
  1890  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
  1891  	}
  1892  
  1893  	// Make sure retrieved body voxels are same as original
  1894  	retrieved := newTestVolume(128, 128, 128)
  1895  	retrieved.get(t, uuid, "labels", false)
  1896  	if len(retrieved.data) != 8*128*128*128 {
  1897  		t.Errorf("Retrieved post-split volume is incorrect size\n")
  1898  	}
  1899  	if testEnclosing {
  1900  		original.addBody(body4, 3)
  1901  	}
  1902  	if err := original.equals(retrieved); err != nil {
  1903  		t.Errorf("Post-supervoxel split label volume not equal to expected volume: %v\n", err)
  1904  	}
  1905  	downres1 := newTestVolume(64, 64, 64)
  1906  	downres1.getScale(t, uuid, "labels", 1, false)
  1907  	if err := downres1.equalsDownres(original); err != nil {
  1908  		t.Errorf("split supervoxel volume failed level 1 down-scale: %v\n", err)
  1909  	}
  1910  	downres2 := newTestVolume(32, 32, 32)
  1911  	downres2.getScale(t, uuid, "labels", 2, false)
  1912  	if err := downres2.equalsDownres(downres1); err != nil {
  1913  		t.Errorf("split supervoxel volume failed level 2 down-scale: %v\n", err)
  1914  	}
  1915  
  1916  	// Make sure retrieved supervoxels are correct
  1917  	retrieved.get(t, uuid, "labels", true)
  1918  	if testEnclosing {
  1919  		original.addBody(body4, 4)
  1920  	}
  1921  	original.addBody(bodysplit, 5)
  1922  	original.addBody(bodyleft, 6)
  1923  	if err := original.equals(retrieved); err != nil {
  1924  		t.Errorf("Post-supervoxel split supervoxel volume not equal to expected supervoxels: %v\n", err)
  1925  	}
  1926  
  1927  	// Check split body hasn't changed usine legacy RLEs
  1928  	if testEnclosing {
  1929  		reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/3", server.WebAPIPath, uuid)
  1930  	} else {
  1931  		reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/4", server.WebAPIPath, uuid)
  1932  	}
  1933  	splitBody := server.TestHTTP(t, "GET", reqStr, nil)
  1934  	if !bytes.Equal(splitBody, encoding) {
  1935  		t.Errorf("split body after supervoxel split has changed incorrectly!\n")
  1936  	}
  1937  }
  1938  
  1939  func TestSplitSupervoxel(t *testing.T) {
  1940  	dvid.Infof("Testing non-agglomerated supervoxel...\n")
  1941  	testSplitSupervoxel(t, false)
  1942  	dvid.Infof("Testing agglomerated supervoxel...\n")
  1943  	testSplitSupervoxel(t, true)
  1944  }
  1945  
  1946  func TestCompleteSplitSupervoxel(t *testing.T) {
  1947  	if err := server.OpenTest(); err != nil {
  1948  		t.Fatalf("can't open test server: %v\n", err)
  1949  	}
  1950  	defer server.CloseTest()
  1951  
  1952  	// Create testbed volume and data instances
  1953  	uuid, _ := initTestRepo()
  1954  	var config dvid.Config
  1955  	config.Set("BlockSize", "32,32,32") // Previous test data was on 32^3 blocks
  1956  	server.CreateTestInstance(t, uuid, "labelmap", "labels", config)
  1957  
  1958  	// Post supervoxel volume
  1959  	original := createLabelTestVolume(t, uuid, "labels")
  1960  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
  1961  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
  1962  	}
  1963  
  1964  	reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/4", server.WebAPIPath, uuid)
  1965  	encoding := server.TestHTTP(t, "GET", reqStr, nil)
  1966  	body4.checkSparseVol(t, encoding, dvid.OptionalBounds{})
  1967  
  1968  	// Create the sparsevol encoding for split area
  1969  	numspans := len(body4.voxelSpans)
  1970  	rles := make(dvid.RLEs, numspans, numspans)
  1971  	for i, span := range body4.voxelSpans {
  1972  		start := dvid.Point3d{span[2], span[1], span[0]}
  1973  		length := span[3] - span[2] + 1
  1974  		rles[i] = dvid.NewRLE(start, length)
  1975  	}
  1976  
  1977  	// Create the split sparse volume binary
  1978  	buf := new(bytes.Buffer)
  1979  	buf.WriteByte(dvid.EncodingBinary)
  1980  	binary.Write(buf, binary.LittleEndian, uint8(3))         // # of dimensions
  1981  	binary.Write(buf, binary.LittleEndian, byte(0))          // dimension of run (X = 0)
  1982  	buf.WriteByte(byte(0))                                   // reserved for later
  1983  	binary.Write(buf, binary.LittleEndian, uint32(0))        // Placeholder for # voxels
  1984  	binary.Write(buf, binary.LittleEndian, uint32(numspans)) // Placeholder for # spans
  1985  	rleBytes, err := rles.MarshalBinary()
  1986  	if err != nil {
  1987  		t.Errorf("Unable to serialize RLEs: %v\n", err)
  1988  	}
  1989  	buf.Write(rleBytes)
  1990  
  1991  	// Before split, the supervoxel should be mapped to itself.
  1992  	mappedSV := getSVMapping(t, uuid, "labels", 4)
  1993  	if mappedSV != 4 {
  1994  		t.Fatalf("Expected supervoxel 4 to be mapped to itself before split.  Got %d instead.\n", mappedSV)
  1995  	}
  1996  
  1997  	// Submit the split sparsevol for supervoxel 4 using its entire body
  1998  	reqStr = fmt.Sprintf("%snode/%s/labels/split-supervoxel/4", server.WebAPIPath, uuid)
  1999  	r := server.TestHTTP(t, "POST", reqStr, buf)
  2000  	var jsonVal struct {
  2001  		SplitSupervoxel  uint64
  2002  		RemainSupervoxel uint64
  2003  	}
  2004  	if err := json.Unmarshal(r, &jsonVal); err != nil {
  2005  		t.Errorf("Unable to get new label from split.  Instead got: %v\n", jsonVal)
  2006  	}
  2007  	if jsonVal.SplitSupervoxel != 5 {
  2008  		t.Errorf("Expected split label to be 5, instead got %d\n", jsonVal.SplitSupervoxel)
  2009  	}
  2010  	if jsonVal.RemainSupervoxel != 6 {
  2011  		t.Errorf("Expected remain label to be 6, instead got %d\n", jsonVal.RemainSupervoxel)
  2012  	}
  2013  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
  2014  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
  2015  	}
  2016  
  2017  	// Make sure the split supervoxel is now mapped to 0.
  2018  	mappedSV = getSVMapping(t, uuid, "labels", 4)
  2019  	if mappedSV != 0 {
  2020  		t.Fatalf("Expected supervoxel 4 to map to 0 after split.  Got %d instead.\n", mappedSV)
  2021  	}
  2022  
  2023  	// Make sure retrieved body voxels are same as original
  2024  	retrieved := newTestVolume(128, 128, 128)
  2025  	retrieved.get(t, uuid, "labels", false)
  2026  	if len(retrieved.data) != 8*128*128*128 {
  2027  		t.Errorf("Retrieved post-split volume is incorrect size\n")
  2028  	}
  2029  	if err := original.equals(retrieved); err != nil {
  2030  		t.Errorf("Post-supervoxel split label volume not equal to expected volume: %v\n", err)
  2031  	}
  2032  
  2033  	// Submit the split sparsevol for supervoxel 4 using no RLEs
  2034  	buf = new(bytes.Buffer)
  2035  	buf.WriteByte(dvid.EncodingBinary)
  2036  	binary.Write(buf, binary.LittleEndian, uint8(3))  // # of dimensions
  2037  	binary.Write(buf, binary.LittleEndian, byte(0))   // dimension of run (X = 0)
  2038  	buf.WriteByte(byte(0))                            // reserved for later
  2039  	binary.Write(buf, binary.LittleEndian, uint32(0)) // Placeholder for # voxels
  2040  	binary.Write(buf, binary.LittleEndian, uint32(0)) // Placeholder for # spans
  2041  
  2042  	reqStr = fmt.Sprintf("%snode/%s/labels/split-supervoxel/5", server.WebAPIPath, uuid)
  2043  	r = server.TestHTTP(t, "POST", reqStr, buf)
  2044  	if err := json.Unmarshal(r, &jsonVal); err != nil {
  2045  		t.Errorf("Unable to get new label from split.  Instead got: %v\n", jsonVal)
  2046  	}
  2047  	if jsonVal.SplitSupervoxel != 7 {
  2048  		t.Errorf("Expected split label to be 5, instead got %d\n", jsonVal.SplitSupervoxel)
  2049  	}
  2050  	if jsonVal.RemainSupervoxel != 8 {
  2051  		t.Errorf("Expected remain label to be 6, instead got %d\n", jsonVal.RemainSupervoxel)
  2052  	}
  2053  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
  2054  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
  2055  	}
  2056  
  2057  	// Make sure retrieved body voxels are same as original
  2058  	retrieved = newTestVolume(128, 128, 128)
  2059  	retrieved.get(t, uuid, "labels", false)
  2060  	if len(retrieved.data) != 8*128*128*128 {
  2061  		t.Errorf("Retrieved post-split volume is incorrect size\n")
  2062  	}
  2063  	if err := original.equals(retrieved); err != nil {
  2064  		t.Errorf("Post-supervoxel split label volume not equal to expected volume: %v\n", err)
  2065  	}
  2066  }
  2067  
  2068  type labelType interface {
  2069  	GetLabelPoints(dvid.VersionID, []dvid.Point3d, uint8, bool) ([]uint64, error)
  2070  	GetPointsInSupervoxels(dvid.VersionID, []dvid.Point3d, []uint64) ([]bool, error)
  2071  }
  2072  
  2073  func TestMergeCleave(t *testing.T) {
  2074  	if err := server.OpenTest(); err != nil {
  2075  		t.Fatalf("can't open test server: %v\n", err)
  2076  	}
  2077  	defer server.CloseTest()
  2078  
  2079  	// Create testbed volume and data instances
  2080  	uuid, _ := initTestRepo()
  2081  	var config dvid.Config
  2082  	config.Set("BlockSize", "32,32,32") // Previous test data was on 32^3 blocks
  2083  	server.CreateTestInstance(t, uuid, "labelmap", "labels", config)
  2084  
  2085  	// Post standard label 1-4 volume
  2086  	expected := createLabelTestVolume(t, uuid, "labels")
  2087  
  2088  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
  2089  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
  2090  	}
  2091  
  2092  	reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/4", server.WebAPIPath, uuid)
  2093  	sv4encoding := server.TestHTTP(t, "GET", reqStr, nil)
  2094  	body4.checkSparseVol(t, sv4encoding, dvid.OptionalBounds{})
  2095  
  2096  	// Check direct label queries for points
  2097  	pts := []dvid.Point3d{
  2098  		{25, 40, 15}, // body 1
  2099  		{15, 57, 34},
  2100  		{30, 27, 57}, // body 2
  2101  		{63, 39, 45},
  2102  		{59, 56, 39}, // body 3
  2103  		{75, 40, 73}, // body 4
  2104  	}
  2105  	d, err := datastore.GetDataByUUIDName(uuid, "labels")
  2106  	if err != nil {
  2107  		t.Fatalf("Can't get labels instance from test db: %v\n", err)
  2108  	}
  2109  	labeldata, ok := d.(labelType)
  2110  	if !ok {
  2111  		t.Fatalf("Didn't get labels data that conforms to expected functions.\n")
  2112  	}
  2113  	v, err := datastore.VersionFromUUID(uuid)
  2114  	if err != nil {
  2115  		t.Fatalf("couldn't get version from UUID\n")
  2116  	}
  2117  	mapped, err := labeldata.GetLabelPoints(v, pts, 0, false)
  2118  	if err != nil {
  2119  		t.Errorf("bad response to GetLabelsPoints: %v\n", err)
  2120  	}
  2121  	if len(mapped) != 6 || !reflect.DeepEqual(mapped, []uint64{1, 1, 2, 2, 3, 4}) {
  2122  		t.Fatalf("bad return from GetLabelPoints: %v\n", mapped)
  2123  	}
  2124  	inSupervoxels, err := labeldata.GetPointsInSupervoxels(v, pts, []uint64{1})
  2125  	if err != nil {
  2126  		t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err)
  2127  	}
  2128  	if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{true, true, false, false, false, false}) {
  2129  		t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels)
  2130  	}
  2131  	inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{3})
  2132  	if err != nil {
  2133  		t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err)
  2134  	}
  2135  	if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, true, false}) {
  2136  		t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels)
  2137  	}
  2138  
  2139  	// Merge of 3 into 4
  2140  	testMerge := mergeJSON(`[4, 3]`)
  2141  	testMerge.send(t, uuid, "labels")
  2142  
  2143  	reqStr = fmt.Sprintf("%snode/%s/labels/lastmod/4", server.WebAPIPath, uuid)
  2144  	r := server.TestHTTP(t, "GET", reqStr, nil)
  2145  	var infoVal struct {
  2146  		MutID uint64 `json:"mutation id"`
  2147  		User  string `json:"last mod user"`
  2148  		App   string `json:"last mod app"`
  2149  		Time  string `json:"last mod time"`
  2150  	}
  2151  	if err := json.Unmarshal(r, &infoVal); err != nil {
  2152  		t.Fatalf("unable to get mod info for label 4: %v", err)
  2153  	}
  2154  	if infoVal.MutID != datastore.InitialMutationID+1 {
  2155  		t.Errorf("expected mutation id %d, got %d\n", datastore.InitialMutationID+1, infoVal.MutID)
  2156  	}
  2157  
  2158  	// Check direct label queries for points after merge
  2159  	mapped, err = labeldata.GetLabelPoints(v, pts, 0, false)
  2160  	if err != nil {
  2161  		t.Errorf("bad response to GetLabelsPoints: %v\n", err)
  2162  	}
  2163  	if len(mapped) != 6 || !reflect.DeepEqual(mapped, []uint64{1, 1, 2, 2, 4, 4}) {
  2164  		t.Fatalf("bad return from GetLabelPoints: %v\n", mapped)
  2165  	}
  2166  	inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{3})
  2167  	if err != nil {
  2168  		t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err)
  2169  	}
  2170  	if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, true, false}) {
  2171  		t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels)
  2172  	}
  2173  	inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{4})
  2174  	if err != nil {
  2175  		t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err)
  2176  	}
  2177  	if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, false, true}) {
  2178  		t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels)
  2179  	}
  2180  	inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{3, 4})
  2181  	if err != nil {
  2182  		t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err)
  2183  	}
  2184  	if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, true, true}) {
  2185  		t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels)
  2186  	}
  2187  
  2188  	// Check sizes
  2189  	reqStr = fmt.Sprintf("%snode/%s/labels/size/4", server.WebAPIPath, uuid)
  2190  	r = server.TestHTTP(t, "GET", reqStr, nil)
  2191  	var jsonVal struct {
  2192  		Voxels uint64 `json:"voxels"`
  2193  	}
  2194  	if err := json.Unmarshal(r, &jsonVal); err != nil {
  2195  		t.Fatalf("unable to get size for label 4: %v", err)
  2196  	}
  2197  	voxelsIn3 := body3.voxelSpans.Count()
  2198  	voxelsIn4 := body4.voxelSpans.Count()
  2199  	if jsonVal.Voxels != voxelsIn3+voxelsIn4 {
  2200  		t.Errorf("thought label 4 would have %d voxels, got %d\n", voxelsIn3+voxelsIn4, jsonVal.Voxels)
  2201  	}
  2202  	reqStr = fmt.Sprintf("%snode/%s/labels/size/4?supervoxels=true", server.WebAPIPath, uuid)
  2203  	r = server.TestHTTP(t, "GET", reqStr, nil)
  2204  	if err := json.Unmarshal(r, &jsonVal); err != nil {
  2205  		t.Fatalf("unable to get size for supervoxel 4: %v", err)
  2206  	}
  2207  	if jsonVal.Voxels != voxelsIn4 {
  2208  		t.Errorf("thought supervoxel 4 would have %d voxels, got %d\n", voxelsIn4, jsonVal.Voxels)
  2209  	}
  2210  
  2211  	// Make sure label 3 sparsevol has been removed.
  2212  	reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, 3)
  2213  	server.TestBadHTTP(t, "GET", reqStr, nil)
  2214  
  2215  	retrieved := newTestVolume(128, 128, 128)
  2216  	retrieved.get(t, uuid, "labels", false)
  2217  	if len(retrieved.data) != 8*128*128*128 {
  2218  		t.Errorf("Retrieved label volume is incorrect size\n")
  2219  	}
  2220  	if !retrieved.isLabel(2, &body2) {
  2221  		t.Errorf("Expected label 2 original voxels to remain.  Instead some were removed.\n")
  2222  	}
  2223  	if retrieved.hasLabel(3, &body3) {
  2224  		t.Errorf("Found label 3 when all label 3 should have been merged into label 4!\n")
  2225  	}
  2226  	if !retrieved.isLabel(4, &body3) {
  2227  		t.Errorf("Incomplete merging.  Label 4 should have taken over full extent of label 3\n")
  2228  	}
  2229  	expected.addBody(body3, 4)
  2230  	if err := retrieved.equals(expected); err != nil {
  2231  		t.Errorf("Merged label volume not equal to expected merged volume: %v\n", err)
  2232  	}
  2233  
  2234  	retrieved.get(t, uuid, "labels", true) // check supervoxels
  2235  	if len(retrieved.data) != 8*128*128*128 {
  2236  		t.Errorf("Retrieved supervoxel volume is incorrect size\n")
  2237  	}
  2238  	if !retrieved.isLabel(1, &body1) {
  2239  		t.Errorf("Expected supervoxel 1 original voxels to remain.  Instead some were removed.\n")
  2240  	}
  2241  	if !retrieved.isLabel(2, &body2) {
  2242  		t.Errorf("Expected supervoxel 2 original voxels to remain.  Instead some were removed.\n")
  2243  	}
  2244  	if !retrieved.hasLabel(3, &body3) {
  2245  		t.Errorf("Expected supervoxel 3 original voxels to remain.  Instead some were removed.\n")
  2246  	}
  2247  	if !retrieved.isLabel(4, &body4) {
  2248  		t.Errorf("Expected supervoxel 4 original voxels to remain.  Instead some were removed.\n")
  2249  	}
  2250  
  2251  	// Cleave supervoxel 3 out of label 4.
  2252  	reqStr = fmt.Sprintf("%snode/%s/labels/cleave/4?u=mrsmith&app=myapp", server.WebAPIPath, uuid)
  2253  	r = server.TestHTTP(t, "POST", reqStr, bytes.NewBufferString("[3]"))
  2254  	var jsonVal2 struct {
  2255  		CleavedLabel uint64
  2256  	}
  2257  	if err := json.Unmarshal(r, &jsonVal2); err != nil {
  2258  		t.Errorf("Unable to get new label from cleave.  Instead got: %v\n", jsonVal2)
  2259  	}
  2260  
  2261  	reqStr = fmt.Sprintf("%snode/%s/labels/lastmod/4", server.WebAPIPath, uuid)
  2262  	r = server.TestHTTP(t, "GET", reqStr, nil)
  2263  	if err := json.Unmarshal(r, &infoVal); err != nil {
  2264  		t.Fatalf("unable to get mod info for label 4: %v", err)
  2265  	}
  2266  	if infoVal.MutID != datastore.InitialMutationID+2 || infoVal.App != "myapp" || infoVal.User != "mrsmith" {
  2267  		t.Errorf("unexpected last mod info: %v\n", infoVal)
  2268  	}
  2269  
  2270  	reqStr = fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid)
  2271  	jsonStr := server.TestHTTP(t, "GET", reqStr, nil)
  2272  	expectedJSON := `{"maxlabel": 5}`
  2273  	if string(jsonStr) != expectedJSON {
  2274  		t.Errorf("Expected this JSON returned from maxlabel:\n%s\nGot:\n%s\n", expectedJSON, string(jsonStr))
  2275  	}
  2276  
  2277  	retrieved.get(t, uuid, "labels", false)
  2278  	if len(retrieved.data) != 8*128*128*128 {
  2279  		t.Fatalf("Retrieved label volume is incorrect size\n")
  2280  	}
  2281  	expected.addBody(body3, 5)
  2282  	if err := expected.equals(retrieved); err != nil {
  2283  		t.Fatalf("Post-cleave label volume not equal to expected volume: %v\n", err)
  2284  	}
  2285  
  2286  	retrieved.get(t, uuid, "labels", true)
  2287  	if len(retrieved.data) != 8*128*128*128 {
  2288  		t.Fatalf("Retrieved supervoxel volume is incorrect size\n")
  2289  	}
  2290  	expected.addBody(body3, 3)
  2291  	if err := expected.equals(retrieved); err != nil {
  2292  		t.Fatalf("Post-cleave supervoxel volume not equal to expected volume: %v\n", err)
  2293  	}
  2294  
  2295  	// supervoxel 3 (original body 3) should now be label 5
  2296  	reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/5", server.WebAPIPath, uuid)
  2297  	encoding := server.TestHTTP(t, "GET", reqStr, nil)
  2298  	body3.checkSparseVol(t, encoding, dvid.OptionalBounds{})
  2299  
  2300  	// make sure you can't cleave all supervoxels from a label
  2301  	reqStr = fmt.Sprintf("%snode/%s/labels/cleave/4", server.WebAPIPath, uuid)
  2302  	server.TestBadHTTP(t, "POST", reqStr, bytes.NewBufferString("[4]"))
  2303  
  2304  	// Check direct label queries for points after cleave
  2305  	mapped, err = labeldata.GetLabelPoints(v, pts, 0, false)
  2306  	if err != nil {
  2307  		t.Errorf("bad response to GetLabelsPoints: %v\n", err)
  2308  	}
  2309  	if len(mapped) != 6 || !reflect.DeepEqual(mapped, []uint64{1, 1, 2, 2, 5, 4}) {
  2310  		t.Fatalf("bad return from GetLabelPoints: %v\n", mapped)
  2311  	}
  2312  	inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{3})
  2313  	if err != nil {
  2314  		t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err)
  2315  	}
  2316  	if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, true, false}) {
  2317  		t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels)
  2318  	}
  2319  	inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{4})
  2320  	if err != nil {
  2321  		t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err)
  2322  	}
  2323  	if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, false, true}) {
  2324  		t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels)
  2325  	}
  2326  	inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{4})
  2327  	if err != nil {
  2328  		t.Fatalf("bad response to GetPointsInSupervoxels: %v\n", err)
  2329  	}
  2330  	if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, false, true}) {
  2331  		t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels)
  2332  	}
  2333  	inSupervoxels, err = labeldata.GetPointsInSupervoxels(v, pts, []uint64{3})
  2334  	if err != nil {
  2335  		t.Errorf("bad response to GetPointsInSupervoxels: %v\n", err)
  2336  	}
  2337  	if len(inSupervoxels) != 6 || !reflect.DeepEqual(inSupervoxels, []bool{false, false, false, false, true, false}) {
  2338  		t.Fatalf("bad return from GetPointsInSupervoxels: %v\n", inSupervoxels)
  2339  	}
  2340  
  2341  	// Check storage stats
  2342  	stats, err := datastore.GetStorageDetails()
  2343  	if err != nil {
  2344  		t.Fatalf("error getting storage details: %v\n", err)
  2345  	}
  2346  	dvid.Infof("storage details: %s\n", stats)
  2347  }
  2348  
  2349  func TestMultiscaleMergeCleave(t *testing.T) {
  2350  	testConfig := server.TestConfig{CacheSize: map[string]int{"labelmap": 10}}
  2351  	// var testConfig server.TestConfig
  2352  	if err := server.OpenTest(testConfig); err != nil {
  2353  		t.Fatalf("can't open test server: %v\n", err)
  2354  	}
  2355  	defer server.CloseTest()
  2356  
  2357  	// Create testbed volume
  2358  	uuid, _ := initTestRepo()
  2359  	var config dvid.Config
  2360  	config.Set("MaxDownresLevel", "2")
  2361  	server.CreateTestInstance(t, uuid, "labelmap", "labels", config)
  2362  
  2363  	// Create an easily interpreted label volume with a couple of labels.
  2364  	volume := newTestVolume(128, 128, 128)
  2365  	volume.addSubvol(dvid.Point3d{40, 40, 40}, dvid.Point3d{40, 40, 40}, 1)
  2366  	volume.addSubvol(dvid.Point3d{40, 40, 80}, dvid.Point3d{40, 40, 40}, 2)
  2367  	volume.addSubvol(dvid.Point3d{80, 40, 40}, dvid.Point3d{40, 40, 40}, 13)
  2368  	volume.addSubvol(dvid.Point3d{40, 80, 40}, dvid.Point3d{40, 40, 40}, 209)
  2369  	volume.addSubvol(dvid.Point3d{80, 80, 40}, dvid.Point3d{40, 40, 40}, 311)
  2370  	volume.put(t, uuid, "labels")
  2371  
  2372  	// Verify initial ingest for hi-res
  2373  	if err := downres.BlockOnUpdating(uuid, "labels"); err != nil {
  2374  		t.Fatalf("Error blocking on update for labels: %v\n", err)
  2375  	}
  2376  
  2377  	sizeReq := fmt.Sprintf("%snode/%s/labels/sparsevol-size/1", server.WebAPIPath, uuid)
  2378  	sizeResp := server.TestHTTP(t, "GET", sizeReq, nil)
  2379  	if string(sizeResp) != `{"voxels": 64000, "numblocks": 8, "minvoxel": [0, 0, 0], "maxvoxel": [127, 127, 127]}` {
  2380  		t.Errorf("bad response to sparsevol-size endpoint: %s\n", string(sizeResp))
  2381  	}
  2382  
  2383  	testPoints0 := map[uint64][3]int32{
  2384  		0:   {18, 18, 18},
  2385  		1:   {45, 45, 45},
  2386  		2:   {50, 50, 100},
  2387  		13:  {100, 60, 60},
  2388  		209: {55, 100, 55},
  2389  		311: {81, 81, 41},
  2390  	}
  2391  	testPoints1 := map[uint64][3]int32{
  2392  		0:   {35, 34, 2},
  2393  		1:   {30, 30, 30},
  2394  		2:   {21, 21, 45},
  2395  		13:  {45, 21, 36},
  2396  		209: {21, 50, 35},
  2397  		311: {45, 55, 35},
  2398  	}
  2399  	testPoints2 := map[uint64][3]int32{
  2400  		0:   {15, 16, 2},
  2401  		1:   {15, 15, 15},
  2402  		2:   {11, 11, 23},
  2403  		13:  {23, 11, 18},
  2404  		209: {11, 25, 18},
  2405  		311: {23, 28, 18},
  2406  	}
  2407  
  2408  	hires := newTestVolume(128, 128, 128)
  2409  	hires.get(t, uuid, "labels", false)
  2410  
  2411  	strarray := make([]string, len(testPoints0))
  2412  	var sentLabels []uint64
  2413  	i := 0
  2414  	for label, pt := range testPoints0 {
  2415  		hires.verifyLabel(t, label, pt[0], pt[1], pt[2])
  2416  		sentLabels = append(sentLabels, label)
  2417  		strarray[i] = fmt.Sprintf("[%d,%d,%d]", pt[0], pt[1], pt[2])
  2418  		i++
  2419  	}
  2420  	coordsStr := "[" + strings.Join(strarray, ",") + "]"
  2421  	reqStr := fmt.Sprintf("%snode/%s/labels/labels", server.WebAPIPath, uuid)
  2422  	r := server.TestHTTP(t, "GET", reqStr, bytes.NewBufferString(coordsStr))
  2423  	var gotLabels []uint64
  2424  	if err := json.Unmarshal(r, &gotLabels); err != nil {
  2425  		t.Errorf("Unable to get label array from GET /labels.  Instead got: %v\n", string(r))
  2426  	}
  2427  	for i, sent := range sentLabels {
  2428  		if sent != gotLabels[i] {
  2429  			t.Errorf("expected GET /labels to return label %d in position %d, got %d back\n", sent, i, gotLabels[i])
  2430  		}
  2431  	}
  2432  
  2433  	// Check the first downres: 64^3
  2434  	downres1 := newTestVolume(64, 64, 64)
  2435  	downres1.getScale(t, uuid, "labels", 1, false)
  2436  	sentLabels = []uint64{}
  2437  	i = 0
  2438  	for label, pt := range testPoints1 {
  2439  		downres1.verifyLabel(t, label, pt[0], pt[1], pt[2])
  2440  		sentLabels = append(sentLabels, label)
  2441  		strarray[i] = fmt.Sprintf("[%d,%d,%d]", pt[0], pt[1], pt[2])
  2442  		i++
  2443  	}
  2444  	coordsStr = "[" + strings.Join(strarray, ",") + "]"
  2445  	reqStr = fmt.Sprintf("%snode/%s/labels/labels?scale=1", server.WebAPIPath, uuid)
  2446  	r = server.TestHTTP(t, "GET", reqStr, bytes.NewBufferString(coordsStr))
  2447  	gotLabels = []uint64{}
  2448  	if err := json.Unmarshal(r, &gotLabels); err != nil {
  2449  		t.Errorf("Unable to get label array from GET /labels.  Instead got: %v\n", string(r))
  2450  	}
  2451  	for i, sent := range sentLabels {
  2452  		if sent != gotLabels[i] {
  2453  			t.Errorf("expected GET /labels to return label %d in position %d, got %d back\n", sent, i, gotLabels[i])
  2454  		}
  2455  	}
  2456  	expected1 := newTestVolume(64, 64, 64)
  2457  	expected1.addSubvol(dvid.Point3d{20, 20, 20}, dvid.Point3d{20, 20, 20}, 1)
  2458  	expected1.addSubvol(dvid.Point3d{20, 20, 40}, dvid.Point3d{20, 20, 20}, 2)
  2459  	expected1.addSubvol(dvid.Point3d{40, 20, 20}, dvid.Point3d{20, 20, 20}, 13)
  2460  	expected1.addSubvol(dvid.Point3d{20, 40, 20}, dvid.Point3d{20, 20, 20}, 209)
  2461  	expected1.addSubvol(dvid.Point3d{40, 40, 20}, dvid.Point3d{20, 20, 20}, 311)
  2462  	if err := expected1.equals(downres1); err != nil {
  2463  		t.Errorf("1st downres isn't what is expected: %v\n", err)
  2464  	}
  2465  
  2466  	// Check the second downres to voxel: 32^3
  2467  	downres2 := newTestVolume(32, 32, 32)
  2468  	downres2.getScale(t, uuid, "labels", 2, false)
  2469  	for label, pt := range testPoints2 {
  2470  		downres2.verifyLabel(t, label, pt[0], pt[1], pt[2])
  2471  	}
  2472  	expected2 := newTestVolume(32, 32, 32)
  2473  	expected2.addSubvol(dvid.Point3d{10, 10, 10}, dvid.Point3d{10, 10, 10}, 1)
  2474  	expected2.addSubvol(dvid.Point3d{10, 10, 20}, dvid.Point3d{10, 10, 10}, 2)
  2475  	expected2.addSubvol(dvid.Point3d{20, 10, 10}, dvid.Point3d{10, 10, 10}, 13)
  2476  	expected2.addSubvol(dvid.Point3d{10, 20, 10}, dvid.Point3d{10, 10, 10}, 209)
  2477  	expected2.addSubvol(dvid.Point3d{20, 20, 10}, dvid.Point3d{10, 10, 10}, 311)
  2478  	if err := expected2.equals(downres2); err != nil {
  2479  		t.Errorf("2nd downres isn't what is expected: %v\n", err)
  2480  	}
  2481  
  2482  	var labelJSON struct {
  2483  		Label uint64
  2484  	}
  2485  	for i := 0; i < 100; i++ {
  2486  		for label, pt := range testPoints0 {
  2487  			labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2488  			labelResp := server.TestHTTP(t, "GET", labelReq, nil)
  2489  			if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2490  				t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2491  			}
  2492  			if labelJSON.Label != label {
  2493  				t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2494  			}
  2495  		}
  2496  	}
  2497  	for label, pt := range testPoints1 {
  2498  		labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=1", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2499  		labelResp := server.TestHTTP(t, "GET", labelReq, nil)
  2500  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2501  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2502  		}
  2503  		if labelJSON.Label != label {
  2504  			t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2505  		}
  2506  	}
  2507  	for label, pt := range testPoints2 {
  2508  		labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=2", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2509  		labelResp := server.TestHTTP(t, "GET", labelReq, nil)
  2510  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2511  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2512  		}
  2513  		if labelJSON.Label != label {
  2514  			t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2515  		}
  2516  	}
  2517  
  2518  	// Test merge of 2 and 13 into 1
  2519  	testMerge := mergeJSON(`[1, 2, 13]`)
  2520  	testMerge.send(t, uuid, "labels")
  2521  
  2522  	sizeReq = fmt.Sprintf("%snode/%s/labels/sparsevol-size/1", server.WebAPIPath, uuid)
  2523  	sizeResp = server.TestHTTP(t, "GET", sizeReq, nil)
  2524  	if string(sizeResp) != `{"voxels": 192000, "numblocks": 8, "minvoxel": [0, 0, 0], "maxvoxel": [127, 127, 127]}` {
  2525  		t.Errorf("bad response to sparsevol-size endpoint: %s\n", string(sizeResp))
  2526  	}
  2527  	sizeReq = fmt.Sprintf("%snode/%s/labels/sparsevol-size/2?supervoxels=true", server.WebAPIPath, uuid)
  2528  	sizeResp = server.TestHTTP(t, "GET", sizeReq, nil)
  2529  	if string(sizeResp) != `{"voxels": 64000, "numblocks": 4, "minvoxel": [0, 0, 64], "maxvoxel": [127, 127, 127]}` {
  2530  		t.Errorf("bad response to sparsevol-size endpoint: %s\n", string(sizeResp))
  2531  	}
  2532  	headReq := fmt.Sprintf("%snode/%s/labels/sparsevol/2?supervoxels=true", server.WebAPIPath, uuid)
  2533  	headResp := server.TestHTTPResponse(t, "HEAD", headReq, nil)
  2534  	if headResp.Code != http.StatusOK {
  2535  		t.Errorf("HEAD on %s did not return OK.  Status = %d\n", headReq, headResp.Code)
  2536  	}
  2537  
  2538  	mapping := map[uint64]uint64{
  2539  		1:   1,
  2540  		2:   1,
  2541  		13:  1,
  2542  		209: 209,
  2543  		311: 311,
  2544  	}
  2545  	sentLabels = []uint64{}
  2546  	i = 0
  2547  	for label, pt := range testPoints0 {
  2548  		labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2549  		labelResp := server.TestHTTP(t, "GET", labelReq, nil)
  2550  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2551  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2552  		}
  2553  		if labelJSON.Label != mapping[label] {
  2554  			t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2555  		}
  2556  		labelReq = fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?supervoxels=true", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2557  		labelResp = server.TestHTTP(t, "GET", labelReq, nil)
  2558  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2559  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2560  		}
  2561  		if labelJSON.Label != label {
  2562  			t.Errorf("expected label %d to query on (%d, %d, %d): %s\n", label, pt[0], pt[1], pt[2], string(labelResp))
  2563  		}
  2564  		sentLabels = append(sentLabels, label)
  2565  		strarray[i] = fmt.Sprintf("%d", label)
  2566  		i++
  2567  	}
  2568  	supervoxelsStr := "[" + strings.Join(strarray, ",") + "]"
  2569  	reqStr = fmt.Sprintf("%snode/%s/labels/mapping", server.WebAPIPath, uuid)
  2570  	r = server.TestHTTP(t, "GET", reqStr, bytes.NewBufferString(supervoxelsStr))
  2571  	gotLabels = []uint64{}
  2572  	if err := json.Unmarshal(r, &gotLabels); err != nil {
  2573  		t.Errorf("Unable to get label array from GET /mapping.  Instead got: %v\n", string(r))
  2574  	}
  2575  	for i, sent := range sentLabels {
  2576  		if mapping[sent] != gotLabels[i] {
  2577  			t.Fatalf("expected GET /mapping to return label %d in position %d, got %d back\n", mapping[sent], i, gotLabels[i])
  2578  		}
  2579  	}
  2580  
  2581  	for label, pt := range testPoints1 {
  2582  		labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=1", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2583  		labelResp := server.TestHTTP(t, "GET", labelReq, nil)
  2584  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2585  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2586  		}
  2587  		if labelJSON.Label != mapping[label] {
  2588  			t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2589  		}
  2590  		labelReq = fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=1&supervoxels=true", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2591  		labelResp = server.TestHTTP(t, "GET", labelReq, nil)
  2592  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2593  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2594  		}
  2595  		if labelJSON.Label != label {
  2596  			t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2597  		}
  2598  	}
  2599  	for label, pt := range testPoints2 {
  2600  		labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=2", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2601  		labelResp := server.TestHTTP(t, "GET", labelReq, nil)
  2602  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2603  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2604  		}
  2605  		if labelJSON.Label != mapping[label] {
  2606  			t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2607  		}
  2608  		labelReq = fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=2&supervoxels=true", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2609  		labelResp = server.TestHTTP(t, "GET", labelReq, nil)
  2610  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2611  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2612  		}
  2613  		if labelJSON.Label != label {
  2614  			t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2615  		}
  2616  	}
  2617  
  2618  	// Make sure labels 2 and 13 sparsevol has been removed.
  2619  	reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/2", server.WebAPIPath, uuid)
  2620  	server.TestBadHTTP(t, "GET", reqStr, nil)
  2621  
  2622  	reqStr = fmt.Sprintf("%snode/%s/labels/sparsevol/13", server.WebAPIPath, uuid)
  2623  	server.TestBadHTTP(t, "GET", reqStr, nil)
  2624  
  2625  	// Make sure label changes are correct after completion of merge
  2626  	if err := downres.BlockOnUpdating(uuid, "labels"); err != nil {
  2627  		t.Fatalf("Error blocking on update for labels: %v\n", err)
  2628  	}
  2629  	retrieved := newTestVolume(128, 128, 128)
  2630  	retrieved.get(t, uuid, "labels", false)
  2631  	merged := newTestVolume(128, 128, 128)
  2632  	merged.addSubvol(dvid.Point3d{40, 40, 40}, dvid.Point3d{40, 40, 40}, 1)
  2633  	merged.addSubvol(dvid.Point3d{40, 40, 80}, dvid.Point3d{40, 40, 40}, 1)
  2634  	merged.addSubvol(dvid.Point3d{80, 40, 40}, dvid.Point3d{40, 40, 40}, 1)
  2635  	merged.addSubvol(dvid.Point3d{40, 80, 40}, dvid.Point3d{40, 40, 40}, 209)
  2636  	merged.addSubvol(dvid.Point3d{80, 80, 40}, dvid.Point3d{40, 40, 40}, 311)
  2637  	if err := merged.equals(retrieved); err != nil {
  2638  		t.Errorf("Merged label volume not equal to expected label volume: %v\n", err)
  2639  	}
  2640  
  2641  	retrieved.get(t, uuid, "labels", true) // check supervoxels
  2642  	if err := hires.equals(retrieved); err != nil {
  2643  		t.Errorf("Merged supervoxel volume not equal to original supervoxel volume: %v\n", err)
  2644  	}
  2645  
  2646  	retrieved1 := newTestVolume(64, 64, 64)
  2647  	retrieved1.getScale(t, uuid, "labels", 1, false)
  2648  	retrieved1.verifyLabel(t, 0, 35, 34, 2)
  2649  	merged1 := newTestVolume(64, 64, 64)
  2650  	merged1.addSubvol(dvid.Point3d{20, 20, 20}, dvid.Point3d{20, 20, 20}, 1)
  2651  	merged1.addSubvol(dvid.Point3d{20, 20, 40}, dvid.Point3d{20, 20, 20}, 1)
  2652  	merged1.addSubvol(dvid.Point3d{40, 20, 20}, dvid.Point3d{20, 20, 20}, 1)
  2653  	merged1.addSubvol(dvid.Point3d{20, 40, 20}, dvid.Point3d{20, 20, 20}, 209)
  2654  	merged1.addSubvol(dvid.Point3d{40, 40, 20}, dvid.Point3d{20, 20, 20}, 311)
  2655  	if err := retrieved1.equals(merged1); err != nil {
  2656  		t.Errorf("Merged label volume downres #1 not equal to expected merged volume: %v\n", err)
  2657  	}
  2658  
  2659  	retrieved1.getScale(t, uuid, "labels", 1, true) // check supervoxels
  2660  	if err := downres1.equals(retrieved1); err != nil {
  2661  		t.Errorf("Merged supervoxel volume @ downres #1 not equal to original supervoxel volume: %v\n", err)
  2662  	}
  2663  
  2664  	retrieved2 := newTestVolume(32, 32, 32)
  2665  	retrieved2.getScale(t, uuid, "labels", 2, false)
  2666  	merged2 := newTestVolume(32, 32, 32)
  2667  	merged2.addSubvol(dvid.Point3d{10, 10, 10}, dvid.Point3d{10, 10, 10}, 1)
  2668  	merged2.addSubvol(dvid.Point3d{10, 10, 20}, dvid.Point3d{10, 10, 10}, 1)
  2669  	merged2.addSubvol(dvid.Point3d{20, 10, 10}, dvid.Point3d{10, 10, 10}, 1)
  2670  	merged2.addSubvol(dvid.Point3d{10, 20, 10}, dvid.Point3d{10, 10, 10}, 209)
  2671  	merged2.addSubvol(dvid.Point3d{20, 20, 10}, dvid.Point3d{10, 10, 10}, 311)
  2672  	if err := retrieved2.equals(merged2); err != nil {
  2673  		t.Errorf("Merged label volume downres #2 not equal to expected merged volume: %v\n", err)
  2674  	}
  2675  
  2676  	retrieved2.getScale(t, uuid, "labels", 2, true) // check supervoxels
  2677  	if err := downres2.equals(retrieved2); err != nil {
  2678  		t.Errorf("Merged supervoxel volume @ downres #2 not equal to original supervoxel volume: %v\n", err)
  2679  	}
  2680  
  2681  	// Cleave supervoxel 2 and 13 back out of merge label 1, should be 312.
  2682  	reqStr = fmt.Sprintf("%snode/%s/labels/cleave/1", server.WebAPIPath, uuid)
  2683  	r = server.TestHTTP(t, "POST", reqStr, bytes.NewBufferString("[2, 13]"))
  2684  	var jsonVal struct {
  2685  		CleavedLabel uint64
  2686  		MutationID   uint64
  2687  	}
  2688  	if err := json.Unmarshal(r, &jsonVal); err != nil {
  2689  		t.Errorf("Unable to get new label from cleave.  Instead got: %v\n", jsonVal)
  2690  	}
  2691  	if jsonVal.MutationID == 0 {
  2692  		t.Errorf("expected Mutation ID from cleave but got zero: %v\n", jsonVal)
  2693  	}
  2694  
  2695  	reqStr = fmt.Sprintf("%snode/%s/labels/maxlabel", server.WebAPIPath, uuid)
  2696  	jsonStr := server.TestHTTP(t, "GET", reqStr, nil)
  2697  	expectedJSON := `{"maxlabel": 312}`
  2698  	if string(jsonStr) != expectedJSON {
  2699  		t.Errorf("Expected this JSON returned from maxlabel:\n%s\nGot:\n%s\n", expectedJSON, string(jsonStr))
  2700  	}
  2701  
  2702  	mapping = map[uint64]uint64{
  2703  		1:   1,
  2704  		2:   312,
  2705  		13:  312,
  2706  		209: 209,
  2707  		311: 311,
  2708  	}
  2709  	for label, pt := range testPoints0 {
  2710  		labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2711  		labelResp := server.TestHTTP(t, "GET", labelReq, nil)
  2712  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2713  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2714  		}
  2715  		if labelJSON.Label != mapping[label] {
  2716  			t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2717  		}
  2718  		labelReq = fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?supervoxels=true", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2719  		labelResp = server.TestHTTP(t, "GET", labelReq, nil)
  2720  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2721  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2722  		}
  2723  		if labelJSON.Label != label {
  2724  			t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2725  		}
  2726  	}
  2727  	for label, pt := range testPoints1 {
  2728  		labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=1", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2729  		labelResp := server.TestHTTP(t, "GET", labelReq, nil)
  2730  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2731  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2732  		}
  2733  		if labelJSON.Label != mapping[label] {
  2734  			t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2735  		}
  2736  		labelReq = fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=1&supervoxels=true", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2737  		labelResp = server.TestHTTP(t, "GET", labelReq, nil)
  2738  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2739  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2740  		}
  2741  		if labelJSON.Label != label {
  2742  			t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2743  		}
  2744  	}
  2745  	for label, pt := range testPoints2 {
  2746  		labelReq := fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=2", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2747  		labelResp := server.TestHTTP(t, "GET", labelReq, nil)
  2748  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2749  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2750  		}
  2751  		if labelJSON.Label != mapping[label] {
  2752  			t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2753  		}
  2754  		labelReq = fmt.Sprintf("%snode/%s/labels/label/%d_%d_%d?scale=2&supervoxels=true", server.WebAPIPath, uuid, pt[0], pt[1], pt[2])
  2755  		labelResp = server.TestHTTP(t, "GET", labelReq, nil)
  2756  		if err := json.Unmarshal(labelResp, &labelJSON); err != nil {
  2757  			t.Errorf("problem decoding response (%s): %v\n", string(labelResp), err)
  2758  		}
  2759  		if labelJSON.Label != label {
  2760  			t.Errorf("bad response to label query on (%d, %d, %d): %s\n", pt[0], pt[1], pt[2], string(labelResp))
  2761  		}
  2762  	}
  2763  
  2764  	retrieved.get(t, uuid, "labels", false)
  2765  	cleaved0 := newTestVolume(128, 128, 128)
  2766  	cleaved0.addSubvol(dvid.Point3d{40, 40, 40}, dvid.Point3d{40, 40, 40}, 1)
  2767  	cleaved0.addSubvol(dvid.Point3d{40, 40, 80}, dvid.Point3d{40, 40, 40}, 312)
  2768  	cleaved0.addSubvol(dvid.Point3d{80, 40, 40}, dvid.Point3d{40, 40, 40}, 312)
  2769  	cleaved0.addSubvol(dvid.Point3d{40, 80, 40}, dvid.Point3d{40, 40, 40}, 209)
  2770  	cleaved0.addSubvol(dvid.Point3d{80, 80, 40}, dvid.Point3d{40, 40, 40}, 311)
  2771  	if err := cleaved0.equals(retrieved); err != nil {
  2772  		t.Errorf("Cleaved label volume not equal to expected label volume: %v\n", err)
  2773  	}
  2774  
  2775  	retrieved.get(t, uuid, "labels", true) // check supervoxels
  2776  	if err := hires.equals(retrieved); err != nil {
  2777  		t.Errorf("Cleaved supervoxel volume not equal to original supervoxel volume: %v\n", err)
  2778  	}
  2779  
  2780  	retrieved1.getScale(t, uuid, "labels", 1, false)
  2781  	cleaved1 := newTestVolume(64, 64, 64)
  2782  	cleaved1.addSubvol(dvid.Point3d{20, 20, 20}, dvid.Point3d{20, 20, 20}, 1)
  2783  	cleaved1.addSubvol(dvid.Point3d{20, 20, 40}, dvid.Point3d{20, 20, 20}, 312)
  2784  	cleaved1.addSubvol(dvid.Point3d{40, 20, 20}, dvid.Point3d{20, 20, 20}, 312)
  2785  	cleaved1.addSubvol(dvid.Point3d{20, 40, 20}, dvid.Point3d{20, 20, 20}, 209)
  2786  	cleaved1.addSubvol(dvid.Point3d{40, 40, 20}, dvid.Point3d{20, 20, 20}, 311)
  2787  	if err := retrieved1.equals(cleaved1); err != nil {
  2788  		t.Errorf("Cleaved label volume downres #1 not equal to expected merged volume: %v\n", err)
  2789  	}
  2790  
  2791  	retrieved1.getScale(t, uuid, "labels", 1, true) // check supervoxels
  2792  	if err := downres1.equals(retrieved1); err != nil {
  2793  		t.Errorf("Cleaved supervoxel volume @ downres #1 not equal to original supervoxel volume: %v\n", err)
  2794  	}
  2795  
  2796  	retrieved2.getScale(t, uuid, "labels", 2, false)
  2797  	cleaved2 := newTestVolume(32, 32, 32)
  2798  	cleaved2.addSubvol(dvid.Point3d{10, 10, 10}, dvid.Point3d{10, 10, 10}, 1)
  2799  	cleaved2.addSubvol(dvid.Point3d{10, 10, 20}, dvid.Point3d{10, 10, 10}, 312)
  2800  	cleaved2.addSubvol(dvid.Point3d{20, 10, 10}, dvid.Point3d{10, 10, 10}, 312)
  2801  	cleaved2.addSubvol(dvid.Point3d{10, 20, 10}, dvid.Point3d{10, 10, 10}, 209)
  2802  	cleaved2.addSubvol(dvid.Point3d{20, 20, 10}, dvid.Point3d{10, 10, 10}, 311)
  2803  	if err := retrieved2.equals(cleaved2); err != nil {
  2804  		t.Errorf("Cleaved label volume downres #2 not equal to expected merged volume: %v\n", err)
  2805  	}
  2806  
  2807  	retrieved2.getScale(t, uuid, "labels", 2, true) // check supervoxels
  2808  	if err := downres2.equals(retrieved2); err != nil {
  2809  		t.Errorf("Cleaved supervoxel volume @ downres #2 not equal to original supervoxel volume: %v\n", err)
  2810  	}
  2811  
  2812  }
  2813  
  2814  // Test that mutable labelmap POST will accurately remove prior bodies if we overwrite
  2815  // supervoxels entirely.
  2816  func TestMutableLabelblkPOST(t *testing.T) {
  2817  	testConfig := server.TestConfig{CacheSize: map[string]int{"labelmap": 10}}
  2818  	// var testConfig server.TestConfig
  2819  	if err := server.OpenTest(testConfig); err != nil {
  2820  		t.Fatalf("can't open test server: %v\n", err)
  2821  	}
  2822  	defer server.CloseTest()
  2823  
  2824  	// Create testbed volume and data instances
  2825  	uuid, _ := initTestRepo()
  2826  	var config dvid.Config
  2827  	server.CreateTestInstance(t, uuid, "labelmap", "labels", config)
  2828  
  2829  	// Post labels 1-4
  2830  	createLabelTestVolume(t, uuid, "labels")
  2831  
  2832  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
  2833  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
  2834  	}
  2835  
  2836  	// Make sure we have labels 1-4 sparsevol
  2837  	for _, label := range []uint64{1, 2, 3, 4} {
  2838  		// Check fast HEAD requests
  2839  		reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, label)
  2840  		resp := server.TestHTTPResponse(t, "HEAD", reqStr, nil)
  2841  		if resp.Code != http.StatusOK {
  2842  			t.Errorf("HEAD on %s did not return OK.  Status = %d\n", reqStr, resp.Code)
  2843  		}
  2844  
  2845  		// Check full sparse volumes
  2846  		encoding := server.TestHTTP(t, "GET", reqStr, nil)
  2847  		bodies[label-1].checkSparseVol(t, encoding, dvid.OptionalBounds{})
  2848  	}
  2849  
  2850  	// Post labels 6-7 that overwrite all labels 1-4.
  2851  	createLabelTest2Volume(t, uuid, "labels")
  2852  
  2853  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
  2854  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
  2855  	}
  2856  
  2857  	// Make sure that labels 1-4 have no more sparse vol.
  2858  	for _, label := range []uint64{1, 2, 3, 4} {
  2859  		// Check full sparse volumes aren't retrievable anymore
  2860  		reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, label)
  2861  		server.TestBadHTTP(t, "GET", reqStr, nil)
  2862  
  2863  		// Make sure non-existent bodies return proper HEAD responses.
  2864  		resp := server.TestHTTPResponse(t, "HEAD", reqStr, nil)
  2865  		if resp.Code != http.StatusNoContent {
  2866  			t.Errorf("HEAD on %s did not return 204 (No Content).  Status = %d\n", reqStr, resp.Code)
  2867  		}
  2868  	}
  2869  
  2870  	// Make sure labels 6-7 are available as sparse vol.
  2871  	for _, label := range []uint64{6, 7} {
  2872  		// Check fast HEAD requests
  2873  		reqStr := fmt.Sprintf("%snode/%s/labels/sparsevol/%d", server.WebAPIPath, uuid, label)
  2874  		resp := server.TestHTTPResponse(t, "HEAD", reqStr, nil)
  2875  		if resp.Code != http.StatusOK {
  2876  			t.Errorf("HEAD on %s did not return OK.  Status = %d\n", reqStr, resp.Code)
  2877  		}
  2878  
  2879  		// Check full sparse volumes
  2880  		encoding := server.TestHTTP(t, "GET", reqStr, nil)
  2881  		bodies[label-1].checkSparseVol(t, encoding, dvid.OptionalBounds{})
  2882  	}
  2883  }
  2884  
  2885  func TestConcurrentMutations(t *testing.T) {
  2886  	testConfig := server.TestConfig{CacheSize: map[string]int{"labelmap": 10}}
  2887  	// var testConfig server.TestConfig
  2888  	if err := server.OpenTest(testConfig); err != nil {
  2889  		t.Fatalf("can't open test server: %v\n", err)
  2890  	}
  2891  	defer server.CloseTest()
  2892  
  2893  	// Create testbed volume and data instances
  2894  	uuid, _ := initTestRepo()
  2895  	var config dvid.Config // use native 64^3 blocks
  2896  	server.CreateTestInstance(t, uuid, "labelmap", "labels", config)
  2897  
  2898  	// Make 12 parallel bodies and do merge/split on 3 groups.
  2899  	tbodies := make([]testBody, 12)
  2900  	for i := 0; i < 12; i++ {
  2901  		z := int32(32 + 4*i)
  2902  		blockz := z / 64
  2903  		tbodies[i] = testBody{ // 72 x 4 x 4 horizontal bar
  2904  			label:  uint64(i + 1),
  2905  			offset: dvid.Point3d{9, 68, z},
  2906  			size:   dvid.Point3d{72, 4, 4},
  2907  			blockSpans: []dvid.Span{
  2908  				{blockz, 1, 0, 1},
  2909  			},
  2910  			voxelSpans: []dvid.Span{
  2911  				{z, 68, 9, 80},
  2912  				{z, 69, 9, 80},
  2913  				{z, 70, 9, 80},
  2914  				{z, 71, 9, 80},
  2915  				{z + 1, 68, 9, 80},
  2916  				{z + 1, 69, 9, 80},
  2917  				{z + 1, 70, 9, 80},
  2918  				{z + 1, 71, 9, 80},
  2919  				{z + 2, 68, 9, 80},
  2920  				{z + 2, 69, 9, 80},
  2921  				{z + 2, 70, 9, 80},
  2922  				{z + 2, 71, 9, 80},
  2923  				{z + 3, 68, 9, 80},
  2924  				{z + 3, 69, 9, 80},
  2925  				{z + 3, 70, 9, 80},
  2926  				{z + 3, 71, 9, 80},
  2927  			},
  2928  		}
  2929  	}
  2930  
  2931  	tvol := newTestVolume(192, 128, 128)
  2932  	for i := 0; i < 12; i++ {
  2933  		tvol.addBody(tbodies[i], uint64(i+1))
  2934  	}
  2935  	tvol.put(t, uuid, "labels")
  2936  
  2937  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
  2938  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
  2939  	}
  2940  
  2941  	retrieved := newTestVolume(192, 128, 128)
  2942  	retrieved.get(t, uuid, "labels", false)
  2943  	if len(retrieved.data) != 8*192*128*128 {
  2944  		t.Errorf("Retrieved labelvol volume is incorrect size\n")
  2945  	}
  2946  	if err := retrieved.equals(tvol); err != nil {
  2947  		t.Errorf("Initial put not working: %v\n", err)
  2948  	}
  2949  
  2950  	// Run concurrent cleave/merge ops on labels 1-4, 5-8, and 9-12.
  2951  	expectedMapping1 := make(map[uint64]uint64)
  2952  	expectedMapping2 := make(map[uint64]uint64)
  2953  	expectedMapping3 := make(map[uint64]uint64)
  2954  	wg := new(sync.WaitGroup)
  2955  	wg.Add(3)
  2956  	go func() {
  2957  		var err error
  2958  		for n := 0; n < 50; n++ {
  2959  			if err = mergeCleave(t, uuid, "labels", tbodies[0:4], 1, expectedMapping1); err != nil {
  2960  				break
  2961  			}
  2962  		}
  2963  		wg.Done()
  2964  		if err != nil {
  2965  			t.Error(err)
  2966  		}
  2967  	}()
  2968  	go func() {
  2969  		var err error
  2970  		for n := 0; n < 50; n++ {
  2971  			if err = mergeCleave(t, uuid, "labels", tbodies[4:8], 2, expectedMapping2); err != nil {
  2972  				break
  2973  			}
  2974  		}
  2975  		wg.Done()
  2976  		if err != nil {
  2977  			t.Error(err)
  2978  		}
  2979  	}()
  2980  	go func() {
  2981  		var err error
  2982  		for n := 0; n < 50; n++ {
  2983  			if err = mergeCleave(t, uuid, "labels", tbodies[8:12], 3, expectedMapping3); err != nil {
  2984  				break
  2985  			}
  2986  		}
  2987  		wg.Done()
  2988  		if err != nil {
  2989  			t.Error(err)
  2990  		}
  2991  	}()
  2992  	wg.Wait()
  2993  
  2994  	retrieved2 := newTestVolume(192, 128, 128)
  2995  	retrieved2.get(t, uuid, "labels", false)
  2996  	if len(retrieved2.data) != 8*192*128*128 {
  2997  		t.Errorf("Retrieved labelvol volume is incorrect size\n")
  2998  	}
  2999  	for i := 0; i < 4; i++ {
  3000  		tvol.addBody(tbodies[i], expectedMapping1[uint64(i+1)])
  3001  	}
  3002  	for i := 4; i < 8; i++ {
  3003  		tvol.addBody(tbodies[i], expectedMapping2[uint64(i+1)])
  3004  	}
  3005  	for i := 8; i < 12; i++ {
  3006  		tvol.addBody(tbodies[i], expectedMapping3[uint64(i+1)])
  3007  	}
  3008  	if err := retrieved2.equals(tvol); err != nil {
  3009  		t.Errorf("Concurrent split/merge producing bad result: %v\n", err)
  3010  	}
  3011  
  3012  	// get reverse mapping of new bodies to supervoxel: should be 1 to 1 since cleaves are last ops.
  3013  	reverse := make(map[uint64]uint64, 12)
  3014  	for i := uint64(1); i <= 4; i++ {
  3015  		label, found := expectedMapping1[i]
  3016  		if !found {
  3017  			t.Errorf("unlikely that no mapping found for supervoxel %d!\n", i)
  3018  			label = i
  3019  		}
  3020  		reverse[label] = i
  3021  	}
  3022  	for i := uint64(5); i <= 8; i++ {
  3023  		label, found := expectedMapping2[i]
  3024  		if !found {
  3025  			t.Errorf("unlikely that no mapping found for supervoxel %d!\n", i)
  3026  			label = i
  3027  		}
  3028  		reverse[label] = i
  3029  	}
  3030  	for i := uint64(9); i <= 12; i++ {
  3031  		label, found := expectedMapping3[i]
  3032  		if !found {
  3033  			t.Errorf("unlikely that no mapping found for supervoxel %d!\n", i)
  3034  			label = i
  3035  		}
  3036  		reverse[label] = i
  3037  	}
  3038  
  3039  	reqStr := fmt.Sprintf("%snode/%s/labels/sparsevols-coarse/1/3000", server.WebAPIPath, uuid)
  3040  	encoding := server.TestHTTP(t, "GET", reqStr, nil)
  3041  	var i int
  3042  	for labelNum := 1; labelNum <= 12; labelNum++ {
  3043  		if i+28 > len(encoding) {
  3044  			t.Fatalf("Expected label #%d but only %d bytes remain in encoding\n", labelNum, len(encoding[i:]))
  3045  		}
  3046  		label := binary.LittleEndian.Uint64(encoding[i : i+8])
  3047  		i += 8
  3048  		var spans dvid.Spans
  3049  		if err := spans.UnmarshalBinary(encoding[i:]); err != nil {
  3050  			t.Errorf("Error in decoding coarse sparse volume: %v\n", err)
  3051  			return
  3052  		}
  3053  		i += 4 + len(spans)*16
  3054  		supervoxel, found := reverse[label]
  3055  		if !found {
  3056  			t.Fatalf("Got sparsevol for label %d, yet none of the supervoxels were mapped to it!\n", label)
  3057  		}
  3058  		b := tbodies[supervoxel-1]
  3059  		if !reflect.DeepEqual(spans, b.blockSpans) {
  3060  			t.Errorf("Expected coarse spans for supervoxel %d:\n%s\nGot spans:\n%s\n", b.label, b.blockSpans, spans)
  3061  		}
  3062  	}
  3063  }
  3064  
  3065  // merge a subset of bodies, then cleave each of them back out.
  3066  func mergeCleave(t *testing.T, uuid dvid.UUID, name dvid.InstanceName, tbodies []testBody, thread int, mapping map[uint64]uint64) error {
  3067  	label1 := tbodies[0].label
  3068  	label4 := tbodies[3].label
  3069  	target := label1 + uint64(rand.Int()%4)
  3070  
  3071  	labelset := make(labels.Set)
  3072  	for i := label1; i <= label4; i++ {
  3073  		if i != target {
  3074  			labelset[i] = struct{}{}
  3075  		}
  3076  	}
  3077  
  3078  	mapped, found := mapping[target]
  3079  	if found {
  3080  		target = mapped
  3081  	}
  3082  	var s []string
  3083  	for label := range labelset {
  3084  		mapped, found = mapping[label]
  3085  		if found {
  3086  			label = mapped
  3087  		}
  3088  		s = append(s, fmt.Sprintf("%d", label))
  3089  	}
  3090  	mergeStr := "[" + fmt.Sprintf("%d", target) + ", " + strings.Join(s, ",") + "]"
  3091  	testMerge := mergeJSON(mergeStr)
  3092  	if err := testMerge.sendErr(t, uuid, "labels"); err != nil {
  3093  		return err
  3094  	}
  3095  
  3096  	for label := range labelset {
  3097  		reqStr := fmt.Sprintf("%snode/%s/labels/cleave/%d", server.WebAPIPath, uuid, target)
  3098  		cleaveStr := fmt.Sprintf("[%d]", label)
  3099  		r, err := server.TestHTTPError(t, "POST", reqStr, bytes.NewBufferString(cleaveStr))
  3100  		if err != nil {
  3101  			return err
  3102  		}
  3103  		var jsonVal struct {
  3104  			CleavedLabel uint64
  3105  		}
  3106  		if err := json.Unmarshal(r, &jsonVal); err != nil {
  3107  			return fmt.Errorf("unable to get new label from cleave.  Instead got: %v", jsonVal)
  3108  		}
  3109  		mapping[label] = jsonVal.CleavedLabel
  3110  
  3111  		// make sure old label doesn't have these supervoxels anymore.
  3112  		reqStr = fmt.Sprintf("%snode/%s/labels/supervoxels/%d", server.WebAPIPath, uuid, target)
  3113  		r, err = server.TestHTTPError(t, "GET", reqStr, nil)
  3114  		if err != nil {
  3115  			return err
  3116  		}
  3117  		var supervoxels []uint64
  3118  		if err := json.Unmarshal(r, &supervoxels); err != nil {
  3119  			return fmt.Errorf("unable to get supervoxels after cleave: %v", err)
  3120  		}
  3121  		for _, supervoxel := range supervoxels {
  3122  			if supervoxel == label {
  3123  				return fmt.Errorf("supervoxel %d was supposedly cleaved but still remains in label %d index", label, target)
  3124  			}
  3125  		}
  3126  
  3127  		// make sure cleaved body has just this supervoxel.
  3128  		reqStr = fmt.Sprintf("%snode/%s/labels/supervoxels/%d", server.WebAPIPath, uuid, jsonVal.CleavedLabel)
  3129  		r, err = server.TestHTTPError(t, "GET", reqStr, nil)
  3130  		if err != nil {
  3131  			return err
  3132  		}
  3133  		if err := json.Unmarshal(r, &supervoxels); err != nil {
  3134  			return fmt.Errorf("unable to get supervoxels for cleaved body %d after cleave: %v", jsonVal.CleavedLabel, err)
  3135  		}
  3136  		if len(supervoxels) != 1 {
  3137  			return fmt.Errorf("expected only 1 supervoxel (%d) to remain from cleave of %d into %d.  have: %v", label, target, jsonVal.CleavedLabel, supervoxels)
  3138  		}
  3139  		if supervoxels[0] != label {
  3140  			return fmt.Errorf("expected only supervoxel in cleaved body %d to be %d, got %d", jsonVal.CleavedLabel, label, supervoxels[0])
  3141  		}
  3142  	}
  3143  	return nil
  3144  }
  3145  
  3146  // Test concurrent POST blocks and then extents that should have data-wide mutex so no
  3147  // overwriting of extents.
  3148  func TestPostBlocksExtents(t *testing.T) {
  3149  	numTests := 3
  3150  	for i := 0; i < numTests; i++ {
  3151  		runTestBlocksExtents(t, i)
  3152  	}
  3153  }
  3154  
  3155  func runTestBlocksExtents(t *testing.T, run int) {
  3156  	if err := server.OpenTest(); err != nil {
  3157  		t.Fatalf("can't open test server: %v\n", err)
  3158  	}
  3159  	defer server.CloseTest()
  3160  
  3161  	uuid, _ := datastore.NewTestRepo()
  3162  	if len(uuid) < 5 {
  3163  		t.Fatalf("Bad root UUID for new repo: %s\n", uuid)
  3164  	}
  3165  	server.CreateTestInstance(t, uuid, "labelmap", "labels", dvid.Config{})
  3166  
  3167  	data := loadTestData(t, testFiles[0])
  3168  	gzippedData, err := data.b.CompressGZIP()
  3169  	if err != nil {
  3170  		t.Fatalf("unable to gzip compress block: %v\n", err)
  3171  	}
  3172  
  3173  	apiStr := fmt.Sprintf("%snode/%s/labels/blocks", server.WebAPIPath, uuid)
  3174  	sz := 128
  3175  	span := int32(sz / 64)
  3176  	wg := new(sync.WaitGroup)
  3177  	wg.Add(int(span * span * span))
  3178  	for z := int32(0); z < span; z++ {
  3179  		for y := int32(0); y < span; y++ {
  3180  			for x := int32(0); x < span; x++ {
  3181  				go writeConcurrentBlock(t, wg, apiStr, x, y, z, gzippedData)
  3182  			}
  3183  		}
  3184  	}
  3185  	wg.Wait()
  3186  	if err := datastore.BlockOnUpdating(uuid, "labels"); err != nil {
  3187  		t.Fatalf("Error blocking on sync of labels: %v\n", err)
  3188  	}
  3189  
  3190  	// check extents...
  3191  	apiStr = fmt.Sprintf("%snode/%s/labels/info", server.WebAPIPath, uuid)
  3192  	r := server.TestHTTP(t, "GET", apiStr, nil)
  3193  	jsonResp := make(map[string]map[string]interface{})
  3194  	if err := json.Unmarshal(r, &jsonResp); err != nil {
  3195  		t.Fatalf("Unable to unmarshal labels/info response: %v\n", r)
  3196  	}
  3197  	extJSON, found := jsonResp["Extended"]
  3198  	if !found {
  3199  		t.Fatalf("No Extended property in labels/info response: %v\n", jsonResp)
  3200  	}
  3201  	val, found := extJSON["MinPoint"]
  3202  	if !found {
  3203  		t.Fatalf("No MinPoint property in labels/info response: %v\n", extJSON)
  3204  	}
  3205  	minPoint := val.([]interface{})
  3206  	for i, pt := range minPoint {
  3207  		coord := pt.(float64)
  3208  		if coord != 0 {
  3209  			t.Fatalf("Bad min coord at position %d in run %d: %v\n", i, run, val)
  3210  		}
  3211  	}
  3212  	val, found = extJSON["MaxPoint"]
  3213  	if !found {
  3214  		t.Fatalf("No MaxPoint property in labels/info response: %v\n", extJSON)
  3215  	}
  3216  	maxPoint := val.([]interface{})
  3217  	for i, pt := range maxPoint {
  3218  		coord := pt.(float64)
  3219  		if coord != 127 {
  3220  			t.Fatalf("Bad max coord at position %d in run %d: %v\n", i, run, val)
  3221  		}
  3222  	}
  3223  }
  3224  
  3225  func writeConcurrentBlock(t *testing.T, wg *sync.WaitGroup, apiStr string, x, y, z int32, gzippedData []byte) {
  3226  	if x == 0 && y == 0 && z == 0 { // randomly pause this block to see if extents correct
  3227  		t := time.Duration(rand.Int63() % 100)
  3228  		time.Sleep(t * time.Millisecond)
  3229  	}
  3230  	var buf bytes.Buffer
  3231  	writeTestInt32(t, &buf, x)
  3232  	writeTestInt32(t, &buf, y)
  3233  	writeTestInt32(t, &buf, z)
  3234  	writeTestInt32(t, &buf, int32(len(gzippedData)))
  3235  	n, err := buf.Write(gzippedData)
  3236  	if err != nil {
  3237  		t.Fatalf("unable to write gzip block: %v\n", err)
  3238  	}
  3239  	if n != len(gzippedData) {
  3240  		t.Fatalf("unable to write %d bytes to buffer, only wrote %d bytes\n", len(gzippedData), n)
  3241  	}
  3242  	server.TestHTTP(t, "POST", apiStr, &buf)
  3243  	wg.Done()
  3244  }
  3245  
  3246  var (
  3247  	body1 = testBody{
  3248  		label:  1,
  3249  		offset: dvid.Point3d{10, 40, 10},
  3250  		size:   dvid.Point3d{20, 20, 80},
  3251  		blockSpans: []dvid.Span{
  3252  			{0, 1, 0, 0},
  3253  			{1, 1, 0, 0},
  3254  			{2, 1, 0, 0},
  3255  		},
  3256  		voxelSpans: []dvid.Span{
  3257  			{10, 40, 10, 29}, {10, 41, 10, 29}, {10, 42, 10, 29}, {10, 43, 10, 29}, {10, 44, 10, 29},
  3258  			{10, 45, 10, 29}, {10, 46, 10, 29}, {10, 47, 10, 29}, {10, 48, 10, 29}, {10, 49, 10, 29},
  3259  			{10, 50, 10, 29}, {10, 51, 10, 29}, {10, 52, 10, 29}, {10, 53, 10, 29}, {10, 54, 10, 29},
  3260  			{10, 55, 10, 29}, {10, 56, 10, 29}, {10, 57, 10, 29}, {10, 58, 10, 29}, {10, 59, 10, 29},
  3261  			{11, 40, 10, 29}, {11, 41, 10, 29}, {11, 42, 10, 29}, {11, 43, 10, 29}, {11, 44, 10, 29},
  3262  			{11, 45, 10, 29}, {11, 46, 10, 29}, {11, 47, 10, 29}, {11, 48, 10, 29}, {11, 49, 10, 29},
  3263  			{11, 50, 10, 29}, {11, 51, 10, 29}, {11, 52, 10, 29}, {11, 53, 10, 29}, {11, 54, 10, 29},
  3264  			{11, 55, 10, 29}, {11, 56, 10, 29}, {11, 57, 10, 29}, {11, 58, 10, 29}, {11, 59, 10, 29},
  3265  			{12, 40, 10, 29}, {12, 41, 10, 29}, {12, 42, 10, 29}, {12, 43, 10, 29}, {12, 44, 10, 29},
  3266  			{12, 45, 10, 29}, {12, 46, 10, 29}, {12, 47, 10, 29}, {12, 48, 10, 29}, {12, 49, 10, 29},
  3267  			{12, 50, 10, 29}, {12, 51, 10, 29}, {12, 52, 10, 29}, {12, 53, 10, 29}, {12, 54, 10, 29},
  3268  			{12, 55, 10, 29}, {12, 56, 10, 29}, {12, 57, 10, 29}, {12, 58, 10, 29}, {12, 59, 10, 29},
  3269  			{13, 40, 10, 29}, {13, 41, 10, 29}, {13, 42, 10, 29}, {13, 43, 10, 29}, {13, 44, 10, 29},
  3270  			{13, 45, 10, 29}, {13, 46, 10, 29}, {13, 47, 10, 29}, {13, 48, 10, 29}, {13, 49, 10, 29},
  3271  			{13, 50, 10, 29}, {13, 51, 10, 29}, {13, 52, 10, 29}, {13, 53, 10, 29}, {13, 54, 10, 29},
  3272  			{13, 55, 10, 29}, {13, 56, 10, 29}, {13, 57, 10, 29}, {13, 58, 10, 29}, {13, 59, 10, 29},
  3273  			{14, 40, 10, 29}, {14, 41, 10, 29}, {14, 42, 10, 29}, {14, 43, 10, 29}, {14, 44, 10, 29},
  3274  			{14, 45, 10, 29}, {14, 46, 10, 29}, {14, 47, 10, 29}, {14, 48, 10, 29}, {14, 49, 10, 29},
  3275  			{14, 50, 10, 29}, {14, 51, 10, 29}, {14, 52, 10, 29}, {14, 53, 10, 29}, {14, 54, 10, 29},
  3276  			{14, 55, 10, 29}, {14, 56, 10, 29}, {14, 57, 10, 29}, {14, 58, 10, 29}, {14, 59, 10, 29},
  3277  			{15, 40, 10, 29}, {15, 41, 10, 29}, {15, 42, 10, 29}, {15, 43, 10, 29}, {15, 44, 10, 29},
  3278  			{15, 45, 10, 29}, {15, 46, 10, 29}, {15, 47, 10, 29}, {15, 48, 10, 29}, {15, 49, 10, 29},
  3279  			{15, 50, 10, 29}, {15, 51, 10, 29}, {15, 52, 10, 29}, {15, 53, 10, 29}, {15, 54, 10, 29},
  3280  			{15, 55, 10, 29}, {15, 56, 10, 29}, {15, 57, 10, 29}, {15, 58, 10, 29}, {15, 59, 10, 29},
  3281  			{16, 40, 10, 29}, {16, 41, 10, 29}, {16, 42, 10, 29}, {16, 43, 10, 29}, {16, 44, 10, 29},
  3282  			{16, 45, 10, 29}, {16, 46, 10, 29}, {16, 47, 10, 29}, {16, 48, 10, 29}, {16, 49, 10, 29},
  3283  			{16, 50, 10, 29}, {16, 51, 10, 29}, {16, 52, 10, 29}, {16, 53, 10, 29}, {16, 54, 10, 29},
  3284  			{16, 55, 10, 29}, {16, 56, 10, 29}, {16, 57, 10, 29}, {16, 58, 10, 29}, {16, 59, 10, 29},
  3285  			{17, 40, 10, 29}, {17, 41, 10, 29}, {17, 42, 10, 29}, {17, 43, 10, 29}, {17, 44, 10, 29},
  3286  			{17, 45, 10, 29}, {17, 46, 10, 29}, {17, 47, 10, 29}, {17, 48, 10, 29}, {17, 49, 10, 29},
  3287  			{17, 50, 10, 29}, {17, 51, 10, 29}, {17, 52, 10, 29}, {17, 53, 10, 29}, {17, 54, 10, 29},
  3288  			{17, 55, 10, 29}, {17, 56, 10, 29}, {17, 57, 10, 29}, {17, 58, 10, 29}, {17, 59, 10, 29},
  3289  			{18, 40, 10, 29}, {18, 41, 10, 29}, {18, 42, 10, 29}, {18, 43, 10, 29}, {18, 44, 10, 29},
  3290  			{18, 45, 10, 29}, {18, 46, 10, 29}, {18, 47, 10, 29}, {18, 48, 10, 29}, {18, 49, 10, 29},
  3291  			{18, 50, 10, 29}, {18, 51, 10, 29}, {18, 52, 10, 29}, {18, 53, 10, 29}, {18, 54, 10, 29},
  3292  			{18, 55, 10, 29}, {18, 56, 10, 29}, {18, 57, 10, 29}, {18, 58, 10, 29}, {18, 59, 10, 29},
  3293  			{19, 40, 10, 29}, {19, 41, 10, 29}, {19, 42, 10, 29}, {19, 43, 10, 29}, {19, 44, 10, 29},
  3294  			{19, 45, 10, 29}, {19, 46, 10, 29}, {19, 47, 10, 29}, {19, 48, 10, 29}, {19, 49, 10, 29},
  3295  			{19, 50, 10, 29}, {19, 51, 10, 29}, {19, 52, 10, 29}, {19, 53, 10, 29}, {19, 54, 10, 29},
  3296  			{19, 55, 10, 29}, {19, 56, 10, 29}, {19, 57, 10, 29}, {19, 58, 10, 29}, {19, 59, 10, 29},
  3297  			{20, 40, 10, 29}, {20, 41, 10, 29}, {20, 42, 10, 29}, {20, 43, 10, 29}, {20, 44, 10, 29},
  3298  			{20, 45, 10, 29}, {20, 46, 10, 29}, {20, 47, 10, 29}, {20, 48, 10, 29}, {20, 49, 10, 29},
  3299  			{20, 50, 10, 29}, {20, 51, 10, 29}, {20, 52, 10, 29}, {20, 53, 10, 29}, {20, 54, 10, 29},
  3300  			{20, 55, 10, 29}, {20, 56, 10, 29}, {20, 57, 10, 29}, {20, 58, 10, 29}, {20, 59, 10, 29},
  3301  			{21, 40, 10, 29}, {21, 41, 10, 29}, {21, 42, 10, 29}, {21, 43, 10, 29}, {21, 44, 10, 29},
  3302  			{21, 45, 10, 29}, {21, 46, 10, 29}, {21, 47, 10, 29}, {21, 48, 10, 29}, {21, 49, 10, 29},
  3303  			{21, 50, 10, 29}, {21, 51, 10, 29}, {21, 52, 10, 29}, {21, 53, 10, 29}, {21, 54, 10, 29},
  3304  			{21, 55, 10, 29}, {21, 56, 10, 29}, {21, 57, 10, 29}, {21, 58, 10, 29}, {21, 59, 10, 29},
  3305  			{22, 40, 10, 29}, {22, 41, 10, 29}, {22, 42, 10, 29}, {22, 43, 10, 29}, {22, 44, 10, 29},
  3306  			{22, 45, 10, 29}, {22, 46, 10, 29}, {22, 47, 10, 29}, {22, 48, 10, 29}, {22, 49, 10, 29},
  3307  			{22, 50, 10, 29}, {22, 51, 10, 29}, {22, 52, 10, 29}, {22, 53, 10, 29}, {22, 54, 10, 29},
  3308  			{22, 55, 10, 29}, {22, 56, 10, 29}, {22, 57, 10, 29}, {22, 58, 10, 29}, {22, 59, 10, 29},
  3309  			{23, 40, 10, 29}, {23, 41, 10, 29}, {23, 42, 10, 29}, {23, 43, 10, 29}, {23, 44, 10, 29},
  3310  			{23, 45, 10, 29}, {23, 46, 10, 29}, {23, 47, 10, 29}, {23, 48, 10, 29}, {23, 49, 10, 29},
  3311  			{23, 50, 10, 29}, {23, 51, 10, 29}, {23, 52, 10, 29}, {23, 53, 10, 29}, {23, 54, 10, 29},
  3312  			{23, 55, 10, 29}, {23, 56, 10, 29}, {23, 57, 10, 29}, {23, 58, 10, 29}, {23, 59, 10, 29},
  3313  			{24, 40, 10, 29}, {24, 41, 10, 29}, {24, 42, 10, 29}, {24, 43, 10, 29}, {24, 44, 10, 29},
  3314  			{24, 45, 10, 29}, {24, 46, 10, 29}, {24, 47, 10, 29}, {24, 48, 10, 29}, {24, 49, 10, 29},
  3315  			{24, 50, 10, 29}, {24, 51, 10, 29}, {24, 52, 10, 29}, {24, 53, 10, 29}, {24, 54, 10, 29},
  3316  			{24, 55, 10, 29}, {24, 56, 10, 29}, {24, 57, 10, 29}, {24, 58, 10, 29}, {24, 59, 10, 29},
  3317  			{25, 40, 10, 29}, {25, 41, 10, 29}, {25, 42, 10, 29}, {25, 43, 10, 29}, {25, 44, 10, 29},
  3318  			{25, 45, 10, 29}, {25, 46, 10, 29}, {25, 47, 10, 29}, {25, 48, 10, 29}, {25, 49, 10, 29},
  3319  			{25, 50, 10, 29}, {25, 51, 10, 29}, {25, 52, 10, 29}, {25, 53, 10, 29}, {25, 54, 10, 29},
  3320  			{25, 55, 10, 29}, {25, 56, 10, 29}, {25, 57, 10, 29}, {25, 58, 10, 29}, {25, 59, 10, 29},
  3321  			{26, 40, 10, 29}, {26, 41, 10, 29}, {26, 42, 10, 29}, {26, 43, 10, 29}, {26, 44, 10, 29},
  3322  			{26, 45, 10, 29}, {26, 46, 10, 29}, {26, 47, 10, 29}, {26, 48, 10, 29}, {26, 49, 10, 29},
  3323  			{26, 50, 10, 29}, {26, 51, 10, 29}, {26, 52, 10, 29}, {26, 53, 10, 29}, {26, 54, 10, 29},
  3324  			{26, 55, 10, 29}, {26, 56, 10, 29}, {26, 57, 10, 29}, {26, 58, 10, 29}, {26, 59, 10, 29},
  3325  			{27, 40, 10, 29}, {27, 41, 10, 29}, {27, 42, 10, 29}, {27, 43, 10, 29}, {27, 44, 10, 29},
  3326  			{27, 45, 10, 29}, {27, 46, 10, 29}, {27, 47, 10, 29}, {27, 48, 10, 29}, {27, 49, 10, 29},
  3327  			{27, 50, 10, 29}, {27, 51, 10, 29}, {27, 52, 10, 29}, {27, 53, 10, 29}, {27, 54, 10, 29},
  3328  			{27, 55, 10, 29}, {27, 56, 10, 29}, {27, 57, 10, 29}, {27, 58, 10, 29}, {27, 59, 10, 29},
  3329  			{28, 40, 10, 29}, {28, 41, 10, 29}, {28, 42, 10, 29}, {28, 43, 10, 29}, {28, 44, 10, 29},
  3330  			{28, 45, 10, 29}, {28, 46, 10, 29}, {28, 47, 10, 29}, {28, 48, 10, 29}, {28, 49, 10, 29},
  3331  			{28, 50, 10, 29}, {28, 51, 10, 29}, {28, 52, 10, 29}, {28, 53, 10, 29}, {28, 54, 10, 29},
  3332  			{28, 55, 10, 29}, {28, 56, 10, 29}, {28, 57, 10, 29}, {28, 58, 10, 29}, {28, 59, 10, 29},
  3333  			{29, 40, 10, 29}, {29, 41, 10, 29}, {29, 42, 10, 29}, {29, 43, 10, 29}, {29, 44, 10, 29},
  3334  			{29, 45, 10, 29}, {29, 46, 10, 29}, {29, 47, 10, 29}, {29, 48, 10, 29}, {29, 49, 10, 29},
  3335  			{29, 50, 10, 29}, {29, 51, 10, 29}, {29, 52, 10, 29}, {29, 53, 10, 29}, {29, 54, 10, 29},
  3336  			{29, 55, 10, 29}, {29, 56, 10, 29}, {29, 57, 10, 29}, {29, 58, 10, 29}, {29, 59, 10, 29},
  3337  			{30, 40, 10, 29}, {30, 41, 10, 29}, {30, 42, 10, 29}, {30, 43, 10, 29}, {30, 44, 10, 29},
  3338  			{30, 45, 10, 29}, {30, 46, 10, 29}, {30, 47, 10, 29}, {30, 48, 10, 29}, {30, 49, 10, 29},
  3339  			{30, 50, 10, 29}, {30, 51, 10, 29}, {30, 52, 10, 29}, {30, 53, 10, 29}, {30, 54, 10, 29},
  3340  			{30, 55, 10, 29}, {30, 56, 10, 29}, {30, 57, 10, 29}, {30, 58, 10, 29}, {30, 59, 10, 29},
  3341  			{31, 40, 10, 29}, {31, 41, 10, 29}, {31, 42, 10, 29}, {31, 43, 10, 29}, {31, 44, 10, 29},
  3342  			{31, 45, 10, 29}, {31, 46, 10, 29}, {31, 47, 10, 29}, {31, 48, 10, 29}, {31, 49, 10, 29},
  3343  			{31, 50, 10, 29}, {31, 51, 10, 29}, {31, 52, 10, 29}, {31, 53, 10, 29}, {31, 54, 10, 29},
  3344  			{31, 55, 10, 29}, {31, 56, 10, 29}, {31, 57, 10, 29}, {31, 58, 10, 29}, {31, 59, 10, 29},
  3345  			{32, 40, 10, 29}, {32, 41, 10, 29}, {32, 42, 10, 29}, {32, 43, 10, 29}, {32, 44, 10, 29},
  3346  			{32, 45, 10, 29}, {32, 46, 10, 29}, {32, 47, 10, 29}, {32, 48, 10, 29}, {32, 49, 10, 29},
  3347  			{32, 50, 10, 29}, {32, 51, 10, 29}, {32, 52, 10, 29}, {32, 53, 10, 29}, {32, 54, 10, 29},
  3348  			{32, 55, 10, 29}, {32, 56, 10, 29}, {32, 57, 10, 29}, {32, 58, 10, 29}, {32, 59, 10, 29},
  3349  			{33, 40, 10, 29}, {33, 41, 10, 29}, {33, 42, 10, 29}, {33, 43, 10, 29}, {33, 44, 10, 29},
  3350  			{33, 45, 10, 29}, {33, 46, 10, 29}, {33, 47, 10, 29}, {33, 48, 10, 29}, {33, 49, 10, 29},
  3351  			{33, 50, 10, 29}, {33, 51, 10, 29}, {33, 52, 10, 29}, {33, 53, 10, 29}, {33, 54, 10, 29},
  3352  			{33, 55, 10, 29}, {33, 56, 10, 29}, {33, 57, 10, 29}, {33, 58, 10, 29}, {33, 59, 10, 29},
  3353  			{34, 40, 10, 29}, {34, 41, 10, 29}, {34, 42, 10, 29}, {34, 43, 10, 29}, {34, 44, 10, 29},
  3354  			{34, 45, 10, 29}, {34, 46, 10, 29}, {34, 47, 10, 29}, {34, 48, 10, 29}, {34, 49, 10, 29},
  3355  			{34, 50, 10, 29}, {34, 51, 10, 29}, {34, 52, 10, 29}, {34, 53, 10, 29}, {34, 54, 10, 29},
  3356  			{34, 55, 10, 29}, {34, 56, 10, 29}, {34, 57, 10, 29}, {34, 58, 10, 29}, {34, 59, 10, 29},
  3357  			{35, 40, 10, 29}, {35, 41, 10, 29}, {35, 42, 10, 29}, {35, 43, 10, 29}, {35, 44, 10, 29},
  3358  			{35, 45, 10, 29}, {35, 46, 10, 29}, {35, 47, 10, 29}, {35, 48, 10, 29}, {35, 49, 10, 29},
  3359  			{35, 50, 10, 29}, {35, 51, 10, 29}, {35, 52, 10, 29}, {35, 53, 10, 29}, {35, 54, 10, 29},
  3360  			{35, 55, 10, 29}, {35, 56, 10, 29}, {35, 57, 10, 29}, {35, 58, 10, 29}, {35, 59, 10, 29},
  3361  			{36, 40, 10, 29}, {36, 41, 10, 29}, {36, 42, 10, 29}, {36, 43, 10, 29}, {36, 44, 10, 29},
  3362  			{36, 45, 10, 29}, {36, 46, 10, 29}, {36, 47, 10, 29}, {36, 48, 10, 29}, {36, 49, 10, 29},
  3363  			{36, 50, 10, 29}, {36, 51, 10, 29}, {36, 52, 10, 29}, {36, 53, 10, 29}, {36, 54, 10, 29},
  3364  			{36, 55, 10, 29}, {36, 56, 10, 29}, {36, 57, 10, 29}, {36, 58, 10, 29}, {36, 59, 10, 29},
  3365  			{37, 40, 10, 29}, {37, 41, 10, 29}, {37, 42, 10, 29}, {37, 43, 10, 29}, {37, 44, 10, 29},
  3366  			{37, 45, 10, 29}, {37, 46, 10, 29}, {37, 47, 10, 29}, {37, 48, 10, 29}, {37, 49, 10, 29},
  3367  			{37, 50, 10, 29}, {37, 51, 10, 29}, {37, 52, 10, 29}, {37, 53, 10, 29}, {37, 54, 10, 29},
  3368  			{37, 55, 10, 29}, {37, 56, 10, 29}, {37, 57, 10, 29}, {37, 58, 10, 29}, {37, 59, 10, 29},
  3369  			{38, 40, 10, 29}, {38, 41, 10, 29}, {38, 42, 10, 29}, {38, 43, 10, 29}, {38, 44, 10, 29},
  3370  			{38, 45, 10, 29}, {38, 46, 10, 29}, {38, 47, 10, 29}, {38, 48, 10, 29}, {38, 49, 10, 29},
  3371  			{38, 50, 10, 29}, {38, 51, 10, 29}, {38, 52, 10, 29}, {38, 53, 10, 29}, {38, 54, 10, 29},
  3372  			{38, 55, 10, 29}, {38, 56, 10, 29}, {38, 57, 10, 29}, {38, 58, 10, 29}, {38, 59, 10, 29},
  3373  			{39, 40, 10, 29}, {39, 41, 10, 29}, {39, 42, 10, 29}, {39, 43, 10, 29}, {39, 44, 10, 29},
  3374  			{39, 45, 10, 29}, {39, 46, 10, 29}, {39, 47, 10, 29}, {39, 48, 10, 29}, {39, 49, 10, 29},
  3375  			{39, 50, 10, 29}, {39, 51, 10, 29}, {39, 52, 10, 29}, {39, 53, 10, 29}, {39, 54, 10, 29},
  3376  			{39, 55, 10, 29}, {39, 56, 10, 29}, {39, 57, 10, 29}, {39, 58, 10, 29}, {39, 59, 10, 29},
  3377  			{40, 40, 10, 29}, {40, 41, 10, 29}, {40, 42, 10, 29}, {40, 43, 10, 29}, {40, 44, 10, 29},
  3378  			{40, 45, 10, 29}, {40, 46, 10, 29}, {40, 47, 10, 29}, {40, 48, 10, 29}, {40, 49, 10, 29},
  3379  			{40, 50, 10, 29}, {40, 51, 10, 29}, {40, 52, 10, 29}, {40, 53, 10, 29}, {40, 54, 10, 29},
  3380  			{40, 55, 10, 29}, {40, 56, 10, 29}, {40, 57, 10, 29}, {40, 58, 10, 29}, {40, 59, 10, 29},
  3381  			{41, 40, 10, 29}, {41, 41, 10, 29}, {41, 42, 10, 29}, {41, 43, 10, 29}, {41, 44, 10, 29},
  3382  			{41, 45, 10, 29}, {41, 46, 10, 29}, {41, 47, 10, 29}, {41, 48, 10, 29}, {41, 49, 10, 29},
  3383  			{41, 50, 10, 29}, {41, 51, 10, 29}, {41, 52, 10, 29}, {41, 53, 10, 29}, {41, 54, 10, 29},
  3384  			{41, 55, 10, 29}, {41, 56, 10, 29}, {41, 57, 10, 29}, {41, 58, 10, 29}, {41, 59, 10, 29},
  3385  			{42, 40, 10, 29}, {42, 41, 10, 29}, {42, 42, 10, 29}, {42, 43, 10, 29}, {42, 44, 10, 29},
  3386  			{42, 45, 10, 29}, {42, 46, 10, 29}, {42, 47, 10, 29}, {42, 48, 10, 29}, {42, 49, 10, 29},
  3387  			{42, 50, 10, 29}, {42, 51, 10, 29}, {42, 52, 10, 29}, {42, 53, 10, 29}, {42, 54, 10, 29},
  3388  			{42, 55, 10, 29}, {42, 56, 10, 29}, {42, 57, 10, 29}, {42, 58, 10, 29}, {42, 59, 10, 29},
  3389  			{43, 40, 10, 29}, {43, 41, 10, 29}, {43, 42, 10, 29}, {43, 43, 10, 29}, {43, 44, 10, 29},
  3390  			{43, 45, 10, 29}, {43, 46, 10, 29}, {43, 47, 10, 29}, {43, 48, 10, 29}, {43, 49, 10, 29},
  3391  			{43, 50, 10, 29}, {43, 51, 10, 29}, {43, 52, 10, 29}, {43, 53, 10, 29}, {43, 54, 10, 29},
  3392  			{43, 55, 10, 29}, {43, 56, 10, 29}, {43, 57, 10, 29}, {43, 58, 10, 29}, {43, 59, 10, 29},
  3393  			{44, 40, 10, 29}, {44, 41, 10, 29}, {44, 42, 10, 29}, {44, 43, 10, 29}, {44, 44, 10, 29},
  3394  			{44, 45, 10, 29}, {44, 46, 10, 29}, {44, 47, 10, 29}, {44, 48, 10, 29}, {44, 49, 10, 29},
  3395  			{44, 50, 10, 29}, {44, 51, 10, 29}, {44, 52, 10, 29}, {44, 53, 10, 29}, {44, 54, 10, 29},
  3396  			{44, 55, 10, 29}, {44, 56, 10, 29}, {44, 57, 10, 29}, {44, 58, 10, 29}, {44, 59, 10, 29},
  3397  			{45, 40, 10, 29}, {45, 41, 10, 29}, {45, 42, 10, 29}, {45, 43, 10, 29}, {45, 44, 10, 29},
  3398  			{45, 45, 10, 29}, {45, 46, 10, 29}, {45, 47, 10, 29}, {45, 48, 10, 29}, {45, 49, 10, 29},
  3399  			{45, 50, 10, 29}, {45, 51, 10, 29}, {45, 52, 10, 29}, {45, 53, 10, 29}, {45, 54, 10, 29},
  3400  			{45, 55, 10, 29}, {45, 56, 10, 29}, {45, 57, 10, 29}, {45, 58, 10, 29}, {45, 59, 10, 29},
  3401  			{46, 40, 10, 29}, {46, 41, 10, 29}, {46, 42, 10, 29}, {46, 43, 10, 29}, {46, 44, 10, 29},
  3402  			{46, 45, 10, 29}, {46, 46, 10, 29}, {46, 47, 10, 29}, {46, 48, 10, 29}, {46, 49, 10, 29},
  3403  			{46, 50, 10, 29}, {46, 51, 10, 29}, {46, 52, 10, 29}, {46, 53, 10, 29}, {46, 54, 10, 29},
  3404  			{46, 55, 10, 29}, {46, 56, 10, 29}, {46, 57, 10, 29}, {46, 58, 10, 29}, {46, 59, 10, 29},
  3405  			{47, 40, 10, 29}, {47, 41, 10, 29}, {47, 42, 10, 29}, {47, 43, 10, 29}, {47, 44, 10, 29},
  3406  			{47, 45, 10, 29}, {47, 46, 10, 29}, {47, 47, 10, 29}, {47, 48, 10, 29}, {47, 49, 10, 29},
  3407  			{47, 50, 10, 29}, {47, 51, 10, 29}, {47, 52, 10, 29}, {47, 53, 10, 29}, {47, 54, 10, 29},
  3408  			{47, 55, 10, 29}, {47, 56, 10, 29}, {47, 57, 10, 29}, {47, 58, 10, 29}, {47, 59, 10, 29},
  3409  			{48, 40, 10, 29}, {48, 41, 10, 29}, {48, 42, 10, 29}, {48, 43, 10, 29}, {48, 44, 10, 29},
  3410  			{48, 45, 10, 29}, {48, 46, 10, 29}, {48, 47, 10, 29}, {48, 48, 10, 29}, {48, 49, 10, 29},
  3411  			{48, 50, 10, 29}, {48, 51, 10, 29}, {48, 52, 10, 29}, {48, 53, 10, 29}, {48, 54, 10, 29},
  3412  			{48, 55, 10, 29}, {48, 56, 10, 29}, {48, 57, 10, 29}, {48, 58, 10, 29}, {48, 59, 10, 29},
  3413  			{49, 40, 10, 29}, {49, 41, 10, 29}, {49, 42, 10, 29}, {49, 43, 10, 29}, {49, 44, 10, 29},
  3414  			{49, 45, 10, 29}, {49, 46, 10, 29}, {49, 47, 10, 29}, {49, 48, 10, 29}, {49, 49, 10, 29},
  3415  			{49, 50, 10, 29}, {49, 51, 10, 29}, {49, 52, 10, 29}, {49, 53, 10, 29}, {49, 54, 10, 29},
  3416  			{49, 55, 10, 29}, {49, 56, 10, 29}, {49, 57, 10, 29}, {49, 58, 10, 29}, {49, 59, 10, 29},
  3417  			{50, 40, 10, 29}, {50, 41, 10, 29}, {50, 42, 10, 29}, {50, 43, 10, 29}, {50, 44, 10, 29},
  3418  			{50, 45, 10, 29}, {50, 46, 10, 29}, {50, 47, 10, 29}, {50, 48, 10, 29}, {50, 49, 10, 29},
  3419  			{50, 50, 10, 29}, {50, 51, 10, 29}, {50, 52, 10, 29}, {50, 53, 10, 29}, {50, 54, 10, 29},
  3420  			{50, 55, 10, 29}, {50, 56, 10, 29}, {50, 57, 10, 29}, {50, 58, 10, 29}, {50, 59, 10, 29},
  3421  			{51, 40, 10, 29}, {51, 41, 10, 29}, {51, 42, 10, 29}, {51, 43, 10, 29}, {51, 44, 10, 29},
  3422  			{51, 45, 10, 29}, {51, 46, 10, 29}, {51, 47, 10, 29}, {51, 48, 10, 29}, {51, 49, 10, 29},
  3423  			{51, 50, 10, 29}, {51, 51, 10, 29}, {51, 52, 10, 29}, {51, 53, 10, 29}, {51, 54, 10, 29},
  3424  			{51, 55, 10, 29}, {51, 56, 10, 29}, {51, 57, 10, 29}, {51, 58, 10, 29}, {51, 59, 10, 29},
  3425  			{52, 40, 10, 29}, {52, 41, 10, 29}, {52, 42, 10, 29}, {52, 43, 10, 29}, {52, 44, 10, 29},
  3426  			{52, 45, 10, 29}, {52, 46, 10, 29}, {52, 47, 10, 29}, {52, 48, 10, 29}, {52, 49, 10, 29},
  3427  			{52, 50, 10, 29}, {52, 51, 10, 29}, {52, 52, 10, 29}, {52, 53, 10, 29}, {52, 54, 10, 29},
  3428  			{52, 55, 10, 29}, {52, 56, 10, 29}, {52, 57, 10, 29}, {52, 58, 10, 29}, {52, 59, 10, 29},
  3429  			{53, 40, 10, 29}, {53, 41, 10, 29}, {53, 42, 10, 29}, {53, 43, 10, 29}, {53, 44, 10, 29},
  3430  			{53, 45, 10, 29}, {53, 46, 10, 29}, {53, 47, 10, 29}, {53, 48, 10, 29}, {53, 49, 10, 29},
  3431  			{53, 50, 10, 29}, {53, 51, 10, 29}, {53, 52, 10, 29}, {53, 53, 10, 29}, {53, 54, 10, 29},
  3432  			{53, 55, 10, 29}, {53, 56, 10, 29}, {53, 57, 10, 29}, {53, 58, 10, 29}, {53, 59, 10, 29},
  3433  			{54, 40, 10, 29}, {54, 41, 10, 29}, {54, 42, 10, 29}, {54, 43, 10, 29}, {54, 44, 10, 29},
  3434  			{54, 45, 10, 29}, {54, 46, 10, 29}, {54, 47, 10, 29}, {54, 48, 10, 29}, {54, 49, 10, 29},
  3435  			{54, 50, 10, 29}, {54, 51, 10, 29}, {54, 52, 10, 29}, {54, 53, 10, 29}, {54, 54, 10, 29},
  3436  			{54, 55, 10, 29}, {54, 56, 10, 29}, {54, 57, 10, 29}, {54, 58, 10, 29}, {54, 59, 10, 29},
  3437  			{55, 40, 10, 29}, {55, 41, 10, 29}, {55, 42, 10, 29}, {55, 43, 10, 29}, {55, 44, 10, 29},
  3438  			{55, 45, 10, 29}, {55, 46, 10, 29}, {55, 47, 10, 29}, {55, 48, 10, 29}, {55, 49, 10, 29},
  3439  			{55, 50, 10, 29}, {55, 51, 10, 29}, {55, 52, 10, 29}, {55, 53, 10, 29}, {55, 54, 10, 29},
  3440  			{55, 55, 10, 29}, {55, 56, 10, 29}, {55, 57, 10, 29}, {55, 58, 10, 29}, {55, 59, 10, 29},
  3441  			{56, 40, 10, 29}, {56, 41, 10, 29}, {56, 42, 10, 29}, {56, 43, 10, 29}, {56, 44, 10, 29},
  3442  			{56, 45, 10, 29}, {56, 46, 10, 29}, {56, 47, 10, 29}, {56, 48, 10, 29}, {56, 49, 10, 29},
  3443  			{56, 50, 10, 29}, {56, 51, 10, 29}, {56, 52, 10, 29}, {56, 53, 10, 29}, {56, 54, 10, 29},
  3444  			{56, 55, 10, 29}, {56, 56, 10, 29}, {56, 57, 10, 29}, {56, 58, 10, 29}, {56, 59, 10, 29},
  3445  			{57, 40, 10, 29}, {57, 41, 10, 29}, {57, 42, 10, 29}, {57, 43, 10, 29}, {57, 44, 10, 29},
  3446  			{57, 45, 10, 29}, {57, 46, 10, 29}, {57, 47, 10, 29}, {57, 48, 10, 29}, {57, 49, 10, 29},
  3447  			{57, 50, 10, 29}, {57, 51, 10, 29}, {57, 52, 10, 29}, {57, 53, 10, 29}, {57, 54, 10, 29},
  3448  			{57, 55, 10, 29}, {57, 56, 10, 29}, {57, 57, 10, 29}, {57, 58, 10, 29}, {57, 59, 10, 29},
  3449  			{58, 40, 10, 29}, {58, 41, 10, 29}, {58, 42, 10, 29}, {58, 43, 10, 29}, {58, 44, 10, 29},
  3450  			{58, 45, 10, 29}, {58, 46, 10, 29}, {58, 47, 10, 29}, {58, 48, 10, 29}, {58, 49, 10, 29},
  3451  			{58, 50, 10, 29}, {58, 51, 10, 29}, {58, 52, 10, 29}, {58, 53, 10, 29}, {58, 54, 10, 29},
  3452  			{58, 55, 10, 29}, {58, 56, 10, 29}, {58, 57, 10, 29}, {58, 58, 10, 29}, {58, 59, 10, 29},
  3453  			{59, 40, 10, 29}, {59, 41, 10, 29}, {59, 42, 10, 29}, {59, 43, 10, 29}, {59, 44, 10, 29},
  3454  			{59, 45, 10, 29}, {59, 46, 10, 29}, {59, 47, 10, 29}, {59, 48, 10, 29}, {59, 49, 10, 29},
  3455  			{59, 50, 10, 29}, {59, 51, 10, 29}, {59, 52, 10, 29}, {59, 53, 10, 29}, {59, 54, 10, 29},
  3456  			{59, 55, 10, 29}, {59, 56, 10, 29}, {59, 57, 10, 29}, {59, 58, 10, 29}, {59, 59, 10, 29},
  3457  			{60, 40, 10, 29}, {60, 41, 10, 29}, {60, 42, 10, 29}, {60, 43, 10, 29}, {60, 44, 10, 29},
  3458  			{60, 45, 10, 29}, {60, 46, 10, 29}, {60, 47, 10, 29}, {60, 48, 10, 29}, {60, 49, 10, 29},
  3459  			{60, 50, 10, 29}, {60, 51, 10, 29}, {60, 52, 10, 29}, {60, 53, 10, 29}, {60, 54, 10, 29},
  3460  			{60, 55, 10, 29}, {60, 56, 10, 29}, {60, 57, 10, 29}, {60, 58, 10, 29}, {60, 59, 10, 29},
  3461  			{61, 40, 10, 29}, {61, 41, 10, 29}, {61, 42, 10, 29}, {61, 43, 10, 29}, {61, 44, 10, 29},
  3462  			{61, 45, 10, 29}, {61, 46, 10, 29}, {61, 47, 10, 29}, {61, 48, 10, 29}, {61, 49, 10, 29},
  3463  			{61, 50, 10, 29}, {61, 51, 10, 29}, {61, 52, 10, 29}, {61, 53, 10, 29}, {61, 54, 10, 29},
  3464  			{61, 55, 10, 29}, {61, 56, 10, 29}, {61, 57, 10, 29}, {61, 58, 10, 29}, {61, 59, 10, 29},
  3465  			{62, 40, 10, 29}, {62, 41, 10, 29}, {62, 42, 10, 29}, {62, 43, 10, 29}, {62, 44, 10, 29},
  3466  			{62, 45, 10, 29}, {62, 46, 10, 29}, {62, 47, 10, 29}, {62, 48, 10, 29}, {62, 49, 10, 29},
  3467  			{62, 50, 10, 29}, {62, 51, 10, 29}, {62, 52, 10, 29}, {62, 53, 10, 29}, {62, 54, 10, 29},
  3468  			{62, 55, 10, 29}, {62, 56, 10, 29}, {62, 57, 10, 29}, {62, 58, 10, 29}, {62, 59, 10, 29},
  3469  			{63, 40, 10, 29}, {63, 41, 10, 29}, {63, 42, 10, 29}, {63, 43, 10, 29}, {63, 44, 10, 29},
  3470  			{63, 45, 10, 29}, {63, 46, 10, 29}, {63, 47, 10, 29}, {63, 48, 10, 29}, {63, 49, 10, 29},
  3471  			{63, 50, 10, 29}, {63, 51, 10, 29}, {63, 52, 10, 29}, {63, 53, 10, 29}, {63, 54, 10, 29},
  3472  			{63, 55, 10, 29}, {63, 56, 10, 29}, {63, 57, 10, 29}, {63, 58, 10, 29}, {63, 59, 10, 29},
  3473  			{64, 40, 10, 29}, {64, 41, 10, 29}, {64, 42, 10, 29}, {64, 43, 10, 29}, {64, 44, 10, 29},
  3474  			{64, 45, 10, 29}, {64, 46, 10, 29}, {64, 47, 10, 29}, {64, 48, 10, 29}, {64, 49, 10, 29},
  3475  			{64, 50, 10, 29}, {64, 51, 10, 29}, {64, 52, 10, 29}, {64, 53, 10, 29}, {64, 54, 10, 29},
  3476  			{64, 55, 10, 29}, {64, 56, 10, 29}, {64, 57, 10, 29}, {64, 58, 10, 29}, {64, 59, 10, 29},
  3477  			{65, 40, 10, 29}, {65, 41, 10, 29}, {65, 42, 10, 29}, {65, 43, 10, 29}, {65, 44, 10, 29},
  3478  			{65, 45, 10, 29}, {65, 46, 10, 29}, {65, 47, 10, 29}, {65, 48, 10, 29}, {65, 49, 10, 29},
  3479  			{65, 50, 10, 29}, {65, 51, 10, 29}, {65, 52, 10, 29}, {65, 53, 10, 29}, {65, 54, 10, 29},
  3480  			{65, 55, 10, 29}, {65, 56, 10, 29}, {65, 57, 10, 29}, {65, 58, 10, 29}, {65, 59, 10, 29},
  3481  			{66, 40, 10, 29}, {66, 41, 10, 29}, {66, 42, 10, 29}, {66, 43, 10, 29}, {66, 44, 10, 29},
  3482  			{66, 45, 10, 29}, {66, 46, 10, 29}, {66, 47, 10, 29}, {66, 48, 10, 29}, {66, 49, 10, 29},
  3483  			{66, 50, 10, 29}, {66, 51, 10, 29}, {66, 52, 10, 29}, {66, 53, 10, 29}, {66, 54, 10, 29},
  3484  			{66, 55, 10, 29}, {66, 56, 10, 29}, {66, 57, 10, 29}, {66, 58, 10, 29}, {66, 59, 10, 29},
  3485  			{67, 40, 10, 29}, {67, 41, 10, 29}, {67, 42, 10, 29}, {67, 43, 10, 29}, {67, 44, 10, 29},
  3486  			{67, 45, 10, 29}, {67, 46, 10, 29}, {67, 47, 10, 29}, {67, 48, 10, 29}, {67, 49, 10, 29},
  3487  			{67, 50, 10, 29}, {67, 51, 10, 29}, {67, 52, 10, 29}, {67, 53, 10, 29}, {67, 54, 10, 29},
  3488  			{67, 55, 10, 29}, {67, 56, 10, 29}, {67, 57, 10, 29}, {67, 58, 10, 29}, {67, 59, 10, 29},
  3489  			{68, 40, 10, 29}, {68, 41, 10, 29}, {68, 42, 10, 29}, {68, 43, 10, 29}, {68, 44, 10, 29},
  3490  			{68, 45, 10, 29}, {68, 46, 10, 29}, {68, 47, 10, 29}, {68, 48, 10, 29}, {68, 49, 10, 29},
  3491  			{68, 50, 10, 29}, {68, 51, 10, 29}, {68, 52, 10, 29}, {68, 53, 10, 29}, {68, 54, 10, 29},
  3492  			{68, 55, 10, 29}, {68, 56, 10, 29}, {68, 57, 10, 29}, {68, 58, 10, 29}, {68, 59, 10, 29},
  3493  			{69, 40, 10, 29}, {69, 41, 10, 29}, {69, 42, 10, 29}, {69, 43, 10, 29}, {69, 44, 10, 29},
  3494  			{69, 45, 10, 29}, {69, 46, 10, 29}, {69, 47, 10, 29}, {69, 48, 10, 29}, {69, 49, 10, 29},
  3495  			{69, 50, 10, 29}, {69, 51, 10, 29}, {69, 52, 10, 29}, {69, 53, 10, 29}, {69, 54, 10, 29},
  3496  			{69, 55, 10, 29}, {69, 56, 10, 29}, {69, 57, 10, 29}, {69, 58, 10, 29}, {69, 59, 10, 29},
  3497  			{70, 40, 10, 29}, {70, 41, 10, 29}, {70, 42, 10, 29}, {70, 43, 10, 29}, {70, 44, 10, 29},
  3498  			{70, 45, 10, 29}, {70, 46, 10, 29}, {70, 47, 10, 29}, {70, 48, 10, 29}, {70, 49, 10, 29},
  3499  			{70, 50, 10, 29}, {70, 51, 10, 29}, {70, 52, 10, 29}, {70, 53, 10, 29}, {70, 54, 10, 29},
  3500  			{70, 55, 10, 29}, {70, 56, 10, 29}, {70, 57, 10, 29}, {70, 58, 10, 29}, {70, 59, 10, 29},
  3501  			{71, 40, 10, 29}, {71, 41, 10, 29}, {71, 42, 10, 29}, {71, 43, 10, 29}, {71, 44, 10, 29},
  3502  			{71, 45, 10, 29}, {71, 46, 10, 29}, {71, 47, 10, 29}, {71, 48, 10, 29}, {71, 49, 10, 29},
  3503  			{71, 50, 10, 29}, {71, 51, 10, 29}, {71, 52, 10, 29}, {71, 53, 10, 29}, {71, 54, 10, 29},
  3504  			{71, 55, 10, 29}, {71, 56, 10, 29}, {71, 57, 10, 29}, {71, 58, 10, 29}, {71, 59, 10, 29},
  3505  			{72, 40, 10, 29}, {72, 41, 10, 29}, {72, 42, 10, 29}, {72, 43, 10, 29}, {72, 44, 10, 29},
  3506  			{72, 45, 10, 29}, {72, 46, 10, 29}, {72, 47, 10, 29}, {72, 48, 10, 29}, {72, 49, 10, 29},
  3507  			{72, 50, 10, 29}, {72, 51, 10, 29}, {72, 52, 10, 29}, {72, 53, 10, 29}, {72, 54, 10, 29},
  3508  			{72, 55, 10, 29}, {72, 56, 10, 29}, {72, 57, 10, 29}, {72, 58, 10, 29}, {72, 59, 10, 29},
  3509  			{73, 40, 10, 29}, {73, 41, 10, 29}, {73, 42, 10, 29}, {73, 43, 10, 29}, {73, 44, 10, 29},
  3510  			{73, 45, 10, 29}, {73, 46, 10, 29}, {73, 47, 10, 29}, {73, 48, 10, 29}, {73, 49, 10, 29},
  3511  			{73, 50, 10, 29}, {73, 51, 10, 29}, {73, 52, 10, 29}, {73, 53, 10, 29}, {73, 54, 10, 29},
  3512  			{73, 55, 10, 29}, {73, 56, 10, 29}, {73, 57, 10, 29}, {73, 58, 10, 29}, {73, 59, 10, 29},
  3513  			{74, 40, 10, 29}, {74, 41, 10, 29}, {74, 42, 10, 29}, {74, 43, 10, 29}, {74, 44, 10, 29},
  3514  			{74, 45, 10, 29}, {74, 46, 10, 29}, {74, 47, 10, 29}, {74, 48, 10, 29}, {74, 49, 10, 29},
  3515  			{74, 50, 10, 29}, {74, 51, 10, 29}, {74, 52, 10, 29}, {74, 53, 10, 29}, {74, 54, 10, 29},
  3516  			{74, 55, 10, 29}, {74, 56, 10, 29}, {74, 57, 10, 29}, {74, 58, 10, 29}, {74, 59, 10, 29},
  3517  			{75, 40, 10, 29}, {75, 41, 10, 29}, {75, 42, 10, 29}, {75, 43, 10, 29}, {75, 44, 10, 29},
  3518  			{75, 45, 10, 29}, {75, 46, 10, 29}, {75, 47, 10, 29}, {75, 48, 10, 29}, {75, 49, 10, 29},
  3519  			{75, 50, 10, 29}, {75, 51, 10, 29}, {75, 52, 10, 29}, {75, 53, 10, 29}, {75, 54, 10, 29},
  3520  			{75, 55, 10, 29}, {75, 56, 10, 29}, {75, 57, 10, 29}, {75, 58, 10, 29}, {75, 59, 10, 29},
  3521  			{76, 40, 10, 29}, {76, 41, 10, 29}, {76, 42, 10, 29}, {76, 43, 10, 29}, {76, 44, 10, 29},
  3522  			{76, 45, 10, 29}, {76, 46, 10, 29}, {76, 47, 10, 29}, {76, 48, 10, 29}, {76, 49, 10, 29},
  3523  			{76, 50, 10, 29}, {76, 51, 10, 29}, {76, 52, 10, 29}, {76, 53, 10, 29}, {76, 54, 10, 29},
  3524  			{76, 55, 10, 29}, {76, 56, 10, 29}, {76, 57, 10, 29}, {76, 58, 10, 29}, {76, 59, 10, 29},
  3525  			{77, 40, 10, 29}, {77, 41, 10, 29}, {77, 42, 10, 29}, {77, 43, 10, 29}, {77, 44, 10, 29},
  3526  			{77, 45, 10, 29}, {77, 46, 10, 29}, {77, 47, 10, 29}, {77, 48, 10, 29}, {77, 49, 10, 29},
  3527  			{77, 50, 10, 29}, {77, 51, 10, 29}, {77, 52, 10, 29}, {77, 53, 10, 29}, {77, 54, 10, 29},
  3528  			{77, 55, 10, 29}, {77, 56, 10, 29}, {77, 57, 10, 29}, {77, 58, 10, 29}, {77, 59, 10, 29},
  3529  			{78, 40, 10, 29}, {78, 41, 10, 29}, {78, 42, 10, 29}, {78, 43, 10, 29}, {78, 44, 10, 29},
  3530  			{78, 45, 10, 29}, {78, 46, 10, 29}, {78, 47, 10, 29}, {78, 48, 10, 29}, {78, 49, 10, 29},
  3531  			{78, 50, 10, 29}, {78, 51, 10, 29}, {78, 52, 10, 29}, {78, 53, 10, 29}, {78, 54, 10, 29},
  3532  			{78, 55, 10, 29}, {78, 56, 10, 29}, {78, 57, 10, 29}, {78, 58, 10, 29}, {78, 59, 10, 29},
  3533  			{79, 40, 10, 29}, {79, 41, 10, 29}, {79, 42, 10, 29}, {79, 43, 10, 29}, {79, 44, 10, 29},
  3534  			{79, 45, 10, 29}, {79, 46, 10, 29}, {79, 47, 10, 29}, {79, 48, 10, 29}, {79, 49, 10, 29},
  3535  			{79, 50, 10, 29}, {79, 51, 10, 29}, {79, 52, 10, 29}, {79, 53, 10, 29}, {79, 54, 10, 29},
  3536  			{79, 55, 10, 29}, {79, 56, 10, 29}, {79, 57, 10, 29}, {79, 58, 10, 29}, {79, 59, 10, 29},
  3537  			{80, 40, 10, 29}, {80, 41, 10, 29}, {80, 42, 10, 29}, {80, 43, 10, 29}, {80, 44, 10, 29},
  3538  			{80, 45, 10, 29}, {80, 46, 10, 29}, {80, 47, 10, 29}, {80, 48, 10, 29}, {80, 49, 10, 29},
  3539  			{80, 50, 10, 29}, {80, 51, 10, 29}, {80, 52, 10, 29}, {80, 53, 10, 29}, {80, 54, 10, 29},
  3540  			{80, 55, 10, 29}, {80, 56, 10, 29}, {80, 57, 10, 29}, {80, 58, 10, 29}, {80, 59, 10, 29},
  3541  			{81, 40, 10, 29}, {81, 41, 10, 29}, {81, 42, 10, 29}, {81, 43, 10, 29}, {81, 44, 10, 29},
  3542  			{81, 45, 10, 29}, {81, 46, 10, 29}, {81, 47, 10, 29}, {81, 48, 10, 29}, {81, 49, 10, 29},
  3543  			{81, 50, 10, 29}, {81, 51, 10, 29}, {81, 52, 10, 29}, {81, 53, 10, 29}, {81, 54, 10, 29},
  3544  			{81, 55, 10, 29}, {81, 56, 10, 29}, {81, 57, 10, 29}, {81, 58, 10, 29}, {81, 59, 10, 29},
  3545  			{82, 40, 10, 29}, {82, 41, 10, 29}, {82, 42, 10, 29}, {82, 43, 10, 29}, {82, 44, 10, 29},
  3546  			{82, 45, 10, 29}, {82, 46, 10, 29}, {82, 47, 10, 29}, {82, 48, 10, 29}, {82, 49, 10, 29},
  3547  			{82, 50, 10, 29}, {82, 51, 10, 29}, {82, 52, 10, 29}, {82, 53, 10, 29}, {82, 54, 10, 29},
  3548  			{82, 55, 10, 29}, {82, 56, 10, 29}, {82, 57, 10, 29}, {82, 58, 10, 29}, {82, 59, 10, 29},
  3549  			{83, 40, 10, 29}, {83, 41, 10, 29}, {83, 42, 10, 29}, {83, 43, 10, 29}, {83, 44, 10, 29},
  3550  			{83, 45, 10, 29}, {83, 46, 10, 29}, {83, 47, 10, 29}, {83, 48, 10, 29}, {83, 49, 10, 29},
  3551  			{83, 50, 10, 29}, {83, 51, 10, 29}, {83, 52, 10, 29}, {83, 53, 10, 29}, {83, 54, 10, 29},
  3552  			{83, 55, 10, 29}, {83, 56, 10, 29}, {83, 57, 10, 29}, {83, 58, 10, 29}, {83, 59, 10, 29},
  3553  			{84, 40, 10, 29}, {84, 41, 10, 29}, {84, 42, 10, 29}, {84, 43, 10, 29}, {84, 44, 10, 29},
  3554  			{84, 45, 10, 29}, {84, 46, 10, 29}, {84, 47, 10, 29}, {84, 48, 10, 29}, {84, 49, 10, 29},
  3555  			{84, 50, 10, 29}, {84, 51, 10, 29}, {84, 52, 10, 29}, {84, 53, 10, 29}, {84, 54, 10, 29},
  3556  			{84, 55, 10, 29}, {84, 56, 10, 29}, {84, 57, 10, 29}, {84, 58, 10, 29}, {84, 59, 10, 29},
  3557  			{85, 40, 10, 29}, {85, 41, 10, 29}, {85, 42, 10, 29}, {85, 43, 10, 29}, {85, 44, 10, 29},
  3558  			{85, 45, 10, 29}, {85, 46, 10, 29}, {85, 47, 10, 29}, {85, 48, 10, 29}, {85, 49, 10, 29},
  3559  			{85, 50, 10, 29}, {85, 51, 10, 29}, {85, 52, 10, 29}, {85, 53, 10, 29}, {85, 54, 10, 29},
  3560  			{85, 55, 10, 29}, {85, 56, 10, 29}, {85, 57, 10, 29}, {85, 58, 10, 29}, {85, 59, 10, 29},
  3561  			{86, 40, 10, 29}, {86, 41, 10, 29}, {86, 42, 10, 29}, {86, 43, 10, 29}, {86, 44, 10, 29},
  3562  			{86, 45, 10, 29}, {86, 46, 10, 29}, {86, 47, 10, 29}, {86, 48, 10, 29}, {86, 49, 10, 29},
  3563  			{86, 50, 10, 29}, {86, 51, 10, 29}, {86, 52, 10, 29}, {86, 53, 10, 29}, {86, 54, 10, 29},
  3564  			{86, 55, 10, 29}, {86, 56, 10, 29}, {86, 57, 10, 29}, {86, 58, 10, 29}, {86, 59, 10, 29},
  3565  			{87, 40, 10, 29}, {87, 41, 10, 29}, {87, 42, 10, 29}, {87, 43, 10, 29}, {87, 44, 10, 29},
  3566  			{87, 45, 10, 29}, {87, 46, 10, 29}, {87, 47, 10, 29}, {87, 48, 10, 29}, {87, 49, 10, 29},
  3567  			{87, 50, 10, 29}, {87, 51, 10, 29}, {87, 52, 10, 29}, {87, 53, 10, 29}, {87, 54, 10, 29},
  3568  			{87, 55, 10, 29}, {87, 56, 10, 29}, {87, 57, 10, 29}, {87, 58, 10, 29}, {87, 59, 10, 29},
  3569  			{88, 40, 10, 29}, {88, 41, 10, 29}, {88, 42, 10, 29}, {88, 43, 10, 29}, {88, 44, 10, 29},
  3570  			{88, 45, 10, 29}, {88, 46, 10, 29}, {88, 47, 10, 29}, {88, 48, 10, 29}, {88, 49, 10, 29},
  3571  			{88, 50, 10, 29}, {88, 51, 10, 29}, {88, 52, 10, 29}, {88, 53, 10, 29}, {88, 54, 10, 29},
  3572  			{88, 55, 10, 29}, {88, 56, 10, 29}, {88, 57, 10, 29}, {88, 58, 10, 29}, {88, 59, 10, 29},
  3573  			{89, 40, 10, 29}, {89, 41, 10, 29}, {89, 42, 10, 29}, {89, 43, 10, 29}, {89, 44, 10, 29},
  3574  			{89, 45, 10, 29}, {89, 46, 10, 29}, {89, 47, 10, 29}, {89, 48, 10, 29}, {89, 49, 10, 29},
  3575  			{89, 50, 10, 29}, {89, 51, 10, 29}, {89, 52, 10, 29}, {89, 53, 10, 29}, {89, 54, 10, 29},
  3576  			{89, 55, 10, 29}, {89, 56, 10, 29}, {89, 57, 10, 29}, {89, 58, 10, 29}, {89, 59, 10, 29},
  3577  		},
  3578  	}
  3579  	body2 = testBody{
  3580  		label:  2,
  3581  		offset: dvid.Point3d{30, 20, 40},
  3582  		size:   dvid.Point3d{50, 50, 20},
  3583  		blockSpans: []dvid.Span{
  3584  			{1, 0, 0, 2},
  3585  			{1, 1, 0, 2},
  3586  			{1, 2, 0, 2},
  3587  		},
  3588  		voxelSpans: []dvid.Span{
  3589  			{40, 20, 30, 31}, {40, 21, 30, 31}, {40, 22, 30, 31}, {40, 23, 30, 31}, {40, 24, 30, 31},
  3590  			{40, 25, 30, 31}, {40, 26, 30, 31}, {40, 27, 30, 31}, {40, 28, 30, 31}, {40, 29, 30, 31},
  3591  			{40, 30, 30, 31}, {40, 31, 30, 31}, {41, 20, 30, 31}, {41, 21, 30, 31}, {41, 22, 30, 31},
  3592  			{41, 23, 30, 31}, {41, 24, 30, 31}, {41, 25, 30, 31}, {41, 26, 30, 31}, {41, 27, 30, 31},
  3593  			{41, 28, 30, 31}, {41, 29, 30, 31}, {41, 30, 30, 31}, {41, 31, 30, 31}, {42, 20, 30, 31},
  3594  			{42, 21, 30, 31}, {42, 22, 30, 31}, {42, 23, 30, 31}, {42, 24, 30, 31}, {42, 25, 30, 31},
  3595  			{42, 26, 30, 31}, {42, 27, 30, 31}, {42, 28, 30, 31}, {42, 29, 30, 31}, {42, 30, 30, 31},
  3596  			{42, 31, 30, 31}, {43, 20, 30, 31}, {43, 21, 30, 31}, {43, 22, 30, 31}, {43, 23, 30, 31},
  3597  			{43, 24, 30, 31}, {43, 25, 30, 31}, {43, 26, 30, 31}, {43, 27, 30, 31}, {43, 28, 30, 31},
  3598  			{43, 29, 30, 31}, {43, 30, 30, 31}, {43, 31, 30, 31}, {44, 20, 30, 31}, {44, 21, 30, 31},
  3599  			{44, 22, 30, 31}, {44, 23, 30, 31}, {44, 24, 30, 31}, {44, 25, 30, 31}, {44, 26, 30, 31},
  3600  			{44, 27, 30, 31}, {44, 28, 30, 31}, {44, 29, 30, 31}, {44, 30, 30, 31}, {44, 31, 30, 31},
  3601  			{45, 20, 30, 31}, {45, 21, 30, 31}, {45, 22, 30, 31}, {45, 23, 30, 31}, {45, 24, 30, 31},
  3602  			{45, 25, 30, 31}, {45, 26, 30, 31}, {45, 27, 30, 31}, {45, 28, 30, 31}, {45, 29, 30, 31},
  3603  			{45, 30, 30, 31}, {45, 31, 30, 31}, {46, 20, 30, 31}, {46, 21, 30, 31}, {46, 22, 30, 31},
  3604  			{46, 23, 30, 31}, {46, 24, 30, 31}, {46, 25, 30, 31}, {46, 26, 30, 31}, {46, 27, 30, 31},
  3605  			{46, 28, 30, 31}, {46, 29, 30, 31}, {46, 30, 30, 31}, {46, 31, 30, 31}, {47, 20, 30, 31},
  3606  			{47, 21, 30, 31}, {47, 22, 30, 31}, {47, 23, 30, 31}, {47, 24, 30, 31}, {47, 25, 30, 31},
  3607  			{47, 26, 30, 31}, {47, 27, 30, 31}, {47, 28, 30, 31}, {47, 29, 30, 31}, {47, 30, 30, 31},
  3608  			{47, 31, 30, 31}, {48, 20, 30, 31}, {48, 21, 30, 31}, {48, 22, 30, 31}, {48, 23, 30, 31},
  3609  			{48, 24, 30, 31}, {48, 25, 30, 31}, {48, 26, 30, 31}, {48, 27, 30, 31}, {48, 28, 30, 31},
  3610  			{48, 29, 30, 31}, {48, 30, 30, 31}, {48, 31, 30, 31}, {49, 20, 30, 31}, {49, 21, 30, 31},
  3611  			{49, 22, 30, 31}, {49, 23, 30, 31}, {49, 24, 30, 31}, {49, 25, 30, 31}, {49, 26, 30, 31},
  3612  			{49, 27, 30, 31}, {49, 28, 30, 31}, {49, 29, 30, 31}, {49, 30, 30, 31}, {49, 31, 30, 31},
  3613  			{50, 20, 30, 31}, {50, 21, 30, 31}, {50, 22, 30, 31}, {50, 23, 30, 31}, {50, 24, 30, 31},
  3614  			{50, 25, 30, 31}, {50, 26, 30, 31}, {50, 27, 30, 31}, {50, 28, 30, 31}, {50, 29, 30, 31},
  3615  			{50, 30, 30, 31}, {50, 31, 30, 31}, {51, 20, 30, 31}, {51, 21, 30, 31}, {51, 22, 30, 31},
  3616  			{51, 23, 30, 31}, {51, 24, 30, 31}, {51, 25, 30, 31}, {51, 26, 30, 31}, {51, 27, 30, 31},
  3617  			{51, 28, 30, 31}, {51, 29, 30, 31}, {51, 30, 30, 31}, {51, 31, 30, 31}, {52, 20, 30, 31},
  3618  			{52, 21, 30, 31}, {52, 22, 30, 31}, {52, 23, 30, 31}, {52, 24, 30, 31}, {52, 25, 30, 31},
  3619  			{52, 26, 30, 31}, {52, 27, 30, 31}, {52, 28, 30, 31}, {52, 29, 30, 31}, {52, 30, 30, 31},
  3620  			{52, 31, 30, 31}, {53, 20, 30, 31}, {53, 21, 30, 31}, {53, 22, 30, 31}, {53, 23, 30, 31},
  3621  			{53, 24, 30, 31}, {53, 25, 30, 31}, {53, 26, 30, 31}, {53, 27, 30, 31}, {53, 28, 30, 31},
  3622  			{53, 29, 30, 31}, {53, 30, 30, 31}, {53, 31, 30, 31}, {54, 20, 30, 31}, {54, 21, 30, 31},
  3623  			{54, 22, 30, 31}, {54, 23, 30, 31}, {54, 24, 30, 31}, {54, 25, 30, 31}, {54, 26, 30, 31},
  3624  			{54, 27, 30, 31}, {54, 28, 30, 31}, {54, 29, 30, 31}, {54, 30, 30, 31}, {54, 31, 30, 31},
  3625  			{55, 20, 30, 31}, {55, 21, 30, 31}, {55, 22, 30, 31}, {55, 23, 30, 31}, {55, 24, 30, 31},
  3626  			{55, 25, 30, 31}, {55, 26, 30, 31}, {55, 27, 30, 31}, {55, 28, 30, 31}, {55, 29, 30, 31},
  3627  			{55, 30, 30, 31}, {55, 31, 30, 31}, {56, 20, 30, 31}, {56, 21, 30, 31}, {56, 22, 30, 31},
  3628  			{56, 23, 30, 31}, {56, 24, 30, 31}, {56, 25, 30, 31}, {56, 26, 30, 31}, {56, 27, 30, 31},
  3629  			{56, 28, 30, 31}, {56, 29, 30, 31}, {56, 30, 30, 31}, {56, 31, 30, 31}, {57, 20, 30, 31},
  3630  			{57, 21, 30, 31}, {57, 22, 30, 31}, {57, 23, 30, 31}, {57, 24, 30, 31}, {57, 25, 30, 31},
  3631  			{57, 26, 30, 31}, {57, 27, 30, 31}, {57, 28, 30, 31}, {57, 29, 30, 31}, {57, 30, 30, 31},
  3632  			{57, 31, 30, 31}, {58, 20, 30, 31}, {58, 21, 30, 31}, {58, 22, 30, 31}, {58, 23, 30, 31},
  3633  			{58, 24, 30, 31}, {58, 25, 30, 31}, {58, 26, 30, 31}, {58, 27, 30, 31}, {58, 28, 30, 31},
  3634  			{58, 29, 30, 31}, {58, 30, 30, 31}, {58, 31, 30, 31}, {59, 20, 30, 31}, {59, 21, 30, 31},
  3635  			{59, 22, 30, 31}, {59, 23, 30, 31}, {59, 24, 30, 31}, {59, 25, 30, 31}, {59, 26, 30, 31},
  3636  			{59, 27, 30, 31}, {59, 28, 30, 31}, {59, 29, 30, 31}, {59, 30, 30, 31}, {59, 31, 30, 31},
  3637  			{40, 20, 32, 63}, {40, 21, 32, 63}, {40, 22, 32, 63}, {40, 23, 32, 63}, {40, 24, 32, 63},
  3638  			{40, 25, 32, 63}, {40, 26, 32, 63}, {40, 27, 32, 63}, {40, 28, 32, 63}, {40, 29, 32, 63},
  3639  			{40, 30, 32, 63}, {40, 31, 32, 63}, {41, 20, 32, 63}, {41, 21, 32, 63}, {41, 22, 32, 63},
  3640  			{41, 23, 32, 63}, {41, 24, 32, 63}, {41, 25, 32, 63}, {41, 26, 32, 63}, {41, 27, 32, 63},
  3641  			{41, 28, 32, 63}, {41, 29, 32, 63}, {41, 30, 32, 63}, {41, 31, 32, 63}, {42, 20, 32, 63},
  3642  			{42, 21, 32, 63}, {42, 22, 32, 63}, {42, 23, 32, 63}, {42, 24, 32, 63}, {42, 25, 32, 63},
  3643  			{42, 26, 32, 63}, {42, 27, 32, 63}, {42, 28, 32, 63}, {42, 29, 32, 63}, {42, 30, 32, 63},
  3644  			{42, 31, 32, 63}, {43, 20, 32, 63}, {43, 21, 32, 63}, {43, 22, 32, 63}, {43, 23, 32, 63},
  3645  			{43, 24, 32, 63}, {43, 25, 32, 63}, {43, 26, 32, 63}, {43, 27, 32, 63}, {43, 28, 32, 63},
  3646  			{43, 29, 32, 63}, {43, 30, 32, 63}, {43, 31, 32, 63}, {44, 20, 32, 63}, {44, 21, 32, 63},
  3647  			{44, 22, 32, 63}, {44, 23, 32, 63}, {44, 24, 32, 63}, {44, 25, 32, 63}, {44, 26, 32, 63},
  3648  			{44, 27, 32, 63}, {44, 28, 32, 63}, {44, 29, 32, 63}, {44, 30, 32, 63}, {44, 31, 32, 63},
  3649  			{45, 20, 32, 63}, {45, 21, 32, 63}, {45, 22, 32, 63}, {45, 23, 32, 63}, {45, 24, 32, 63},
  3650  			{45, 25, 32, 63}, {45, 26, 32, 63}, {45, 27, 32, 63}, {45, 28, 32, 63}, {45, 29, 32, 63},
  3651  			{45, 30, 32, 63}, {45, 31, 32, 63}, {46, 20, 32, 63}, {46, 21, 32, 63}, {46, 22, 32, 63},
  3652  			{46, 23, 32, 63}, {46, 24, 32, 63}, {46, 25, 32, 63}, {46, 26, 32, 63}, {46, 27, 32, 63},
  3653  			{46, 28, 32, 63}, {46, 29, 32, 63}, {46, 30, 32, 63}, {46, 31, 32, 63}, {47, 20, 32, 63},
  3654  			{47, 21, 32, 63}, {47, 22, 32, 63}, {47, 23, 32, 63}, {47, 24, 32, 63}, {47, 25, 32, 63},
  3655  			{47, 26, 32, 63}, {47, 27, 32, 63}, {47, 28, 32, 63}, {47, 29, 32, 63}, {47, 30, 32, 63},
  3656  			{47, 31, 32, 63}, {48, 20, 32, 63}, {48, 21, 32, 63}, {48, 22, 32, 63}, {48, 23, 32, 63},
  3657  			{48, 24, 32, 63}, {48, 25, 32, 63}, {48, 26, 32, 63}, {48, 27, 32, 63}, {48, 28, 32, 63},
  3658  			{48, 29, 32, 63}, {48, 30, 32, 63}, {48, 31, 32, 63}, {49, 20, 32, 63}, {49, 21, 32, 63},
  3659  			{49, 22, 32, 63}, {49, 23, 32, 63}, {49, 24, 32, 63}, {49, 25, 32, 63}, {49, 26, 32, 63},
  3660  			{49, 27, 32, 63}, {49, 28, 32, 63}, {49, 29, 32, 63}, {49, 30, 32, 63}, {49, 31, 32, 63},
  3661  			{50, 20, 32, 63}, {50, 21, 32, 63}, {50, 22, 32, 63}, {50, 23, 32, 63}, {50, 24, 32, 63},
  3662  			{50, 25, 32, 63}, {50, 26, 32, 63}, {50, 27, 32, 63}, {50, 28, 32, 63}, {50, 29, 32, 63},
  3663  			{50, 30, 32, 63}, {50, 31, 32, 63}, {51, 20, 32, 63}, {51, 21, 32, 63}, {51, 22, 32, 63},
  3664  			{51, 23, 32, 63}, {51, 24, 32, 63}, {51, 25, 32, 63}, {51, 26, 32, 63}, {51, 27, 32, 63},
  3665  			{51, 28, 32, 63}, {51, 29, 32, 63}, {51, 30, 32, 63}, {51, 31, 32, 63}, {52, 20, 32, 63},
  3666  			{52, 21, 32, 63}, {52, 22, 32, 63}, {52, 23, 32, 63}, {52, 24, 32, 63}, {52, 25, 32, 63},
  3667  			{52, 26, 32, 63}, {52, 27, 32, 63}, {52, 28, 32, 63}, {52, 29, 32, 63}, {52, 30, 32, 63},
  3668  			{52, 31, 32, 63}, {53, 20, 32, 63}, {53, 21, 32, 63}, {53, 22, 32, 63}, {53, 23, 32, 63},
  3669  			{53, 24, 32, 63}, {53, 25, 32, 63}, {53, 26, 32, 63}, {53, 27, 32, 63}, {53, 28, 32, 63},
  3670  			{53, 29, 32, 63}, {53, 30, 32, 63}, {53, 31, 32, 63}, {54, 20, 32, 63}, {54, 21, 32, 63},
  3671  			{54, 22, 32, 63}, {54, 23, 32, 63}, {54, 24, 32, 63}, {54, 25, 32, 63}, {54, 26, 32, 63},
  3672  			{54, 27, 32, 63}, {54, 28, 32, 63}, {54, 29, 32, 63}, {54, 30, 32, 63}, {54, 31, 32, 63},
  3673  			{55, 20, 32, 63}, {55, 21, 32, 63}, {55, 22, 32, 63}, {55, 23, 32, 63}, {55, 24, 32, 63},
  3674  			{55, 25, 32, 63}, {55, 26, 32, 63}, {55, 27, 32, 63}, {55, 28, 32, 63}, {55, 29, 32, 63},
  3675  			{55, 30, 32, 63}, {55, 31, 32, 63}, {56, 20, 32, 63}, {56, 21, 32, 63}, {56, 22, 32, 63},
  3676  			{56, 23, 32, 63}, {56, 24, 32, 63}, {56, 25, 32, 63}, {56, 26, 32, 63}, {56, 27, 32, 63},
  3677  			{56, 28, 32, 63}, {56, 29, 32, 63}, {56, 30, 32, 63}, {56, 31, 32, 63}, {57, 20, 32, 63},
  3678  			{57, 21, 32, 63}, {57, 22, 32, 63}, {57, 23, 32, 63}, {57, 24, 32, 63}, {57, 25, 32, 63},
  3679  			{57, 26, 32, 63}, {57, 27, 32, 63}, {57, 28, 32, 63}, {57, 29, 32, 63}, {57, 30, 32, 63},
  3680  			{57, 31, 32, 63}, {58, 20, 32, 63}, {58, 21, 32, 63}, {58, 22, 32, 63}, {58, 23, 32, 63},
  3681  			{58, 24, 32, 63}, {58, 25, 32, 63}, {58, 26, 32, 63}, {58, 27, 32, 63}, {58, 28, 32, 63},
  3682  			{58, 29, 32, 63}, {58, 30, 32, 63}, {58, 31, 32, 63}, {59, 20, 32, 63}, {59, 21, 32, 63},
  3683  			{59, 22, 32, 63}, {59, 23, 32, 63}, {59, 24, 32, 63}, {59, 25, 32, 63}, {59, 26, 32, 63},
  3684  			{59, 27, 32, 63}, {59, 28, 32, 63}, {59, 29, 32, 63}, {59, 30, 32, 63}, {59, 31, 32, 63},
  3685  			{40, 20, 64, 79}, {40, 21, 64, 79}, {40, 22, 64, 79}, {40, 23, 64, 79}, {40, 24, 64, 79},
  3686  			{40, 25, 64, 79}, {40, 26, 64, 79}, {40, 27, 64, 79}, {40, 28, 64, 79}, {40, 29, 64, 79},
  3687  			{40, 30, 64, 79}, {40, 31, 64, 79}, {41, 20, 64, 79}, {41, 21, 64, 79}, {41, 22, 64, 79},
  3688  			{41, 23, 64, 79}, {41, 24, 64, 79}, {41, 25, 64, 79}, {41, 26, 64, 79}, {41, 27, 64, 79},
  3689  			{41, 28, 64, 79}, {41, 29, 64, 79}, {41, 30, 64, 79}, {41, 31, 64, 79}, {42, 20, 64, 79},
  3690  			{42, 21, 64, 79}, {42, 22, 64, 79}, {42, 23, 64, 79}, {42, 24, 64, 79}, {42, 25, 64, 79},
  3691  			{42, 26, 64, 79}, {42, 27, 64, 79}, {42, 28, 64, 79}, {42, 29, 64, 79}, {42, 30, 64, 79},
  3692  			{42, 31, 64, 79}, {43, 20, 64, 79}, {43, 21, 64, 79}, {43, 22, 64, 79}, {43, 23, 64, 79},
  3693  			{43, 24, 64, 79}, {43, 25, 64, 79}, {43, 26, 64, 79}, {43, 27, 64, 79}, {43, 28, 64, 79},
  3694  			{43, 29, 64, 79}, {43, 30, 64, 79}, {43, 31, 64, 79}, {44, 20, 64, 79}, {44, 21, 64, 79},
  3695  			{44, 22, 64, 79}, {44, 23, 64, 79}, {44, 24, 64, 79}, {44, 25, 64, 79}, {44, 26, 64, 79},
  3696  			{44, 27, 64, 79}, {44, 28, 64, 79}, {44, 29, 64, 79}, {44, 30, 64, 79}, {44, 31, 64, 79},
  3697  			{45, 20, 64, 79}, {45, 21, 64, 79}, {45, 22, 64, 79}, {45, 23, 64, 79}, {45, 24, 64, 79},
  3698  			{45, 25, 64, 79}, {45, 26, 64, 79}, {45, 27, 64, 79}, {45, 28, 64, 79}, {45, 29, 64, 79},
  3699  			{45, 30, 64, 79}, {45, 31, 64, 79}, {46, 20, 64, 79}, {46, 21, 64, 79}, {46, 22, 64, 79},
  3700  			{46, 23, 64, 79}, {46, 24, 64, 79}, {46, 25, 64, 79}, {46, 26, 64, 79}, {46, 27, 64, 79},
  3701  			{46, 28, 64, 79}, {46, 29, 64, 79}, {46, 30, 64, 79}, {46, 31, 64, 79}, {47, 20, 64, 79},
  3702  			{47, 21, 64, 79}, {47, 22, 64, 79}, {47, 23, 64, 79}, {47, 24, 64, 79}, {47, 25, 64, 79},
  3703  			{47, 26, 64, 79}, {47, 27, 64, 79}, {47, 28, 64, 79}, {47, 29, 64, 79}, {47, 30, 64, 79},
  3704  			{47, 31, 64, 79}, {48, 20, 64, 79}, {48, 21, 64, 79}, {48, 22, 64, 79}, {48, 23, 64, 79},
  3705  			{48, 24, 64, 79}, {48, 25, 64, 79}, {48, 26, 64, 79}, {48, 27, 64, 79}, {48, 28, 64, 79},
  3706  			{48, 29, 64, 79}, {48, 30, 64, 79}, {48, 31, 64, 79}, {49, 20, 64, 79}, {49, 21, 64, 79},
  3707  			{49, 22, 64, 79}, {49, 23, 64, 79}, {49, 24, 64, 79}, {49, 25, 64, 79}, {49, 26, 64, 79},
  3708  			{49, 27, 64, 79}, {49, 28, 64, 79}, {49, 29, 64, 79}, {49, 30, 64, 79}, {49, 31, 64, 79},
  3709  			{50, 20, 64, 79}, {50, 21, 64, 79}, {50, 22, 64, 79}, {50, 23, 64, 79}, {50, 24, 64, 79},
  3710  			{50, 25, 64, 79}, {50, 26, 64, 79}, {50, 27, 64, 79}, {50, 28, 64, 79}, {50, 29, 64, 79},
  3711  			{50, 30, 64, 79}, {50, 31, 64, 79}, {51, 20, 64, 79}, {51, 21, 64, 79}, {51, 22, 64, 79},
  3712  			{51, 23, 64, 79}, {51, 24, 64, 79}, {51, 25, 64, 79}, {51, 26, 64, 79}, {51, 27, 64, 79},
  3713  			{51, 28, 64, 79}, {51, 29, 64, 79}, {51, 30, 64, 79}, {51, 31, 64, 79}, {52, 20, 64, 79},
  3714  			{52, 21, 64, 79}, {52, 22, 64, 79}, {52, 23, 64, 79}, {52, 24, 64, 79}, {52, 25, 64, 79},
  3715  			{52, 26, 64, 79}, {52, 27, 64, 79}, {52, 28, 64, 79}, {52, 29, 64, 79}, {52, 30, 64, 79},
  3716  			{52, 31, 64, 79}, {53, 20, 64, 79}, {53, 21, 64, 79}, {53, 22, 64, 79}, {53, 23, 64, 79},
  3717  			{53, 24, 64, 79}, {53, 25, 64, 79}, {53, 26, 64, 79}, {53, 27, 64, 79}, {53, 28, 64, 79},
  3718  			{53, 29, 64, 79}, {53, 30, 64, 79}, {53, 31, 64, 79}, {54, 20, 64, 79}, {54, 21, 64, 79},
  3719  			{54, 22, 64, 79}, {54, 23, 64, 79}, {54, 24, 64, 79}, {54, 25, 64, 79}, {54, 26, 64, 79},
  3720  			{54, 27, 64, 79}, {54, 28, 64, 79}, {54, 29, 64, 79}, {54, 30, 64, 79}, {54, 31, 64, 79},
  3721  			{55, 20, 64, 79}, {55, 21, 64, 79}, {55, 22, 64, 79}, {55, 23, 64, 79}, {55, 24, 64, 79},
  3722  			{55, 25, 64, 79}, {55, 26, 64, 79}, {55, 27, 64, 79}, {55, 28, 64, 79}, {55, 29, 64, 79},
  3723  			{55, 30, 64, 79}, {55, 31, 64, 79}, {56, 20, 64, 79}, {56, 21, 64, 79}, {56, 22, 64, 79},
  3724  			{56, 23, 64, 79}, {56, 24, 64, 79}, {56, 25, 64, 79}, {56, 26, 64, 79}, {56, 27, 64, 79},
  3725  			{56, 28, 64, 79}, {56, 29, 64, 79}, {56, 30, 64, 79}, {56, 31, 64, 79}, {57, 20, 64, 79},
  3726  			{57, 21, 64, 79}, {57, 22, 64, 79}, {57, 23, 64, 79}, {57, 24, 64, 79}, {57, 25, 64, 79},
  3727  			{57, 26, 64, 79}, {57, 27, 64, 79}, {57, 28, 64, 79}, {57, 29, 64, 79}, {57, 30, 64, 79},
  3728  			{57, 31, 64, 79}, {58, 20, 64, 79}, {58, 21, 64, 79}, {58, 22, 64, 79}, {58, 23, 64, 79},
  3729  			{58, 24, 64, 79}, {58, 25, 64, 79}, {58, 26, 64, 79}, {58, 27, 64, 79}, {58, 28, 64, 79},
  3730  			{58, 29, 64, 79}, {58, 30, 64, 79}, {58, 31, 64, 79}, {59, 20, 64, 79}, {59, 21, 64, 79},
  3731  			{59, 22, 64, 79}, {59, 23, 64, 79}, {59, 24, 64, 79}, {59, 25, 64, 79}, {59, 26, 64, 79},
  3732  			{59, 27, 64, 79}, {59, 28, 64, 79}, {59, 29, 64, 79}, {59, 30, 64, 79}, {59, 31, 64, 79},
  3733  			{40, 32, 30, 31}, {40, 33, 30, 31}, {40, 34, 30, 31}, {40, 35, 30, 31}, {40, 36, 30, 31},
  3734  			{40, 37, 30, 31}, {40, 38, 30, 31}, {40, 39, 30, 31}, {40, 40, 30, 31}, {40, 41, 30, 31},
  3735  			{40, 42, 30, 31}, {40, 43, 30, 31}, {40, 44, 30, 31}, {40, 45, 30, 31}, {40, 46, 30, 31},
  3736  			{40, 47, 30, 31}, {40, 48, 30, 31}, {40, 49, 30, 31}, {40, 50, 30, 31}, {40, 51, 30, 31},
  3737  			{40, 52, 30, 31}, {40, 53, 30, 31}, {40, 54, 30, 31}, {40, 55, 30, 31}, {40, 56, 30, 31},
  3738  			{40, 57, 30, 31}, {40, 58, 30, 31}, {40, 59, 30, 31}, {40, 60, 30, 31}, {40, 61, 30, 31},
  3739  			{40, 62, 30, 31}, {40, 63, 30, 31}, {41, 32, 30, 31}, {41, 33, 30, 31}, {41, 34, 30, 31},
  3740  			{41, 35, 30, 31}, {41, 36, 30, 31}, {41, 37, 30, 31}, {41, 38, 30, 31}, {41, 39, 30, 31},
  3741  			{41, 40, 30, 31}, {41, 41, 30, 31}, {41, 42, 30, 31}, {41, 43, 30, 31}, {41, 44, 30, 31},
  3742  			{41, 45, 30, 31}, {41, 46, 30, 31}, {41, 47, 30, 31}, {41, 48, 30, 31}, {41, 49, 30, 31},
  3743  			{41, 50, 30, 31}, {41, 51, 30, 31}, {41, 52, 30, 31}, {41, 53, 30, 31}, {41, 54, 30, 31},
  3744  			{41, 55, 30, 31}, {41, 56, 30, 31}, {41, 57, 30, 31}, {41, 58, 30, 31}, {41, 59, 30, 31},
  3745  			{41, 60, 30, 31}, {41, 61, 30, 31}, {41, 62, 30, 31}, {41, 63, 30, 31}, {42, 32, 30, 31},
  3746  			{42, 33, 30, 31}, {42, 34, 30, 31}, {42, 35, 30, 31}, {42, 36, 30, 31}, {42, 37, 30, 31},
  3747  			{42, 38, 30, 31}, {42, 39, 30, 31}, {42, 40, 30, 31}, {42, 41, 30, 31}, {42, 42, 30, 31},
  3748  			{42, 43, 30, 31}, {42, 44, 30, 31}, {42, 45, 30, 31}, {42, 46, 30, 31}, {42, 47, 30, 31},
  3749  			{42, 48, 30, 31}, {42, 49, 30, 31}, {42, 50, 30, 31}, {42, 51, 30, 31}, {42, 52, 30, 31},
  3750  			{42, 53, 30, 31}, {42, 54, 30, 31}, {42, 55, 30, 31}, {42, 56, 30, 31}, {42, 57, 30, 31},
  3751  			{42, 58, 30, 31}, {42, 59, 30, 31}, {42, 60, 30, 31}, {42, 61, 30, 31}, {42, 62, 30, 31},
  3752  			{42, 63, 30, 31}, {43, 32, 30, 31}, {43, 33, 30, 31}, {43, 34, 30, 31}, {43, 35, 30, 31},
  3753  			{43, 36, 30, 31}, {43, 37, 30, 31}, {43, 38, 30, 31}, {43, 39, 30, 31}, {43, 40, 30, 31},
  3754  			{43, 41, 30, 31}, {43, 42, 30, 31}, {43, 43, 30, 31}, {43, 44, 30, 31}, {43, 45, 30, 31},
  3755  			{43, 46, 30, 31}, {43, 47, 30, 31}, {43, 48, 30, 31}, {43, 49, 30, 31}, {43, 50, 30, 31},
  3756  			{43, 51, 30, 31}, {43, 52, 30, 31}, {43, 53, 30, 31}, {43, 54, 30, 31}, {43, 55, 30, 31},
  3757  			{43, 56, 30, 31}, {43, 57, 30, 31}, {43, 58, 30, 31}, {43, 59, 30, 31}, {43, 60, 30, 31},
  3758  			{43, 61, 30, 31}, {43, 62, 30, 31}, {43, 63, 30, 31}, {44, 32, 30, 31}, {44, 33, 30, 31},
  3759  			{44, 34, 30, 31}, {44, 35, 30, 31}, {44, 36, 30, 31}, {44, 37, 30, 31}, {44, 38, 30, 31},
  3760  			{44, 39, 30, 31}, {44, 40, 30, 31}, {44, 41, 30, 31}, {44, 42, 30, 31}, {44, 43, 30, 31},
  3761  			{44, 44, 30, 31}, {44, 45, 30, 31}, {44, 46, 30, 31}, {44, 47, 30, 31}, {44, 48, 30, 31},
  3762  			{44, 49, 30, 31}, {44, 50, 30, 31}, {44, 51, 30, 31}, {44, 52, 30, 31}, {44, 53, 30, 31},
  3763  			{44, 54, 30, 31}, {44, 55, 30, 31}, {44, 56, 30, 31}, {44, 57, 30, 31}, {44, 58, 30, 31},
  3764  			{44, 59, 30, 31}, {44, 60, 30, 31}, {44, 61, 30, 31}, {44, 62, 30, 31}, {44, 63, 30, 31},
  3765  			{45, 32, 30, 31}, {45, 33, 30, 31}, {45, 34, 30, 31}, {45, 35, 30, 31}, {45, 36, 30, 31},
  3766  			{45, 37, 30, 31}, {45, 38, 30, 31}, {45, 39, 30, 31}, {45, 40, 30, 31}, {45, 41, 30, 31},
  3767  			{45, 42, 30, 31}, {45, 43, 30, 31}, {45, 44, 30, 31}, {45, 45, 30, 31}, {45, 46, 30, 31},
  3768  			{45, 47, 30, 31}, {45, 48, 30, 31}, {45, 49, 30, 31}, {45, 50, 30, 31}, {45, 51, 30, 31},
  3769  			{45, 52, 30, 31}, {45, 53, 30, 31}, {45, 54, 30, 31}, {45, 55, 30, 31}, {45, 56, 30, 31},
  3770  			{45, 57, 30, 31}, {45, 58, 30, 31}, {45, 59, 30, 31}, {45, 60, 30, 31}, {45, 61, 30, 31},
  3771  			{45, 62, 30, 31}, {45, 63, 30, 31}, {46, 32, 30, 31}, {46, 33, 30, 31}, {46, 34, 30, 31},
  3772  			{46, 35, 30, 31}, {46, 36, 30, 31}, {46, 37, 30, 31}, {46, 38, 30, 31}, {46, 39, 30, 31},
  3773  			{46, 40, 30, 31}, {46, 41, 30, 31}, {46, 42, 30, 31}, {46, 43, 30, 31}, {46, 44, 30, 31},
  3774  			{46, 45, 30, 31}, {46, 46, 30, 31}, {46, 47, 30, 31}, {46, 48, 30, 31}, {46, 49, 30, 31},
  3775  			{46, 50, 30, 31}, {46, 51, 30, 31}, {46, 52, 30, 31}, {46, 53, 30, 31}, {46, 54, 30, 31},
  3776  			{46, 55, 30, 31}, {46, 56, 30, 31}, {46, 57, 30, 31}, {46, 58, 30, 31}, {46, 59, 30, 31},
  3777  			{46, 60, 30, 31}, {46, 61, 30, 31}, {46, 62, 30, 31}, {46, 63, 30, 31}, {47, 32, 30, 31},
  3778  			{47, 33, 30, 31}, {47, 34, 30, 31}, {47, 35, 30, 31}, {47, 36, 30, 31}, {47, 37, 30, 31},
  3779  			{47, 38, 30, 31}, {47, 39, 30, 31}, {47, 40, 30, 31}, {47, 41, 30, 31}, {47, 42, 30, 31},
  3780  			{47, 43, 30, 31}, {47, 44, 30, 31}, {47, 45, 30, 31}, {47, 46, 30, 31}, {47, 47, 30, 31},
  3781  			{47, 48, 30, 31}, {47, 49, 30, 31}, {47, 50, 30, 31}, {47, 51, 30, 31}, {47, 52, 30, 31},
  3782  			{47, 53, 30, 31}, {47, 54, 30, 31}, {47, 55, 30, 31}, {47, 56, 30, 31}, {47, 57, 30, 31},
  3783  			{47, 58, 30, 31}, {47, 59, 30, 31}, {47, 60, 30, 31}, {47, 61, 30, 31}, {47, 62, 30, 31},
  3784  			{47, 63, 30, 31}, {48, 32, 30, 31}, {48, 33, 30, 31}, {48, 34, 30, 31}, {48, 35, 30, 31},
  3785  			{48, 36, 30, 31}, {48, 37, 30, 31}, {48, 38, 30, 31}, {48, 39, 30, 31}, {48, 40, 30, 31},
  3786  			{48, 41, 30, 31}, {48, 42, 30, 31}, {48, 43, 30, 31}, {48, 44, 30, 31}, {48, 45, 30, 31},
  3787  			{48, 46, 30, 31}, {48, 47, 30, 31}, {48, 48, 30, 31}, {48, 49, 30, 31}, {48, 50, 30, 31},
  3788  			{48, 51, 30, 31}, {48, 52, 30, 31}, {48, 53, 30, 31}, {48, 54, 30, 31}, {48, 55, 30, 31},
  3789  			{48, 56, 30, 31}, {48, 57, 30, 31}, {48, 58, 30, 31}, {48, 59, 30, 31}, {48, 60, 30, 31},
  3790  			{48, 61, 30, 31}, {48, 62, 30, 31}, {48, 63, 30, 31}, {49, 32, 30, 31}, {49, 33, 30, 31},
  3791  			{49, 34, 30, 31}, {49, 35, 30, 31}, {49, 36, 30, 31}, {49, 37, 30, 31}, {49, 38, 30, 31},
  3792  			{49, 39, 30, 31}, {49, 40, 30, 31}, {49, 41, 30, 31}, {49, 42, 30, 31}, {49, 43, 30, 31},
  3793  			{49, 44, 30, 31}, {49, 45, 30, 31}, {49, 46, 30, 31}, {49, 47, 30, 31}, {49, 48, 30, 31},
  3794  			{49, 49, 30, 31}, {49, 50, 30, 31}, {49, 51, 30, 31}, {49, 52, 30, 31}, {49, 53, 30, 31},
  3795  			{49, 54, 30, 31}, {49, 55, 30, 31}, {49, 56, 30, 31}, {49, 57, 30, 31}, {49, 58, 30, 31},
  3796  			{49, 59, 30, 31}, {49, 60, 30, 31}, {49, 61, 30, 31}, {49, 62, 30, 31}, {49, 63, 30, 31},
  3797  			{50, 32, 30, 31}, {50, 33, 30, 31}, {50, 34, 30, 31}, {50, 35, 30, 31}, {50, 36, 30, 31},
  3798  			{50, 37, 30, 31}, {50, 38, 30, 31}, {50, 39, 30, 31}, {50, 40, 30, 31}, {50, 41, 30, 31},
  3799  			{50, 42, 30, 31}, {50, 43, 30, 31}, {50, 44, 30, 31}, {50, 45, 30, 31}, {50, 46, 30, 31},
  3800  			{50, 47, 30, 31}, {50, 48, 30, 31}, {50, 49, 30, 31}, {50, 50, 30, 31}, {50, 51, 30, 31},
  3801  			{50, 52, 30, 31}, {50, 53, 30, 31}, {50, 54, 30, 31}, {50, 55, 30, 31}, {50, 56, 30, 31},
  3802  			{50, 57, 30, 31}, {50, 58, 30, 31}, {50, 59, 30, 31}, {50, 60, 30, 31}, {50, 61, 30, 31},
  3803  			{50, 62, 30, 31}, {50, 63, 30, 31}, {51, 32, 30, 31}, {51, 33, 30, 31}, {51, 34, 30, 31},
  3804  			{51, 35, 30, 31}, {51, 36, 30, 31}, {51, 37, 30, 31}, {51, 38, 30, 31}, {51, 39, 30, 31},
  3805  			{51, 40, 30, 31}, {51, 41, 30, 31}, {51, 42, 30, 31}, {51, 43, 30, 31}, {51, 44, 30, 31},
  3806  			{51, 45, 30, 31}, {51, 46, 30, 31}, {51, 47, 30, 31}, {51, 48, 30, 31}, {51, 49, 30, 31},
  3807  			{51, 50, 30, 31}, {51, 51, 30, 31}, {51, 52, 30, 31}, {51, 53, 30, 31}, {51, 54, 30, 31},
  3808  			{51, 55, 30, 31}, {51, 56, 30, 31}, {51, 57, 30, 31}, {51, 58, 30, 31}, {51, 59, 30, 31},
  3809  			{51, 60, 30, 31}, {51, 61, 30, 31}, {51, 62, 30, 31}, {51, 63, 30, 31}, {52, 32, 30, 31},
  3810  			{52, 33, 30, 31}, {52, 34, 30, 31}, {52, 35, 30, 31}, {52, 36, 30, 31}, {52, 37, 30, 31},
  3811  			{52, 38, 30, 31}, {52, 39, 30, 31}, {52, 40, 30, 31}, {52, 41, 30, 31}, {52, 42, 30, 31},
  3812  			{52, 43, 30, 31}, {52, 44, 30, 31}, {52, 45, 30, 31}, {52, 46, 30, 31}, {52, 47, 30, 31},
  3813  			{52, 48, 30, 31}, {52, 49, 30, 31}, {52, 50, 30, 31}, {52, 51, 30, 31}, {52, 52, 30, 31},
  3814  			{52, 53, 30, 31}, {52, 54, 30, 31}, {52, 55, 30, 31}, {52, 56, 30, 31}, {52, 57, 30, 31},
  3815  			{52, 58, 30, 31}, {52, 59, 30, 31}, {52, 60, 30, 31}, {52, 61, 30, 31}, {52, 62, 30, 31},
  3816  			{52, 63, 30, 31}, {53, 32, 30, 31}, {53, 33, 30, 31}, {53, 34, 30, 31}, {53, 35, 30, 31},
  3817  			{53, 36, 30, 31}, {53, 37, 30, 31}, {53, 38, 30, 31}, {53, 39, 30, 31}, {53, 40, 30, 31},
  3818  			{53, 41, 30, 31}, {53, 42, 30, 31}, {53, 43, 30, 31}, {53, 44, 30, 31}, {53, 45, 30, 31},
  3819  			{53, 46, 30, 31}, {53, 47, 30, 31}, {53, 48, 30, 31}, {53, 49, 30, 31}, {53, 50, 30, 31},
  3820  			{53, 51, 30, 31}, {53, 52, 30, 31}, {53, 53, 30, 31}, {53, 54, 30, 31}, {53, 55, 30, 31},
  3821  			{53, 56, 30, 31}, {53, 57, 30, 31}, {53, 58, 30, 31}, {53, 59, 30, 31}, {53, 60, 30, 31},
  3822  			{53, 61, 30, 31}, {53, 62, 30, 31}, {53, 63, 30, 31}, {54, 32, 30, 31}, {54, 33, 30, 31},
  3823  			{54, 34, 30, 31}, {54, 35, 30, 31}, {54, 36, 30, 31}, {54, 37, 30, 31}, {54, 38, 30, 31},
  3824  			{54, 39, 30, 31}, {54, 40, 30, 31}, {54, 41, 30, 31}, {54, 42, 30, 31}, {54, 43, 30, 31},
  3825  			{54, 44, 30, 31}, {54, 45, 30, 31}, {54, 46, 30, 31}, {54, 47, 30, 31}, {54, 48, 30, 31},
  3826  			{54, 49, 30, 31}, {54, 50, 30, 31}, {54, 51, 30, 31}, {54, 52, 30, 31}, {54, 53, 30, 31},
  3827  			{54, 54, 30, 31}, {54, 55, 30, 31}, {54, 56, 30, 31}, {54, 57, 30, 31}, {54, 58, 30, 31},
  3828  			{54, 59, 30, 31}, {54, 60, 30, 31}, {54, 61, 30, 31}, {54, 62, 30, 31}, {54, 63, 30, 31},
  3829  			{55, 32, 30, 31}, {55, 33, 30, 31}, {55, 34, 30, 31}, {55, 35, 30, 31}, {55, 36, 30, 31},
  3830  			{55, 37, 30, 31}, {55, 38, 30, 31}, {55, 39, 30, 31}, {55, 40, 30, 31}, {55, 41, 30, 31},
  3831  			{55, 42, 30, 31}, {55, 43, 30, 31}, {55, 44, 30, 31}, {55, 45, 30, 31}, {55, 46, 30, 31},
  3832  			{55, 47, 30, 31}, {55, 48, 30, 31}, {55, 49, 30, 31}, {55, 50, 30, 31}, {55, 51, 30, 31},
  3833  			{55, 52, 30, 31}, {55, 53, 30, 31}, {55, 54, 30, 31}, {55, 55, 30, 31}, {55, 56, 30, 31},
  3834  			{55, 57, 30, 31}, {55, 58, 30, 31}, {55, 59, 30, 31}, {55, 60, 30, 31}, {55, 61, 30, 31},
  3835  			{55, 62, 30, 31}, {55, 63, 30, 31}, {56, 32, 30, 31}, {56, 33, 30, 31}, {56, 34, 30, 31},
  3836  			{56, 35, 30, 31}, {56, 36, 30, 31}, {56, 37, 30, 31}, {56, 38, 30, 31}, {56, 39, 30, 31},
  3837  			{56, 40, 30, 31}, {56, 41, 30, 31}, {56, 42, 30, 31}, {56, 43, 30, 31}, {56, 44, 30, 31},
  3838  			{56, 45, 30, 31}, {56, 46, 30, 31}, {56, 47, 30, 31}, {56, 48, 30, 31}, {56, 49, 30, 31},
  3839  			{56, 50, 30, 31}, {56, 51, 30, 31}, {56, 52, 30, 31}, {56, 53, 30, 31}, {56, 54, 30, 31},
  3840  			{56, 55, 30, 31}, {56, 56, 30, 31}, {56, 57, 30, 31}, {56, 58, 30, 31}, {56, 59, 30, 31},
  3841  			{56, 60, 30, 31}, {56, 61, 30, 31}, {56, 62, 30, 31}, {56, 63, 30, 31}, {57, 32, 30, 31},
  3842  			{57, 33, 30, 31}, {57, 34, 30, 31}, {57, 35, 30, 31}, {57, 36, 30, 31}, {57, 37, 30, 31},
  3843  			{57, 38, 30, 31}, {57, 39, 30, 31}, {57, 40, 30, 31}, {57, 41, 30, 31}, {57, 42, 30, 31},
  3844  			{57, 43, 30, 31}, {57, 44, 30, 31}, {57, 45, 30, 31}, {57, 46, 30, 31}, {57, 47, 30, 31},
  3845  			{57, 48, 30, 31}, {57, 49, 30, 31}, {57, 50, 30, 31}, {57, 51, 30, 31}, {57, 52, 30, 31},
  3846  			{57, 53, 30, 31}, {57, 54, 30, 31}, {57, 55, 30, 31}, {57, 56, 30, 31}, {57, 57, 30, 31},
  3847  			{57, 58, 30, 31}, {57, 59, 30, 31}, {57, 60, 30, 31}, {57, 61, 30, 31}, {57, 62, 30, 31},
  3848  			{57, 63, 30, 31}, {58, 32, 30, 31}, {58, 33, 30, 31}, {58, 34, 30, 31}, {58, 35, 30, 31},
  3849  			{58, 36, 30, 31}, {58, 37, 30, 31}, {58, 38, 30, 31}, {58, 39, 30, 31}, {58, 40, 30, 31},
  3850  			{58, 41, 30, 31}, {58, 42, 30, 31}, {58, 43, 30, 31}, {58, 44, 30, 31}, {58, 45, 30, 31},
  3851  			{58, 46, 30, 31}, {58, 47, 30, 31}, {58, 48, 30, 31}, {58, 49, 30, 31}, {58, 50, 30, 31},
  3852  			{58, 51, 30, 31}, {58, 52, 30, 31}, {58, 53, 30, 31}, {58, 54, 30, 31}, {58, 55, 30, 31},
  3853  			{58, 56, 30, 31}, {58, 57, 30, 31}, {58, 58, 30, 31}, {58, 59, 30, 31}, {58, 60, 30, 31},
  3854  			{58, 61, 30, 31}, {58, 62, 30, 31}, {58, 63, 30, 31}, {59, 32, 30, 31}, {59, 33, 30, 31},
  3855  			{59, 34, 30, 31}, {59, 35, 30, 31}, {59, 36, 30, 31}, {59, 37, 30, 31}, {59, 38, 30, 31},
  3856  			{59, 39, 30, 31}, {59, 40, 30, 31}, {59, 41, 30, 31}, {59, 42, 30, 31}, {59, 43, 30, 31},
  3857  			{59, 44, 30, 31}, {59, 45, 30, 31}, {59, 46, 30, 31}, {59, 47, 30, 31}, {59, 48, 30, 31},
  3858  			{59, 49, 30, 31}, {59, 50, 30, 31}, {59, 51, 30, 31}, {59, 52, 30, 31}, {59, 53, 30, 31},
  3859  			{59, 54, 30, 31}, {59, 55, 30, 31}, {59, 56, 30, 31}, {59, 57, 30, 31}, {59, 58, 30, 31},
  3860  			{59, 59, 30, 31}, {59, 60, 30, 31}, {59, 61, 30, 31}, {59, 62, 30, 31}, {59, 63, 30, 31},
  3861  			{40, 32, 32, 63}, {40, 33, 32, 63}, {40, 34, 32, 63}, {40, 35, 32, 63}, {40, 36, 32, 63},
  3862  			{40, 37, 32, 63}, {40, 38, 32, 63}, {40, 39, 32, 63}, {40, 40, 32, 63}, {40, 41, 32, 63},
  3863  			{40, 42, 32, 63}, {40, 43, 32, 63}, {40, 44, 32, 63}, {40, 45, 32, 63}, {40, 46, 32, 63},
  3864  			{40, 47, 32, 63}, {40, 48, 32, 63}, {40, 49, 32, 63}, {40, 50, 32, 63}, {40, 51, 32, 63},
  3865  			{40, 52, 32, 63}, {40, 53, 32, 63}, {40, 54, 32, 63}, {40, 55, 32, 63}, {40, 56, 32, 63},
  3866  			{40, 57, 32, 63}, {40, 58, 32, 63}, {40, 59, 32, 63}, {40, 60, 32, 63}, {40, 61, 32, 63},
  3867  			{40, 62, 32, 63}, {40, 63, 32, 63}, {41, 32, 32, 63}, {41, 33, 32, 63}, {41, 34, 32, 63},
  3868  			{41, 35, 32, 63}, {41, 36, 32, 63}, {41, 37, 32, 63}, {41, 38, 32, 63}, {41, 39, 32, 63},
  3869  			{41, 40, 32, 63}, {41, 41, 32, 63}, {41, 42, 32, 63}, {41, 43, 32, 63}, {41, 44, 32, 63},
  3870  			{41, 45, 32, 63}, {41, 46, 32, 63}, {41, 47, 32, 63}, {41, 48, 32, 63}, {41, 49, 32, 63},
  3871  			{41, 50, 32, 63}, {41, 51, 32, 63}, {41, 52, 32, 63}, {41, 53, 32, 63}, {41, 54, 32, 63},
  3872  			{41, 55, 32, 63}, {41, 56, 32, 63}, {41, 57, 32, 63}, {41, 58, 32, 63}, {41, 59, 32, 63},
  3873  			{41, 60, 32, 63}, {41, 61, 32, 63}, {41, 62, 32, 63}, {41, 63, 32, 63}, {42, 32, 32, 63},
  3874  			{42, 33, 32, 63}, {42, 34, 32, 63}, {42, 35, 32, 63}, {42, 36, 32, 63}, {42, 37, 32, 63},
  3875  			{42, 38, 32, 63}, {42, 39, 32, 63}, {42, 40, 32, 63}, {42, 41, 32, 63}, {42, 42, 32, 63},
  3876  			{42, 43, 32, 63}, {42, 44, 32, 63}, {42, 45, 32, 63}, {42, 46, 32, 63}, {42, 47, 32, 63},
  3877  			{42, 48, 32, 63}, {42, 49, 32, 63}, {42, 50, 32, 63}, {42, 51, 32, 63}, {42, 52, 32, 63},
  3878  			{42, 53, 32, 63}, {42, 54, 32, 63}, {42, 55, 32, 63}, {42, 56, 32, 63}, {42, 57, 32, 63},
  3879  			{42, 58, 32, 63}, {42, 59, 32, 63}, {42, 60, 32, 63}, {42, 61, 32, 63}, {42, 62, 32, 63},
  3880  			{42, 63, 32, 63}, {43, 32, 32, 63}, {43, 33, 32, 63}, {43, 34, 32, 63}, {43, 35, 32, 63},
  3881  			{43, 36, 32, 63}, {43, 37, 32, 63}, {43, 38, 32, 63}, {43, 39, 32, 63}, {43, 40, 32, 63},
  3882  			{43, 41, 32, 63}, {43, 42, 32, 63}, {43, 43, 32, 63}, {43, 44, 32, 63}, {43, 45, 32, 63},
  3883  			{43, 46, 32, 63}, {43, 47, 32, 63}, {43, 48, 32, 63}, {43, 49, 32, 63}, {43, 50, 32, 63},
  3884  			{43, 51, 32, 63}, {43, 52, 32, 63}, {43, 53, 32, 63}, {43, 54, 32, 63}, {43, 55, 32, 63},
  3885  			{43, 56, 32, 63}, {43, 57, 32, 63}, {43, 58, 32, 63}, {43, 59, 32, 63}, {43, 60, 32, 63},
  3886  			{43, 61, 32, 63}, {43, 62, 32, 63}, {43, 63, 32, 63}, {44, 32, 32, 63}, {44, 33, 32, 63},
  3887  			{44, 34, 32, 63}, {44, 35, 32, 63}, {44, 36, 32, 63}, {44, 37, 32, 63}, {44, 38, 32, 63},
  3888  			{44, 39, 32, 63}, {44, 40, 32, 63}, {44, 41, 32, 63}, {44, 42, 32, 63}, {44, 43, 32, 63},
  3889  			{44, 44, 32, 63}, {44, 45, 32, 63}, {44, 46, 32, 63}, {44, 47, 32, 63}, {44, 48, 32, 63},
  3890  			{44, 49, 32, 63}, {44, 50, 32, 63}, {44, 51, 32, 63}, {44, 52, 32, 63}, {44, 53, 32, 63},
  3891  			{44, 54, 32, 63}, {44, 55, 32, 63}, {44, 56, 32, 63}, {44, 57, 32, 63}, {44, 58, 32, 63},
  3892  			{44, 59, 32, 63}, {44, 60, 32, 63}, {44, 61, 32, 63}, {44, 62, 32, 63}, {44, 63, 32, 63},
  3893  			{45, 32, 32, 63}, {45, 33, 32, 63}, {45, 34, 32, 63}, {45, 35, 32, 63}, {45, 36, 32, 63},
  3894  			{45, 37, 32, 63}, {45, 38, 32, 63}, {45, 39, 32, 63}, {45, 40, 32, 63}, {45, 41, 32, 63},
  3895  			{45, 42, 32, 63}, {45, 43, 32, 63}, {45, 44, 32, 63}, {45, 45, 32, 63}, {45, 46, 32, 63},
  3896  			{45, 47, 32, 63}, {45, 48, 32, 63}, {45, 49, 32, 63}, {45, 50, 32, 63}, {45, 51, 32, 63},
  3897  			{45, 52, 32, 63}, {45, 53, 32, 63}, {45, 54, 32, 63}, {45, 55, 32, 63}, {45, 56, 32, 63},
  3898  			{45, 57, 32, 63}, {45, 58, 32, 63}, {45, 59, 32, 63}, {45, 60, 32, 63}, {45, 61, 32, 63},
  3899  			{45, 62, 32, 63}, {45, 63, 32, 63}, {46, 32, 32, 63}, {46, 33, 32, 63}, {46, 34, 32, 63},
  3900  			{46, 35, 32, 63}, {46, 36, 32, 63}, {46, 37, 32, 63}, {46, 38, 32, 63}, {46, 39, 32, 63},
  3901  			{46, 40, 32, 63}, {46, 41, 32, 63}, {46, 42, 32, 63}, {46, 43, 32, 63}, {46, 44, 32, 63},
  3902  			{46, 45, 32, 63}, {46, 46, 32, 63}, {46, 47, 32, 63}, {46, 48, 32, 63}, {46, 49, 32, 63},
  3903  			{46, 50, 32, 63}, {46, 51, 32, 63}, {46, 52, 32, 63}, {46, 53, 32, 63}, {46, 54, 32, 63},
  3904  			{46, 55, 32, 63}, {46, 56, 32, 63}, {46, 57, 32, 63}, {46, 58, 32, 63}, {46, 59, 32, 63},
  3905  			{46, 60, 32, 63}, {46, 61, 32, 63}, {46, 62, 32, 63}, {46, 63, 32, 63}, {47, 32, 32, 63},
  3906  			{47, 33, 32, 63}, {47, 34, 32, 63}, {47, 35, 32, 63}, {47, 36, 32, 63}, {47, 37, 32, 63},
  3907  			{47, 38, 32, 63}, {47, 39, 32, 63}, {47, 40, 32, 63}, {47, 41, 32, 63}, {47, 42, 32, 63},
  3908  			{47, 43, 32, 63}, {47, 44, 32, 63}, {47, 45, 32, 63}, {47, 46, 32, 63}, {47, 47, 32, 63},
  3909  			{47, 48, 32, 63}, {47, 49, 32, 63}, {47, 50, 32, 63}, {47, 51, 32, 63}, {47, 52, 32, 63},
  3910  			{47, 53, 32, 63}, {47, 54, 32, 63}, {47, 55, 32, 63}, {47, 56, 32, 63}, {47, 57, 32, 63},
  3911  			{47, 58, 32, 63}, {47, 59, 32, 63}, {47, 60, 32, 63}, {47, 61, 32, 63}, {47, 62, 32, 63},
  3912  			{47, 63, 32, 63}, {48, 32, 32, 63}, {48, 33, 32, 63}, {48, 34, 32, 63}, {48, 35, 32, 63},
  3913  			{48, 36, 32, 63}, {48, 37, 32, 63}, {48, 38, 32, 63}, {48, 39, 32, 63}, {48, 40, 32, 63},
  3914  			{48, 41, 32, 63}, {48, 42, 32, 63}, {48, 43, 32, 63}, {48, 44, 32, 63}, {48, 45, 32, 63},
  3915  			{48, 46, 32, 63}, {48, 47, 32, 63}, {48, 48, 32, 63}, {48, 49, 32, 63}, {48, 50, 32, 63},
  3916  			{48, 51, 32, 63}, {48, 52, 32, 63}, {48, 53, 32, 63}, {48, 54, 32, 63}, {48, 55, 32, 63},
  3917  			{48, 56, 32, 63}, {48, 57, 32, 63}, {48, 58, 32, 63}, {48, 59, 32, 63}, {48, 60, 32, 63},
  3918  			{48, 61, 32, 63}, {48, 62, 32, 63}, {48, 63, 32, 63}, {49, 32, 32, 63}, {49, 33, 32, 63},
  3919  			{49, 34, 32, 63}, {49, 35, 32, 63}, {49, 36, 32, 63}, {49, 37, 32, 63}, {49, 38, 32, 63},
  3920  			{49, 39, 32, 63}, {49, 40, 32, 63}, {49, 41, 32, 63}, {49, 42, 32, 63}, {49, 43, 32, 63},
  3921  			{49, 44, 32, 63}, {49, 45, 32, 63}, {49, 46, 32, 63}, {49, 47, 32, 63}, {49, 48, 32, 63},
  3922  			{49, 49, 32, 63}, {49, 50, 32, 63}, {49, 51, 32, 63}, {49, 52, 32, 63}, {49, 53, 32, 63},
  3923  			{49, 54, 32, 63}, {49, 55, 32, 63}, {49, 56, 32, 63}, {49, 57, 32, 63}, {49, 58, 32, 63},
  3924  			{49, 59, 32, 63}, {49, 60, 32, 63}, {49, 61, 32, 63}, {49, 62, 32, 63}, {49, 63, 32, 63},
  3925  			{50, 32, 32, 63}, {50, 33, 32, 63}, {50, 34, 32, 63}, {50, 35, 32, 63}, {50, 36, 32, 63},
  3926  			{50, 37, 32, 63}, {50, 38, 32, 63}, {50, 39, 32, 63}, {50, 40, 32, 63}, {50, 41, 32, 63},
  3927  			{50, 42, 32, 63}, {50, 43, 32, 63}, {50, 44, 32, 63}, {50, 45, 32, 63}, {50, 46, 32, 63},
  3928  			{50, 47, 32, 63}, {50, 48, 32, 63}, {50, 49, 32, 63}, {50, 50, 32, 63}, {50, 51, 32, 63},
  3929  			{50, 52, 32, 63}, {50, 53, 32, 63}, {50, 54, 32, 63}, {50, 55, 32, 63}, {50, 56, 32, 63},
  3930  			{50, 57, 32, 63}, {50, 58, 32, 63}, {50, 59, 32, 63}, {50, 60, 32, 63}, {50, 61, 32, 63},
  3931  			{50, 62, 32, 63}, {50, 63, 32, 63}, {51, 32, 32, 63}, {51, 33, 32, 63}, {51, 34, 32, 63},
  3932  			{51, 35, 32, 63}, {51, 36, 32, 63}, {51, 37, 32, 63}, {51, 38, 32, 63}, {51, 39, 32, 63},
  3933  			{51, 40, 32, 63}, {51, 41, 32, 63}, {51, 42, 32, 63}, {51, 43, 32, 63}, {51, 44, 32, 63},
  3934  			{51, 45, 32, 63}, {51, 46, 32, 63}, {51, 47, 32, 63}, {51, 48, 32, 63}, {51, 49, 32, 63},
  3935  			{51, 50, 32, 63}, {51, 51, 32, 63}, {51, 52, 32, 63}, {51, 53, 32, 63}, {51, 54, 32, 63},
  3936  			{51, 55, 32, 63}, {51, 56, 32, 63}, {51, 57, 32, 63}, {51, 58, 32, 63}, {51, 59, 32, 63},
  3937  			{51, 60, 32, 63}, {51, 61, 32, 63}, {51, 62, 32, 63}, {51, 63, 32, 63}, {52, 32, 32, 63},
  3938  			{52, 33, 32, 63}, {52, 34, 32, 63}, {52, 35, 32, 63}, {52, 36, 32, 63}, {52, 37, 32, 63},
  3939  			{52, 38, 32, 63}, {52, 39, 32, 63}, {52, 40, 32, 63}, {52, 41, 32, 63}, {52, 42, 32, 63},
  3940  			{52, 43, 32, 63}, {52, 44, 32, 63}, {52, 45, 32, 63}, {52, 46, 32, 63}, {52, 47, 32, 63},
  3941  			{52, 48, 32, 63}, {52, 49, 32, 63}, {52, 50, 32, 63}, {52, 51, 32, 63}, {52, 52, 32, 63},
  3942  			{52, 53, 32, 63}, {52, 54, 32, 63}, {52, 55, 32, 63}, {52, 56, 32, 63}, {52, 57, 32, 63},
  3943  			{52, 58, 32, 63}, {52, 59, 32, 63}, {52, 60, 32, 63}, {52, 61, 32, 63}, {52, 62, 32, 63},
  3944  			{52, 63, 32, 63}, {53, 32, 32, 63}, {53, 33, 32, 63}, {53, 34, 32, 63}, {53, 35, 32, 63},
  3945  			{53, 36, 32, 63}, {53, 37, 32, 63}, {53, 38, 32, 63}, {53, 39, 32, 63}, {53, 40, 32, 63},
  3946  			{53, 41, 32, 63}, {53, 42, 32, 63}, {53, 43, 32, 63}, {53, 44, 32, 63}, {53, 45, 32, 63},
  3947  			{53, 46, 32, 63}, {53, 47, 32, 63}, {53, 48, 32, 63}, {53, 49, 32, 63}, {53, 50, 32, 63},
  3948  			{53, 51, 32, 63}, {53, 52, 32, 63}, {53, 53, 32, 63}, {53, 54, 32, 63}, {53, 55, 32, 63},
  3949  			{53, 56, 32, 63}, {53, 57, 32, 63}, {53, 58, 32, 63}, {53, 59, 32, 63}, {53, 60, 32, 63},
  3950  			{53, 61, 32, 63}, {53, 62, 32, 63}, {53, 63, 32, 63}, {54, 32, 32, 63}, {54, 33, 32, 63},
  3951  			{54, 34, 32, 63}, {54, 35, 32, 63}, {54, 36, 32, 63}, {54, 37, 32, 63}, {54, 38, 32, 63},
  3952  			{54, 39, 32, 63}, {54, 40, 32, 63}, {54, 41, 32, 63}, {54, 42, 32, 63}, {54, 43, 32, 63},
  3953  			{54, 44, 32, 63}, {54, 45, 32, 63}, {54, 46, 32, 63}, {54, 47, 32, 63}, {54, 48, 32, 63},
  3954  			{54, 49, 32, 63}, {54, 50, 32, 63}, {54, 51, 32, 63}, {54, 52, 32, 63}, {54, 53, 32, 63},
  3955  			{54, 54, 32, 63}, {54, 55, 32, 63}, {54, 56, 32, 63}, {54, 57, 32, 63}, {54, 58, 32, 63},
  3956  			{54, 59, 32, 63}, {54, 60, 32, 63}, {54, 61, 32, 63}, {54, 62, 32, 63}, {54, 63, 32, 63},
  3957  			{55, 32, 32, 63}, {55, 33, 32, 63}, {55, 34, 32, 63}, {55, 35, 32, 63}, {55, 36, 32, 63},
  3958  			{55, 37, 32, 63}, {55, 38, 32, 63}, {55, 39, 32, 63}, {55, 40, 32, 63}, {55, 41, 32, 63},
  3959  			{55, 42, 32, 63}, {55, 43, 32, 63}, {55, 44, 32, 63}, {55, 45, 32, 63}, {55, 46, 32, 63},
  3960  			{55, 47, 32, 63}, {55, 48, 32, 63}, {55, 49, 32, 63}, {55, 50, 32, 63}, {55, 51, 32, 63},
  3961  			{55, 52, 32, 63}, {55, 53, 32, 63}, {55, 54, 32, 63}, {55, 55, 32, 63}, {55, 56, 32, 63},
  3962  			{55, 57, 32, 63}, {55, 58, 32, 63}, {55, 59, 32, 63}, {55, 60, 32, 63}, {55, 61, 32, 63},
  3963  			{55, 62, 32, 63}, {55, 63, 32, 63}, {56, 32, 32, 63}, {56, 33, 32, 63}, {56, 34, 32, 63},
  3964  			{56, 35, 32, 63}, {56, 36, 32, 63}, {56, 37, 32, 63}, {56, 38, 32, 63}, {56, 39, 32, 63},
  3965  			{56, 40, 32, 63}, {56, 41, 32, 63}, {56, 42, 32, 63}, {56, 43, 32, 63}, {56, 44, 32, 63},
  3966  			{56, 45, 32, 63}, {56, 46, 32, 63}, {56, 47, 32, 63}, {56, 48, 32, 63}, {56, 49, 32, 63},
  3967  			{56, 50, 32, 63}, {56, 51, 32, 63}, {56, 52, 32, 63}, {56, 53, 32, 63}, {56, 54, 32, 63},
  3968  			{56, 55, 32, 63}, {56, 56, 32, 63}, {56, 57, 32, 63}, {56, 58, 32, 63}, {56, 59, 32, 63},
  3969  			{56, 60, 32, 63}, {56, 61, 32, 63}, {56, 62, 32, 63}, {56, 63, 32, 63}, {57, 32, 32, 63},
  3970  			{57, 33, 32, 63}, {57, 34, 32, 63}, {57, 35, 32, 63}, {57, 36, 32, 63}, {57, 37, 32, 63},
  3971  			{57, 38, 32, 63}, {57, 39, 32, 63}, {57, 40, 32, 63}, {57, 41, 32, 63}, {57, 42, 32, 63},
  3972  			{57, 43, 32, 63}, {57, 44, 32, 63}, {57, 45, 32, 63}, {57, 46, 32, 63}, {57, 47, 32, 63},
  3973  			{57, 48, 32, 63}, {57, 49, 32, 63}, {57, 50, 32, 63}, {57, 51, 32, 63}, {57, 52, 32, 63},
  3974  			{57, 53, 32, 63}, {57, 54, 32, 63}, {57, 55, 32, 63}, {57, 56, 32, 63}, {57, 57, 32, 63},
  3975  			{57, 58, 32, 63}, {57, 59, 32, 63}, {57, 60, 32, 63}, {57, 61, 32, 63}, {57, 62, 32, 63},
  3976  			{57, 63, 32, 63}, {58, 32, 32, 63}, {58, 33, 32, 63}, {58, 34, 32, 63}, {58, 35, 32, 63},
  3977  			{58, 36, 32, 63}, {58, 37, 32, 63}, {58, 38, 32, 63}, {58, 39, 32, 63}, {58, 40, 32, 63},
  3978  			{58, 41, 32, 63}, {58, 42, 32, 63}, {58, 43, 32, 63}, {58, 44, 32, 63}, {58, 45, 32, 63},
  3979  			{58, 46, 32, 63}, {58, 47, 32, 63}, {58, 48, 32, 63}, {58, 49, 32, 63}, {58, 50, 32, 63},
  3980  			{58, 51, 32, 63}, {58, 52, 32, 63}, {58, 53, 32, 63}, {58, 54, 32, 63}, {58, 55, 32, 63},
  3981  			{58, 56, 32, 63}, {58, 57, 32, 63}, {58, 58, 32, 63}, {58, 59, 32, 63}, {58, 60, 32, 63},
  3982  			{58, 61, 32, 63}, {58, 62, 32, 63}, {58, 63, 32, 63}, {59, 32, 32, 63}, {59, 33, 32, 63},
  3983  			{59, 34, 32, 63}, {59, 35, 32, 63}, {59, 36, 32, 63}, {59, 37, 32, 63}, {59, 38, 32, 63},
  3984  			{59, 39, 32, 63}, {59, 40, 32, 63}, {59, 41, 32, 63}, {59, 42, 32, 63}, {59, 43, 32, 63},
  3985  			{59, 44, 32, 63}, {59, 45, 32, 63}, {59, 46, 32, 63}, {59, 47, 32, 63}, {59, 48, 32, 63},
  3986  			{59, 49, 32, 63}, {59, 50, 32, 63}, {59, 51, 32, 63}, {59, 52, 32, 63}, {59, 53, 32, 63},
  3987  			{59, 54, 32, 63}, {59, 55, 32, 63}, {59, 56, 32, 63}, {59, 57, 32, 63}, {59, 58, 32, 63},
  3988  			{59, 59, 32, 63}, {59, 60, 32, 63}, {59, 61, 32, 63}, {59, 62, 32, 63}, {59, 63, 32, 63},
  3989  			{40, 32, 64, 79}, {40, 33, 64, 79}, {40, 34, 64, 79}, {40, 35, 64, 79}, {40, 36, 64, 79},
  3990  			{40, 37, 64, 79}, {40, 38, 64, 79}, {40, 39, 64, 79}, {40, 40, 64, 79}, {40, 41, 64, 79},
  3991  			{40, 42, 64, 79}, {40, 43, 64, 79}, {40, 44, 64, 79}, {40, 45, 64, 79}, {40, 46, 64, 79},
  3992  			{40, 47, 64, 79}, {40, 48, 64, 79}, {40, 49, 64, 79}, {40, 50, 64, 79}, {40, 51, 64, 79},
  3993  			{40, 52, 64, 79}, {40, 53, 64, 79}, {40, 54, 64, 79}, {40, 55, 64, 79}, {40, 56, 64, 79},
  3994  			{40, 57, 64, 79}, {40, 58, 64, 79}, {40, 59, 64, 79}, {40, 60, 64, 79}, {40, 61, 64, 79},
  3995  			{40, 62, 64, 79}, {40, 63, 64, 79}, {41, 32, 64, 79}, {41, 33, 64, 79}, {41, 34, 64, 79},
  3996  			{41, 35, 64, 79}, {41, 36, 64, 79}, {41, 37, 64, 79}, {41, 38, 64, 79}, {41, 39, 64, 79},
  3997  			{41, 40, 64, 79}, {41, 41, 64, 79}, {41, 42, 64, 79}, {41, 43, 64, 79}, {41, 44, 64, 79},
  3998  			{41, 45, 64, 79}, {41, 46, 64, 79}, {41, 47, 64, 79}, {41, 48, 64, 79}, {41, 49, 64, 79},
  3999  			{41, 50, 64, 79}, {41, 51, 64, 79}, {41, 52, 64, 79}, {41, 53, 64, 79}, {41, 54, 64, 79},
  4000  			{41, 55, 64, 79}, {41, 56, 64, 79}, {41, 57, 64, 79}, {41, 58, 64, 79}, {41, 59, 64, 79},
  4001  			{41, 60, 64, 79}, {41, 61, 64, 79}, {41, 62, 64, 79}, {41, 63, 64, 79}, {42, 32, 64, 79},
  4002  			{42, 33, 64, 79}, {42, 34, 64, 79}, {42, 35, 64, 79}, {42, 36, 64, 79}, {42, 37, 64, 79},
  4003  			{42, 38, 64, 79}, {42, 39, 64, 79}, {42, 40, 64, 79}, {42, 41, 64, 79}, {42, 42, 64, 79},
  4004  			{42, 43, 64, 79}, {42, 44, 64, 79}, {42, 45, 64, 79}, {42, 46, 64, 79}, {42, 47, 64, 79},
  4005  			{42, 48, 64, 79}, {42, 49, 64, 79}, {42, 50, 64, 79}, {42, 51, 64, 79}, {42, 52, 64, 79},
  4006  			{42, 53, 64, 79}, {42, 54, 64, 79}, {42, 55, 64, 79}, {42, 56, 64, 79}, {42, 57, 64, 79},
  4007  			{42, 58, 64, 79}, {42, 59, 64, 79}, {42, 60, 64, 79}, {42, 61, 64, 79}, {42, 62, 64, 79},
  4008  			{42, 63, 64, 79}, {43, 32, 64, 79}, {43, 33, 64, 79}, {43, 34, 64, 79}, {43, 35, 64, 79},
  4009  			{43, 36, 64, 79}, {43, 37, 64, 79}, {43, 38, 64, 79}, {43, 39, 64, 79}, {43, 40, 64, 79},
  4010  			{43, 41, 64, 79}, {43, 42, 64, 79}, {43, 43, 64, 79}, {43, 44, 64, 79}, {43, 45, 64, 79},
  4011  			{43, 46, 64, 79}, {43, 47, 64, 79}, {43, 48, 64, 79}, {43, 49, 64, 79}, {43, 50, 64, 79},
  4012  			{43, 51, 64, 79}, {43, 52, 64, 79}, {43, 53, 64, 79}, {43, 54, 64, 79}, {43, 55, 64, 79},
  4013  			{43, 56, 64, 79}, {43, 57, 64, 79}, {43, 58, 64, 79}, {43, 59, 64, 79}, {43, 60, 64, 79},
  4014  			{43, 61, 64, 79}, {43, 62, 64, 79}, {43, 63, 64, 79}, {44, 32, 64, 79}, {44, 33, 64, 79},
  4015  			{44, 34, 64, 79}, {44, 35, 64, 79}, {44, 36, 64, 79}, {44, 37, 64, 79}, {44, 38, 64, 79},
  4016  			{44, 39, 64, 79}, {44, 40, 64, 79}, {44, 41, 64, 79}, {44, 42, 64, 79}, {44, 43, 64, 79},
  4017  			{44, 44, 64, 79}, {44, 45, 64, 79}, {44, 46, 64, 79}, {44, 47, 64, 79}, {44, 48, 64, 79},
  4018  			{44, 49, 64, 79}, {44, 50, 64, 79}, {44, 51, 64, 79}, {44, 52, 64, 79}, {44, 53, 64, 79},
  4019  			{44, 54, 64, 79}, {44, 55, 64, 79}, {44, 56, 64, 79}, {44, 57, 64, 79}, {44, 58, 64, 79},
  4020  			{44, 59, 64, 79}, {44, 60, 64, 79}, {44, 61, 64, 79}, {44, 62, 64, 79}, {44, 63, 64, 79},
  4021  			{45, 32, 64, 79}, {45, 33, 64, 79}, {45, 34, 64, 79}, {45, 35, 64, 79}, {45, 36, 64, 79},
  4022  			{45, 37, 64, 79}, {45, 38, 64, 79}, {45, 39, 64, 79}, {45, 40, 64, 79}, {45, 41, 64, 79},
  4023  			{45, 42, 64, 79}, {45, 43, 64, 79}, {45, 44, 64, 79}, {45, 45, 64, 79}, {45, 46, 64, 79},
  4024  			{45, 47, 64, 79}, {45, 48, 64, 79}, {45, 49, 64, 79}, {45, 50, 64, 79}, {45, 51, 64, 79},
  4025  			{45, 52, 64, 79}, {45, 53, 64, 79}, {45, 54, 64, 79}, {45, 55, 64, 79}, {45, 56, 64, 79},
  4026  			{45, 57, 64, 79}, {45, 58, 64, 79}, {45, 59, 64, 79}, {45, 60, 64, 79}, {45, 61, 64, 79},
  4027  			{45, 62, 64, 79}, {45, 63, 64, 79}, {46, 32, 64, 79}, {46, 33, 64, 79}, {46, 34, 64, 79},
  4028  			{46, 35, 64, 79}, {46, 36, 64, 79}, {46, 37, 64, 79}, {46, 38, 64, 79}, {46, 39, 64, 79},
  4029  			{46, 40, 64, 79}, {46, 41, 64, 79}, {46, 42, 64, 79}, {46, 43, 64, 79}, {46, 44, 64, 79},
  4030  			{46, 45, 64, 79}, {46, 46, 64, 79}, {46, 47, 64, 79}, {46, 48, 64, 79}, {46, 49, 64, 79},
  4031  			{46, 50, 64, 79}, {46, 51, 64, 79}, {46, 52, 64, 79}, {46, 53, 64, 79}, {46, 54, 64, 79},
  4032  			{46, 55, 64, 79}, {46, 56, 64, 79}, {46, 57, 64, 79}, {46, 58, 64, 79}, {46, 59, 64, 79},
  4033  			{46, 60, 64, 79}, {46, 61, 64, 79}, {46, 62, 64, 79}, {46, 63, 64, 79}, {47, 32, 64, 79},
  4034  			{47, 33, 64, 79}, {47, 34, 64, 79}, {47, 35, 64, 79}, {47, 36, 64, 79}, {47, 37, 64, 79},
  4035  			{47, 38, 64, 79}, {47, 39, 64, 79}, {47, 40, 64, 79}, {47, 41, 64, 79}, {47, 42, 64, 79},
  4036  			{47, 43, 64, 79}, {47, 44, 64, 79}, {47, 45, 64, 79}, {47, 46, 64, 79}, {47, 47, 64, 79},
  4037  			{47, 48, 64, 79}, {47, 49, 64, 79}, {47, 50, 64, 79}, {47, 51, 64, 79}, {47, 52, 64, 79},
  4038  			{47, 53, 64, 79}, {47, 54, 64, 79}, {47, 55, 64, 79}, {47, 56, 64, 79}, {47, 57, 64, 79},
  4039  			{47, 58, 64, 79}, {47, 59, 64, 79}, {47, 60, 64, 79}, {47, 61, 64, 79}, {47, 62, 64, 79},
  4040  			{47, 63, 64, 79}, {48, 32, 64, 79}, {48, 33, 64, 79}, {48, 34, 64, 79}, {48, 35, 64, 79},
  4041  			{48, 36, 64, 79}, {48, 37, 64, 79}, {48, 38, 64, 79}, {48, 39, 64, 79}, {48, 40, 64, 79},
  4042  			{48, 41, 64, 79}, {48, 42, 64, 79}, {48, 43, 64, 79}, {48, 44, 64, 79}, {48, 45, 64, 79},
  4043  			{48, 46, 64, 79}, {48, 47, 64, 79}, {48, 48, 64, 79}, {48, 49, 64, 79}, {48, 50, 64, 79},
  4044  			{48, 51, 64, 79}, {48, 52, 64, 79}, {48, 53, 64, 79}, {48, 54, 64, 79}, {48, 55, 64, 79},
  4045  			{48, 56, 64, 79}, {48, 57, 64, 79}, {48, 58, 64, 79}, {48, 59, 64, 79}, {48, 60, 64, 79},
  4046  			{48, 61, 64, 79}, {48, 62, 64, 79}, {48, 63, 64, 79}, {49, 32, 64, 79}, {49, 33, 64, 79},
  4047  			{49, 34, 64, 79}, {49, 35, 64, 79}, {49, 36, 64, 79}, {49, 37, 64, 79}, {49, 38, 64, 79},
  4048  			{49, 39, 64, 79}, {49, 40, 64, 79}, {49, 41, 64, 79}, {49, 42, 64, 79}, {49, 43, 64, 79},
  4049  			{49, 44, 64, 79}, {49, 45, 64, 79}, {49, 46, 64, 79}, {49, 47, 64, 79}, {49, 48, 64, 79},
  4050  			{49, 49, 64, 79}, {49, 50, 64, 79}, {49, 51, 64, 79}, {49, 52, 64, 79}, {49, 53, 64, 79},
  4051  			{49, 54, 64, 79}, {49, 55, 64, 79}, {49, 56, 64, 79}, {49, 57, 64, 79}, {49, 58, 64, 79},
  4052  			{49, 59, 64, 79}, {49, 60, 64, 79}, {49, 61, 64, 79}, {49, 62, 64, 79}, {49, 63, 64, 79},
  4053  			{50, 32, 64, 79}, {50, 33, 64, 79}, {50, 34, 64, 79}, {50, 35, 64, 79}, {50, 36, 64, 79},
  4054  			{50, 37, 64, 79}, {50, 38, 64, 79}, {50, 39, 64, 79}, {50, 40, 64, 79}, {50, 41, 64, 79},
  4055  			{50, 42, 64, 79}, {50, 43, 64, 79}, {50, 44, 64, 79}, {50, 45, 64, 79}, {50, 46, 64, 79},
  4056  			{50, 47, 64, 79}, {50, 48, 64, 79}, {50, 49, 64, 79}, {50, 50, 64, 79}, {50, 51, 64, 79},
  4057  			{50, 52, 64, 79}, {50, 53, 64, 79}, {50, 54, 64, 79}, {50, 55, 64, 79}, {50, 56, 64, 79},
  4058  			{50, 57, 64, 79}, {50, 58, 64, 79}, {50, 59, 64, 79}, {50, 60, 64, 79}, {50, 61, 64, 79},
  4059  			{50, 62, 64, 79}, {50, 63, 64, 79}, {51, 32, 64, 79}, {51, 33, 64, 79}, {51, 34, 64, 79},
  4060  			{51, 35, 64, 79}, {51, 36, 64, 79}, {51, 37, 64, 79}, {51, 38, 64, 79}, {51, 39, 64, 79},
  4061  			{51, 40, 64, 79}, {51, 41, 64, 79}, {51, 42, 64, 79}, {51, 43, 64, 79}, {51, 44, 64, 79},
  4062  			{51, 45, 64, 79}, {51, 46, 64, 79}, {51, 47, 64, 79}, {51, 48, 64, 79}, {51, 49, 64, 79},
  4063  			{51, 50, 64, 79}, {51, 51, 64, 79}, {51, 52, 64, 79}, {51, 53, 64, 79}, {51, 54, 64, 79},
  4064  			{51, 55, 64, 79}, {51, 56, 64, 79}, {51, 57, 64, 79}, {51, 58, 64, 79}, {51, 59, 64, 79},
  4065  			{51, 60, 64, 79}, {51, 61, 64, 79}, {51, 62, 64, 79}, {51, 63, 64, 79}, {52, 32, 64, 79},
  4066  			{52, 33, 64, 79}, {52, 34, 64, 79}, {52, 35, 64, 79}, {52, 36, 64, 79}, {52, 37, 64, 79},
  4067  			{52, 38, 64, 79}, {52, 39, 64, 79}, {52, 40, 64, 79}, {52, 41, 64, 79}, {52, 42, 64, 79},
  4068  			{52, 43, 64, 79}, {52, 44, 64, 79}, {52, 45, 64, 79}, {52, 46, 64, 79}, {52, 47, 64, 79},
  4069  			{52, 48, 64, 79}, {52, 49, 64, 79}, {52, 50, 64, 79}, {52, 51, 64, 79}, {52, 52, 64, 79},
  4070  			{52, 53, 64, 79}, {52, 54, 64, 79}, {52, 55, 64, 79}, {52, 56, 64, 79}, {52, 57, 64, 79},
  4071  			{52, 58, 64, 79}, {52, 59, 64, 79}, {52, 60, 64, 79}, {52, 61, 64, 79}, {52, 62, 64, 79},
  4072  			{52, 63, 64, 79}, {53, 32, 64, 79}, {53, 33, 64, 79}, {53, 34, 64, 79}, {53, 35, 64, 79},
  4073  			{53, 36, 64, 79}, {53, 37, 64, 79}, {53, 38, 64, 79}, {53, 39, 64, 79}, {53, 40, 64, 79},
  4074  			{53, 41, 64, 79}, {53, 42, 64, 79}, {53, 43, 64, 79}, {53, 44, 64, 79}, {53, 45, 64, 79},
  4075  			{53, 46, 64, 79}, {53, 47, 64, 79}, {53, 48, 64, 79}, {53, 49, 64, 79}, {53, 50, 64, 79},
  4076  			{53, 51, 64, 79}, {53, 52, 64, 79}, {53, 53, 64, 79}, {53, 54, 64, 79}, {53, 55, 64, 79},
  4077  			{53, 56, 64, 79}, {53, 57, 64, 79}, {53, 58, 64, 79}, {53, 59, 64, 79}, {53, 60, 64, 79},
  4078  			{53, 61, 64, 79}, {53, 62, 64, 79}, {53, 63, 64, 79}, {54, 32, 64, 79}, {54, 33, 64, 79},
  4079  			{54, 34, 64, 79}, {54, 35, 64, 79}, {54, 36, 64, 79}, {54, 37, 64, 79}, {54, 38, 64, 79},
  4080  			{54, 39, 64, 79}, {54, 40, 64, 79}, {54, 41, 64, 79}, {54, 42, 64, 79}, {54, 43, 64, 79},
  4081  			{54, 44, 64, 79}, {54, 45, 64, 79}, {54, 46, 64, 79}, {54, 47, 64, 79}, {54, 48, 64, 79},
  4082  			{54, 49, 64, 79}, {54, 50, 64, 79}, {54, 51, 64, 79}, {54, 52, 64, 79}, {54, 53, 64, 79},
  4083  			{54, 54, 64, 79}, {54, 55, 64, 79}, {54, 56, 64, 79}, {54, 57, 64, 79}, {54, 58, 64, 79},
  4084  			{54, 59, 64, 79}, {54, 60, 64, 79}, {54, 61, 64, 79}, {54, 62, 64, 79}, {54, 63, 64, 79},
  4085  			{55, 32, 64, 79}, {55, 33, 64, 79}, {55, 34, 64, 79}, {55, 35, 64, 79}, {55, 36, 64, 79},
  4086  			{55, 37, 64, 79}, {55, 38, 64, 79}, {55, 39, 64, 79}, {55, 40, 64, 79}, {55, 41, 64, 79},
  4087  			{55, 42, 64, 79}, {55, 43, 64, 79}, {55, 44, 64, 79}, {55, 45, 64, 79}, {55, 46, 64, 79},
  4088  			{55, 47, 64, 79}, {55, 48, 64, 79}, {55, 49, 64, 79}, {55, 50, 64, 79}, {55, 51, 64, 79},
  4089  			{55, 52, 64, 79}, {55, 53, 64, 79}, {55, 54, 64, 79}, {55, 55, 64, 79}, {55, 56, 64, 79},
  4090  			{55, 57, 64, 79}, {55, 58, 64, 79}, {55, 59, 64, 79}, {55, 60, 64, 79}, {55, 61, 64, 79},
  4091  			{55, 62, 64, 79}, {55, 63, 64, 79}, {56, 32, 64, 79}, {56, 33, 64, 79}, {56, 34, 64, 79},
  4092  			{56, 35, 64, 79}, {56, 36, 64, 79}, {56, 37, 64, 79}, {56, 38, 64, 79}, {56, 39, 64, 79},
  4093  			{56, 40, 64, 79}, {56, 41, 64, 79}, {56, 42, 64, 79}, {56, 43, 64, 79}, {56, 44, 64, 79},
  4094  			{56, 45, 64, 79}, {56, 46, 64, 79}, {56, 47, 64, 79}, {56, 48, 64, 79}, {56, 49, 64, 79},
  4095  			{56, 50, 64, 79}, {56, 51, 64, 79}, {56, 52, 64, 79}, {56, 53, 64, 79}, {56, 54, 64, 79},
  4096  			{56, 55, 64, 79}, {56, 56, 64, 79}, {56, 57, 64, 79}, {56, 58, 64, 79}, {56, 59, 64, 79},
  4097  			{56, 60, 64, 79}, {56, 61, 64, 79}, {56, 62, 64, 79}, {56, 63, 64, 79}, {57, 32, 64, 79},
  4098  			{57, 33, 64, 79}, {57, 34, 64, 79}, {57, 35, 64, 79}, {57, 36, 64, 79}, {57, 37, 64, 79},
  4099  			{57, 38, 64, 79}, {57, 39, 64, 79}, {57, 40, 64, 79}, {57, 41, 64, 79}, {57, 42, 64, 79},
  4100  			{57, 43, 64, 79}, {57, 44, 64, 79}, {57, 45, 64, 79}, {57, 46, 64, 79}, {57, 47, 64, 79},
  4101  			{57, 48, 64, 79}, {57, 49, 64, 79}, {57, 50, 64, 79}, {57, 51, 64, 79}, {57, 52, 64, 79},
  4102  			{57, 53, 64, 79}, {57, 54, 64, 79}, {57, 55, 64, 79}, {57, 56, 64, 79}, {57, 57, 64, 79},
  4103  			{57, 58, 64, 79}, {57, 59, 64, 79}, {57, 60, 64, 79}, {57, 61, 64, 79}, {57, 62, 64, 79},
  4104  			{57, 63, 64, 79}, {58, 32, 64, 79}, {58, 33, 64, 79}, {58, 34, 64, 79}, {58, 35, 64, 79},
  4105  			{58, 36, 64, 79}, {58, 37, 64, 79}, {58, 38, 64, 79}, {58, 39, 64, 79}, {58, 40, 64, 79},
  4106  			{58, 41, 64, 79}, {58, 42, 64, 79}, {58, 43, 64, 79}, {58, 44, 64, 79}, {58, 45, 64, 79},
  4107  			{58, 46, 64, 79}, {58, 47, 64, 79}, {58, 48, 64, 79}, {58, 49, 64, 79}, {58, 50, 64, 79},
  4108  			{58, 51, 64, 79}, {58, 52, 64, 79}, {58, 53, 64, 79}, {58, 54, 64, 79}, {58, 55, 64, 79},
  4109  			{58, 56, 64, 79}, {58, 57, 64, 79}, {58, 58, 64, 79}, {58, 59, 64, 79}, {58, 60, 64, 79},
  4110  			{58, 61, 64, 79}, {58, 62, 64, 79}, {58, 63, 64, 79}, {59, 32, 64, 79}, {59, 33, 64, 79},
  4111  			{59, 34, 64, 79}, {59, 35, 64, 79}, {59, 36, 64, 79}, {59, 37, 64, 79}, {59, 38, 64, 79},
  4112  			{59, 39, 64, 79}, {59, 40, 64, 79}, {59, 41, 64, 79}, {59, 42, 64, 79}, {59, 43, 64, 79},
  4113  			{59, 44, 64, 79}, {59, 45, 64, 79}, {59, 46, 64, 79}, {59, 47, 64, 79}, {59, 48, 64, 79},
  4114  			{59, 49, 64, 79}, {59, 50, 64, 79}, {59, 51, 64, 79}, {59, 52, 64, 79}, {59, 53, 64, 79},
  4115  			{59, 54, 64, 79}, {59, 55, 64, 79}, {59, 56, 64, 79}, {59, 57, 64, 79}, {59, 58, 64, 79},
  4116  			{59, 59, 64, 79}, {59, 60, 64, 79}, {59, 61, 64, 79}, {59, 62, 64, 79}, {59, 63, 64, 79},
  4117  			{40, 64, 30, 31}, {40, 65, 30, 31}, {40, 66, 30, 31}, {40, 67, 30, 31}, {40, 68, 30, 31},
  4118  			{40, 69, 30, 31}, {41, 64, 30, 31}, {41, 65, 30, 31}, {41, 66, 30, 31}, {41, 67, 30, 31},
  4119  			{41, 68, 30, 31}, {41, 69, 30, 31}, {42, 64, 30, 31}, {42, 65, 30, 31}, {42, 66, 30, 31},
  4120  			{42, 67, 30, 31}, {42, 68, 30, 31}, {42, 69, 30, 31}, {43, 64, 30, 31}, {43, 65, 30, 31},
  4121  			{43, 66, 30, 31}, {43, 67, 30, 31}, {43, 68, 30, 31}, {43, 69, 30, 31}, {44, 64, 30, 31},
  4122  			{44, 65, 30, 31}, {44, 66, 30, 31}, {44, 67, 30, 31}, {44, 68, 30, 31}, {44, 69, 30, 31},
  4123  			{45, 64, 30, 31}, {45, 65, 30, 31}, {45, 66, 30, 31}, {45, 67, 30, 31}, {45, 68, 30, 31},
  4124  			{45, 69, 30, 31}, {46, 64, 30, 31}, {46, 65, 30, 31}, {46, 66, 30, 31}, {46, 67, 30, 31},
  4125  			{46, 68, 30, 31}, {46, 69, 30, 31}, {47, 64, 30, 31}, {47, 65, 30, 31}, {47, 66, 30, 31},
  4126  			{47, 67, 30, 31}, {47, 68, 30, 31}, {47, 69, 30, 31}, {48, 64, 30, 31}, {48, 65, 30, 31},
  4127  			{48, 66, 30, 31}, {48, 67, 30, 31}, {48, 68, 30, 31}, {48, 69, 30, 31}, {49, 64, 30, 31},
  4128  			{49, 65, 30, 31}, {49, 66, 30, 31}, {49, 67, 30, 31}, {49, 68, 30, 31}, {49, 69, 30, 31},
  4129  			{50, 64, 30, 31}, {50, 65, 30, 31}, {50, 66, 30, 31}, {50, 67, 30, 31}, {50, 68, 30, 31},
  4130  			{50, 69, 30, 31}, {51, 64, 30, 31}, {51, 65, 30, 31}, {51, 66, 30, 31}, {51, 67, 30, 31},
  4131  			{51, 68, 30, 31}, {51, 69, 30, 31}, {52, 64, 30, 31}, {52, 65, 30, 31}, {52, 66, 30, 31},
  4132  			{52, 67, 30, 31}, {52, 68, 30, 31}, {52, 69, 30, 31}, {53, 64, 30, 31}, {53, 65, 30, 31},
  4133  			{53, 66, 30, 31}, {53, 67, 30, 31}, {53, 68, 30, 31}, {53, 69, 30, 31}, {54, 64, 30, 31},
  4134  			{54, 65, 30, 31}, {54, 66, 30, 31}, {54, 67, 30, 31}, {54, 68, 30, 31}, {54, 69, 30, 31},
  4135  			{55, 64, 30, 31}, {55, 65, 30, 31}, {55, 66, 30, 31}, {55, 67, 30, 31}, {55, 68, 30, 31},
  4136  			{55, 69, 30, 31}, {56, 64, 30, 31}, {56, 65, 30, 31}, {56, 66, 30, 31}, {56, 67, 30, 31},
  4137  			{56, 68, 30, 31}, {56, 69, 30, 31}, {57, 64, 30, 31}, {57, 65, 30, 31}, {57, 66, 30, 31},
  4138  			{57, 67, 30, 31}, {57, 68, 30, 31}, {57, 69, 30, 31}, {58, 64, 30, 31}, {58, 65, 30, 31},
  4139  			{58, 66, 30, 31}, {58, 67, 30, 31}, {58, 68, 30, 31}, {58, 69, 30, 31}, {59, 64, 30, 31},
  4140  			{59, 65, 30, 31}, {59, 66, 30, 31}, {59, 67, 30, 31}, {59, 68, 30, 31}, {59, 69, 30, 31},
  4141  			{40, 64, 32, 63}, {40, 65, 32, 63}, {40, 66, 32, 63}, {40, 67, 32, 63}, {40, 68, 32, 63},
  4142  			{40, 69, 32, 63}, {41, 64, 32, 63}, {41, 65, 32, 63}, {41, 66, 32, 63}, {41, 67, 32, 63},
  4143  			{41, 68, 32, 63}, {41, 69, 32, 63}, {42, 64, 32, 63}, {42, 65, 32, 63}, {42, 66, 32, 63},
  4144  			{42, 67, 32, 63}, {42, 68, 32, 63}, {42, 69, 32, 63}, {43, 64, 32, 63}, {43, 65, 32, 63},
  4145  			{43, 66, 32, 63}, {43, 67, 32, 63}, {43, 68, 32, 63}, {43, 69, 32, 63}, {44, 64, 32, 63},
  4146  			{44, 65, 32, 63}, {44, 66, 32, 63}, {44, 67, 32, 63}, {44, 68, 32, 63}, {44, 69, 32, 63},
  4147  			{45, 64, 32, 63}, {45, 65, 32, 63}, {45, 66, 32, 63}, {45, 67, 32, 63}, {45, 68, 32, 63},
  4148  			{45, 69, 32, 63}, {46, 64, 32, 63}, {46, 65, 32, 63}, {46, 66, 32, 63}, {46, 67, 32, 63},
  4149  			{46, 68, 32, 63}, {46, 69, 32, 63}, {47, 64, 32, 63}, {47, 65, 32, 63}, {47, 66, 32, 63},
  4150  			{47, 67, 32, 63}, {47, 68, 32, 63}, {47, 69, 32, 63}, {48, 64, 32, 63}, {48, 65, 32, 63},
  4151  			{48, 66, 32, 63}, {48, 67, 32, 63}, {48, 68, 32, 63}, {48, 69, 32, 63}, {49, 64, 32, 63},
  4152  			{49, 65, 32, 63}, {49, 66, 32, 63}, {49, 67, 32, 63}, {49, 68, 32, 63}, {49, 69, 32, 63},
  4153  			{50, 64, 32, 63}, {50, 65, 32, 63}, {50, 66, 32, 63}, {50, 67, 32, 63}, {50, 68, 32, 63},
  4154  			{50, 69, 32, 63}, {51, 64, 32, 63}, {51, 65, 32, 63}, {51, 66, 32, 63}, {51, 67, 32, 63},
  4155  			{51, 68, 32, 63}, {51, 69, 32, 63}, {52, 64, 32, 63}, {52, 65, 32, 63}, {52, 66, 32, 63},
  4156  			{52, 67, 32, 63}, {52, 68, 32, 63}, {52, 69, 32, 63}, {53, 64, 32, 63}, {53, 65, 32, 63},
  4157  			{53, 66, 32, 63}, {53, 67, 32, 63}, {53, 68, 32, 63}, {53, 69, 32, 63}, {54, 64, 32, 63},
  4158  			{54, 65, 32, 63}, {54, 66, 32, 63}, {54, 67, 32, 63}, {54, 68, 32, 63}, {54, 69, 32, 63},
  4159  			{55, 64, 32, 63}, {55, 65, 32, 63}, {55, 66, 32, 63}, {55, 67, 32, 63}, {55, 68, 32, 63},
  4160  			{55, 69, 32, 63}, {56, 64, 32, 63}, {56, 65, 32, 63}, {56, 66, 32, 63}, {56, 67, 32, 63},
  4161  			{56, 68, 32, 63}, {56, 69, 32, 63}, {57, 64, 32, 63}, {57, 65, 32, 63}, {57, 66, 32, 63},
  4162  			{57, 67, 32, 63}, {57, 68, 32, 63}, {57, 69, 32, 63}, {58, 64, 32, 63}, {58, 65, 32, 63},
  4163  			{58, 66, 32, 63}, {58, 67, 32, 63}, {58, 68, 32, 63}, {58, 69, 32, 63}, {59, 64, 32, 63},
  4164  			{59, 65, 32, 63}, {59, 66, 32, 63}, {59, 67, 32, 63}, {59, 68, 32, 63}, {59, 69, 32, 63},
  4165  			{40, 64, 64, 79}, {40, 65, 64, 79}, {40, 66, 64, 79}, {40, 67, 64, 79}, {40, 68, 64, 79},
  4166  			{40, 69, 64, 79}, {41, 64, 64, 79}, {41, 65, 64, 79}, {41, 66, 64, 79}, {41, 67, 64, 79},
  4167  			{41, 68, 64, 79}, {41, 69, 64, 79}, {42, 64, 64, 79}, {42, 65, 64, 79}, {42, 66, 64, 79},
  4168  			{42, 67, 64, 79}, {42, 68, 64, 79}, {42, 69, 64, 79}, {43, 64, 64, 79}, {43, 65, 64, 79},
  4169  			{43, 66, 64, 79}, {43, 67, 64, 79}, {43, 68, 64, 79}, {43, 69, 64, 79}, {44, 64, 64, 79},
  4170  			{44, 65, 64, 79}, {44, 66, 64, 79}, {44, 67, 64, 79}, {44, 68, 64, 79}, {44, 69, 64, 79},
  4171  			{45, 64, 64, 79}, {45, 65, 64, 79}, {45, 66, 64, 79}, {45, 67, 64, 79}, {45, 68, 64, 79},
  4172  			{45, 69, 64, 79}, {46, 64, 64, 79}, {46, 65, 64, 79}, {46, 66, 64, 79}, {46, 67, 64, 79},
  4173  			{46, 68, 64, 79}, {46, 69, 64, 79}, {47, 64, 64, 79}, {47, 65, 64, 79}, {47, 66, 64, 79},
  4174  			{47, 67, 64, 79}, {47, 68, 64, 79}, {47, 69, 64, 79}, {48, 64, 64, 79}, {48, 65, 64, 79},
  4175  			{48, 66, 64, 79}, {48, 67, 64, 79}, {48, 68, 64, 79}, {48, 69, 64, 79}, {49, 64, 64, 79},
  4176  			{49, 65, 64, 79}, {49, 66, 64, 79}, {49, 67, 64, 79}, {49, 68, 64, 79}, {49, 69, 64, 79},
  4177  			{50, 64, 64, 79}, {50, 65, 64, 79}, {50, 66, 64, 79}, {50, 67, 64, 79}, {50, 68, 64, 79},
  4178  			{50, 69, 64, 79}, {51, 64, 64, 79}, {51, 65, 64, 79}, {51, 66, 64, 79}, {51, 67, 64, 79},
  4179  			{51, 68, 64, 79}, {51, 69, 64, 79}, {52, 64, 64, 79}, {52, 65, 64, 79}, {52, 66, 64, 79},
  4180  			{52, 67, 64, 79}, {52, 68, 64, 79}, {52, 69, 64, 79}, {53, 64, 64, 79}, {53, 65, 64, 79},
  4181  			{53, 66, 64, 79}, {53, 67, 64, 79}, {53, 68, 64, 79}, {53, 69, 64, 79}, {54, 64, 64, 79},
  4182  			{54, 65, 64, 79}, {54, 66, 64, 79}, {54, 67, 64, 79}, {54, 68, 64, 79}, {54, 69, 64, 79},
  4183  			{55, 64, 64, 79}, {55, 65, 64, 79}, {55, 66, 64, 79}, {55, 67, 64, 79}, {55, 68, 64, 79},
  4184  			{55, 69, 64, 79}, {56, 64, 64, 79}, {56, 65, 64, 79}, {56, 66, 64, 79}, {56, 67, 64, 79},
  4185  			{56, 68, 64, 79}, {56, 69, 64, 79}, {57, 64, 64, 79}, {57, 65, 64, 79}, {57, 66, 64, 79},
  4186  			{57, 67, 64, 79}, {57, 68, 64, 79}, {57, 69, 64, 79}, {58, 64, 64, 79}, {58, 65, 64, 79},
  4187  			{58, 66, 64, 79}, {58, 67, 64, 79}, {58, 68, 64, 79}, {58, 69, 64, 79}, {59, 64, 64, 79},
  4188  			{59, 65, 64, 79}, {59, 66, 64, 79}, {59, 67, 64, 79}, {59, 68, 64, 79}, {59, 69, 64, 79},
  4189  		},
  4190  	}
  4191  	body3 = testBody{
  4192  		label:  3,
  4193  		offset: dvid.Point3d{40, 40, 10},
  4194  		size:   dvid.Point3d{20, 20, 30},
  4195  		blockSpans: []dvid.Span{
  4196  			{0, 1, 1, 1},
  4197  			{1, 1, 1, 1},
  4198  		},
  4199  		voxelSpans: []dvid.Span{
  4200  			{10, 40, 40, 59}, {10, 41, 40, 59}, {10, 42, 40, 59}, {10, 43, 40, 59}, {10, 44, 40, 59},
  4201  			{10, 45, 40, 59}, {10, 46, 40, 59}, {10, 47, 40, 59}, {10, 48, 40, 59}, {10, 49, 40, 59},
  4202  			{10, 50, 40, 59}, {10, 51, 40, 59}, {10, 52, 40, 59}, {10, 53, 40, 59}, {10, 54, 40, 59},
  4203  			{10, 55, 40, 59}, {10, 56, 40, 59}, {10, 57, 40, 59}, {10, 58, 40, 59}, {10, 59, 40, 59},
  4204  			{11, 40, 40, 59}, {11, 41, 40, 59}, {11, 42, 40, 59}, {11, 43, 40, 59}, {11, 44, 40, 59},
  4205  			{11, 45, 40, 59}, {11, 46, 40, 59}, {11, 47, 40, 59}, {11, 48, 40, 59}, {11, 49, 40, 59},
  4206  			{11, 50, 40, 59}, {11, 51, 40, 59}, {11, 52, 40, 59}, {11, 53, 40, 59}, {11, 54, 40, 59},
  4207  			{11, 55, 40, 59}, {11, 56, 40, 59}, {11, 57, 40, 59}, {11, 58, 40, 59}, {11, 59, 40, 59},
  4208  			{12, 40, 40, 59}, {12, 41, 40, 59}, {12, 42, 40, 59}, {12, 43, 40, 59}, {12, 44, 40, 59},
  4209  			{12, 45, 40, 59}, {12, 46, 40, 59}, {12, 47, 40, 59}, {12, 48, 40, 59}, {12, 49, 40, 59},
  4210  			{12, 50, 40, 59}, {12, 51, 40, 59}, {12, 52, 40, 59}, {12, 53, 40, 59}, {12, 54, 40, 59},
  4211  			{12, 55, 40, 59}, {12, 56, 40, 59}, {12, 57, 40, 59}, {12, 58, 40, 59}, {12, 59, 40, 59},
  4212  			{13, 40, 40, 59}, {13, 41, 40, 59}, {13, 42, 40, 59}, {13, 43, 40, 59}, {13, 44, 40, 59},
  4213  			{13, 45, 40, 59}, {13, 46, 40, 59}, {13, 47, 40, 59}, {13, 48, 40, 59}, {13, 49, 40, 59},
  4214  			{13, 50, 40, 59}, {13, 51, 40, 59}, {13, 52, 40, 59}, {13, 53, 40, 59}, {13, 54, 40, 59},
  4215  			{13, 55, 40, 59}, {13, 56, 40, 59}, {13, 57, 40, 59}, {13, 58, 40, 59}, {13, 59, 40, 59},
  4216  			{14, 40, 40, 59}, {14, 41, 40, 59}, {14, 42, 40, 59}, {14, 43, 40, 59}, {14, 44, 40, 59},
  4217  			{14, 45, 40, 59}, {14, 46, 40, 59}, {14, 47, 40, 59}, {14, 48, 40, 59}, {14, 49, 40, 59},
  4218  			{14, 50, 40, 59}, {14, 51, 40, 59}, {14, 52, 40, 59}, {14, 53, 40, 59}, {14, 54, 40, 59},
  4219  			{14, 55, 40, 59}, {14, 56, 40, 59}, {14, 57, 40, 59}, {14, 58, 40, 59}, {14, 59, 40, 59},
  4220  			{15, 40, 40, 59}, {15, 41, 40, 59}, {15, 42, 40, 59}, {15, 43, 40, 59}, {15, 44, 40, 59},
  4221  			{15, 45, 40, 59}, {15, 46, 40, 59}, {15, 47, 40, 59}, {15, 48, 40, 59}, {15, 49, 40, 59},
  4222  			{15, 50, 40, 59}, {15, 51, 40, 59}, {15, 52, 40, 59}, {15, 53, 40, 59}, {15, 54, 40, 59},
  4223  			{15, 55, 40, 59}, {15, 56, 40, 59}, {15, 57, 40, 59}, {15, 58, 40, 59}, {15, 59, 40, 59},
  4224  			{16, 40, 40, 59}, {16, 41, 40, 59}, {16, 42, 40, 59}, {16, 43, 40, 59}, {16, 44, 40, 59},
  4225  			{16, 45, 40, 59}, {16, 46, 40, 59}, {16, 47, 40, 59}, {16, 48, 40, 59}, {16, 49, 40, 59},
  4226  			{16, 50, 40, 59}, {16, 51, 40, 59}, {16, 52, 40, 59}, {16, 53, 40, 59}, {16, 54, 40, 59},
  4227  			{16, 55, 40, 59}, {16, 56, 40, 59}, {16, 57, 40, 59}, {16, 58, 40, 59}, {16, 59, 40, 59},
  4228  			{17, 40, 40, 59}, {17, 41, 40, 59}, {17, 42, 40, 59}, {17, 43, 40, 59}, {17, 44, 40, 59},
  4229  			{17, 45, 40, 59}, {17, 46, 40, 59}, {17, 47, 40, 59}, {17, 48, 40, 59}, {17, 49, 40, 59},
  4230  			{17, 50, 40, 59}, {17, 51, 40, 59}, {17, 52, 40, 59}, {17, 53, 40, 59}, {17, 54, 40, 59},
  4231  			{17, 55, 40, 59}, {17, 56, 40, 59}, {17, 57, 40, 59}, {17, 58, 40, 59}, {17, 59, 40, 59},
  4232  			{18, 40, 40, 59}, {18, 41, 40, 59}, {18, 42, 40, 59}, {18, 43, 40, 59}, {18, 44, 40, 59},
  4233  			{18, 45, 40, 59}, {18, 46, 40, 59}, {18, 47, 40, 59}, {18, 48, 40, 59}, {18, 49, 40, 59},
  4234  			{18, 50, 40, 59}, {18, 51, 40, 59}, {18, 52, 40, 59}, {18, 53, 40, 59}, {18, 54, 40, 59},
  4235  			{18, 55, 40, 59}, {18, 56, 40, 59}, {18, 57, 40, 59}, {18, 58, 40, 59}, {18, 59, 40, 59},
  4236  			{19, 40, 40, 59}, {19, 41, 40, 59}, {19, 42, 40, 59}, {19, 43, 40, 59}, {19, 44, 40, 59},
  4237  			{19, 45, 40, 59}, {19, 46, 40, 59}, {19, 47, 40, 59}, {19, 48, 40, 59}, {19, 49, 40, 59},
  4238  			{19, 50, 40, 59}, {19, 51, 40, 59}, {19, 52, 40, 59}, {19, 53, 40, 59}, {19, 54, 40, 59},
  4239  			{19, 55, 40, 59}, {19, 56, 40, 59}, {19, 57, 40, 59}, {19, 58, 40, 59}, {19, 59, 40, 59},
  4240  			{20, 40, 40, 59}, {20, 41, 40, 59}, {20, 42, 40, 59}, {20, 43, 40, 59}, {20, 44, 40, 59},
  4241  			{20, 45, 40, 59}, {20, 46, 40, 59}, {20, 47, 40, 59}, {20, 48, 40, 59}, {20, 49, 40, 59},
  4242  			{20, 50, 40, 59}, {20, 51, 40, 59}, {20, 52, 40, 59}, {20, 53, 40, 59}, {20, 54, 40, 59},
  4243  			{20, 55, 40, 59}, {20, 56, 40, 59}, {20, 57, 40, 59}, {20, 58, 40, 59}, {20, 59, 40, 59},
  4244  			{21, 40, 40, 59}, {21, 41, 40, 59}, {21, 42, 40, 59}, {21, 43, 40, 59}, {21, 44, 40, 59},
  4245  			{21, 45, 40, 59}, {21, 46, 40, 59}, {21, 47, 40, 59}, {21, 48, 40, 59}, {21, 49, 40, 59},
  4246  			{21, 50, 40, 59}, {21, 51, 40, 59}, {21, 52, 40, 59}, {21, 53, 40, 59}, {21, 54, 40, 59},
  4247  			{21, 55, 40, 59}, {21, 56, 40, 59}, {21, 57, 40, 59}, {21, 58, 40, 59}, {21, 59, 40, 59},
  4248  			{22, 40, 40, 59}, {22, 41, 40, 59}, {22, 42, 40, 59}, {22, 43, 40, 59}, {22, 44, 40, 59},
  4249  			{22, 45, 40, 59}, {22, 46, 40, 59}, {22, 47, 40, 59}, {22, 48, 40, 59}, {22, 49, 40, 59},
  4250  			{22, 50, 40, 59}, {22, 51, 40, 59}, {22, 52, 40, 59}, {22, 53, 40, 59}, {22, 54, 40, 59},
  4251  			{22, 55, 40, 59}, {22, 56, 40, 59}, {22, 57, 40, 59}, {22, 58, 40, 59}, {22, 59, 40, 59},
  4252  			{23, 40, 40, 59}, {23, 41, 40, 59}, {23, 42, 40, 59}, {23, 43, 40, 59}, {23, 44, 40, 59},
  4253  			{23, 45, 40, 59}, {23, 46, 40, 59}, {23, 47, 40, 59}, {23, 48, 40, 59}, {23, 49, 40, 59},
  4254  			{23, 50, 40, 59}, {23, 51, 40, 59}, {23, 52, 40, 59}, {23, 53, 40, 59}, {23, 54, 40, 59},
  4255  			{23, 55, 40, 59}, {23, 56, 40, 59}, {23, 57, 40, 59}, {23, 58, 40, 59}, {23, 59, 40, 59},
  4256  			{24, 40, 40, 59}, {24, 41, 40, 59}, {24, 42, 40, 59}, {24, 43, 40, 59}, {24, 44, 40, 59},
  4257  			{24, 45, 40, 59}, {24, 46, 40, 59}, {24, 47, 40, 59}, {24, 48, 40, 59}, {24, 49, 40, 59},
  4258  			{24, 50, 40, 59}, {24, 51, 40, 59}, {24, 52, 40, 59}, {24, 53, 40, 59}, {24, 54, 40, 59},
  4259  			{24, 55, 40, 59}, {24, 56, 40, 59}, {24, 57, 40, 59}, {24, 58, 40, 59}, {24, 59, 40, 59},
  4260  			{25, 40, 40, 59}, {25, 41, 40, 59}, {25, 42, 40, 59}, {25, 43, 40, 59}, {25, 44, 40, 59},
  4261  			{25, 45, 40, 59}, {25, 46, 40, 59}, {25, 47, 40, 59}, {25, 48, 40, 59}, {25, 49, 40, 59},
  4262  			{25, 50, 40, 59}, {25, 51, 40, 59}, {25, 52, 40, 59}, {25, 53, 40, 59}, {25, 54, 40, 59},
  4263  			{25, 55, 40, 59}, {25, 56, 40, 59}, {25, 57, 40, 59}, {25, 58, 40, 59}, {25, 59, 40, 59},
  4264  			{26, 40, 40, 59}, {26, 41, 40, 59}, {26, 42, 40, 59}, {26, 43, 40, 59}, {26, 44, 40, 59},
  4265  			{26, 45, 40, 59}, {26, 46, 40, 59}, {26, 47, 40, 59}, {26, 48, 40, 59}, {26, 49, 40, 59},
  4266  			{26, 50, 40, 59}, {26, 51, 40, 59}, {26, 52, 40, 59}, {26, 53, 40, 59}, {26, 54, 40, 59},
  4267  			{26, 55, 40, 59}, {26, 56, 40, 59}, {26, 57, 40, 59}, {26, 58, 40, 59}, {26, 59, 40, 59},
  4268  			{27, 40, 40, 59}, {27, 41, 40, 59}, {27, 42, 40, 59}, {27, 43, 40, 59}, {27, 44, 40, 59},
  4269  			{27, 45, 40, 59}, {27, 46, 40, 59}, {27, 47, 40, 59}, {27, 48, 40, 59}, {27, 49, 40, 59},
  4270  			{27, 50, 40, 59}, {27, 51, 40, 59}, {27, 52, 40, 59}, {27, 53, 40, 59}, {27, 54, 40, 59},
  4271  			{27, 55, 40, 59}, {27, 56, 40, 59}, {27, 57, 40, 59}, {27, 58, 40, 59}, {27, 59, 40, 59},
  4272  			{28, 40, 40, 59}, {28, 41, 40, 59}, {28, 42, 40, 59}, {28, 43, 40, 59}, {28, 44, 40, 59},
  4273  			{28, 45, 40, 59}, {28, 46, 40, 59}, {28, 47, 40, 59}, {28, 48, 40, 59}, {28, 49, 40, 59},
  4274  			{28, 50, 40, 59}, {28, 51, 40, 59}, {28, 52, 40, 59}, {28, 53, 40, 59}, {28, 54, 40, 59},
  4275  			{28, 55, 40, 59}, {28, 56, 40, 59}, {28, 57, 40, 59}, {28, 58, 40, 59}, {28, 59, 40, 59},
  4276  			{29, 40, 40, 59}, {29, 41, 40, 59}, {29, 42, 40, 59}, {29, 43, 40, 59}, {29, 44, 40, 59},
  4277  			{29, 45, 40, 59}, {29, 46, 40, 59}, {29, 47, 40, 59}, {29, 48, 40, 59}, {29, 49, 40, 59},
  4278  			{29, 50, 40, 59}, {29, 51, 40, 59}, {29, 52, 40, 59}, {29, 53, 40, 59}, {29, 54, 40, 59},
  4279  			{29, 55, 40, 59}, {29, 56, 40, 59}, {29, 57, 40, 59}, {29, 58, 40, 59}, {29, 59, 40, 59},
  4280  			{30, 40, 40, 59}, {30, 41, 40, 59}, {30, 42, 40, 59}, {30, 43, 40, 59}, {30, 44, 40, 59},
  4281  			{30, 45, 40, 59}, {30, 46, 40, 59}, {30, 47, 40, 59}, {30, 48, 40, 59}, {30, 49, 40, 59},
  4282  			{30, 50, 40, 59}, {30, 51, 40, 59}, {30, 52, 40, 59}, {30, 53, 40, 59}, {30, 54, 40, 59},
  4283  			{30, 55, 40, 59}, {30, 56, 40, 59}, {30, 57, 40, 59}, {30, 58, 40, 59}, {30, 59, 40, 59},
  4284  			{31, 40, 40, 59}, {31, 41, 40, 59}, {31, 42, 40, 59}, {31, 43, 40, 59}, {31, 44, 40, 59},
  4285  			{31, 45, 40, 59}, {31, 46, 40, 59}, {31, 47, 40, 59}, {31, 48, 40, 59}, {31, 49, 40, 59},
  4286  			{31, 50, 40, 59}, {31, 51, 40, 59}, {31, 52, 40, 59}, {31, 53, 40, 59}, {31, 54, 40, 59},
  4287  			{31, 55, 40, 59}, {31, 56, 40, 59}, {31, 57, 40, 59}, {31, 58, 40, 59}, {31, 59, 40, 59},
  4288  			{32, 40, 40, 59}, {32, 41, 40, 59}, {32, 42, 40, 59}, {32, 43, 40, 59}, {32, 44, 40, 59},
  4289  			{32, 45, 40, 59}, {32, 46, 40, 59}, {32, 47, 40, 59}, {32, 48, 40, 59}, {32, 49, 40, 59},
  4290  			{32, 50, 40, 59}, {32, 51, 40, 59}, {32, 52, 40, 59}, {32, 53, 40, 59}, {32, 54, 40, 59},
  4291  			{32, 55, 40, 59}, {32, 56, 40, 59}, {32, 57, 40, 59}, {32, 58, 40, 59}, {32, 59, 40, 59},
  4292  			{33, 40, 40, 59}, {33, 41, 40, 59}, {33, 42, 40, 59}, {33, 43, 40, 59}, {33, 44, 40, 59},
  4293  			{33, 45, 40, 59}, {33, 46, 40, 59}, {33, 47, 40, 59}, {33, 48, 40, 59}, {33, 49, 40, 59},
  4294  			{33, 50, 40, 59}, {33, 51, 40, 59}, {33, 52, 40, 59}, {33, 53, 40, 59}, {33, 54, 40, 59},
  4295  			{33, 55, 40, 59}, {33, 56, 40, 59}, {33, 57, 40, 59}, {33, 58, 40, 59}, {33, 59, 40, 59},
  4296  			{34, 40, 40, 59}, {34, 41, 40, 59}, {34, 42, 40, 59}, {34, 43, 40, 59}, {34, 44, 40, 59},
  4297  			{34, 45, 40, 59}, {34, 46, 40, 59}, {34, 47, 40, 59}, {34, 48, 40, 59}, {34, 49, 40, 59},
  4298  			{34, 50, 40, 59}, {34, 51, 40, 59}, {34, 52, 40, 59}, {34, 53, 40, 59}, {34, 54, 40, 59},
  4299  			{34, 55, 40, 59}, {34, 56, 40, 59}, {34, 57, 40, 59}, {34, 58, 40, 59}, {34, 59, 40, 59},
  4300  			{35, 40, 40, 59}, {35, 41, 40, 59}, {35, 42, 40, 59}, {35, 43, 40, 59}, {35, 44, 40, 59},
  4301  			{35, 45, 40, 59}, {35, 46, 40, 59}, {35, 47, 40, 59}, {35, 48, 40, 59}, {35, 49, 40, 59},
  4302  			{35, 50, 40, 59}, {35, 51, 40, 59}, {35, 52, 40, 59}, {35, 53, 40, 59}, {35, 54, 40, 59},
  4303  			{35, 55, 40, 59}, {35, 56, 40, 59}, {35, 57, 40, 59}, {35, 58, 40, 59}, {35, 59, 40, 59},
  4304  			{36, 40, 40, 59}, {36, 41, 40, 59}, {36, 42, 40, 59}, {36, 43, 40, 59}, {36, 44, 40, 59},
  4305  			{36, 45, 40, 59}, {36, 46, 40, 59}, {36, 47, 40, 59}, {36, 48, 40, 59}, {36, 49, 40, 59},
  4306  			{36, 50, 40, 59}, {36, 51, 40, 59}, {36, 52, 40, 59}, {36, 53, 40, 59}, {36, 54, 40, 59},
  4307  			{36, 55, 40, 59}, {36, 56, 40, 59}, {36, 57, 40, 59}, {36, 58, 40, 59}, {36, 59, 40, 59},
  4308  			{37, 40, 40, 59}, {37, 41, 40, 59}, {37, 42, 40, 59}, {37, 43, 40, 59}, {37, 44, 40, 59},
  4309  			{37, 45, 40, 59}, {37, 46, 40, 59}, {37, 47, 40, 59}, {37, 48, 40, 59}, {37, 49, 40, 59},
  4310  			{37, 50, 40, 59}, {37, 51, 40, 59}, {37, 52, 40, 59}, {37, 53, 40, 59}, {37, 54, 40, 59},
  4311  			{37, 55, 40, 59}, {37, 56, 40, 59}, {37, 57, 40, 59}, {37, 58, 40, 59}, {37, 59, 40, 59},
  4312  			{38, 40, 40, 59}, {38, 41, 40, 59}, {38, 42, 40, 59}, {38, 43, 40, 59}, {38, 44, 40, 59},
  4313  			{38, 45, 40, 59}, {38, 46, 40, 59}, {38, 47, 40, 59}, {38, 48, 40, 59}, {38, 49, 40, 59},
  4314  			{38, 50, 40, 59}, {38, 51, 40, 59}, {38, 52, 40, 59}, {38, 53, 40, 59}, {38, 54, 40, 59},
  4315  			{38, 55, 40, 59}, {38, 56, 40, 59}, {38, 57, 40, 59}, {38, 58, 40, 59}, {38, 59, 40, 59},
  4316  			{39, 40, 40, 59}, {39, 41, 40, 59}, {39, 42, 40, 59}, {39, 43, 40, 59}, {39, 44, 40, 59},
  4317  			{39, 45, 40, 59}, {39, 46, 40, 59}, {39, 47, 40, 59}, {39, 48, 40, 59}, {39, 49, 40, 59},
  4318  			{39, 50, 40, 59}, {39, 51, 40, 59}, {39, 52, 40, 59}, {39, 53, 40, 59}, {39, 54, 40, 59},
  4319  			{39, 55, 40, 59}, {39, 56, 40, 59}, {39, 57, 40, 59}, {39, 58, 40, 59}, {39, 59, 40, 59},
  4320  		},
  4321  	}
  4322  	body4 = testBody{
  4323  		label:  4,
  4324  		offset: dvid.Point3d{75, 40, 60},
  4325  		size:   dvid.Point3d{20, 20, 30},
  4326  		blockSpans: []dvid.Span{
  4327  			{1, 1, 2, 2},
  4328  			{2, 1, 2, 2},
  4329  		},
  4330  		voxelSpans: []dvid.Span{
  4331  			{60, 40, 75, 94}, {60, 41, 75, 94}, {60, 42, 75, 94}, {60, 43, 75, 94}, {60, 44, 75, 94},
  4332  			{60, 45, 75, 94}, {60, 46, 75, 94}, {60, 47, 75, 94}, {60, 48, 75, 94}, {60, 49, 75, 94},
  4333  			{60, 50, 75, 94}, {60, 51, 75, 94}, {60, 52, 75, 94}, {60, 53, 75, 94}, {60, 54, 75, 94},
  4334  			{60, 55, 75, 94}, {60, 56, 75, 94}, {60, 57, 75, 94}, {60, 58, 75, 94}, {60, 59, 75, 94},
  4335  			{61, 40, 75, 94}, {61, 41, 75, 94}, {61, 42, 75, 94}, {61, 43, 75, 94}, {61, 44, 75, 94},
  4336  			{61, 45, 75, 94}, {61, 46, 75, 94}, {61, 47, 75, 94}, {61, 48, 75, 94}, {61, 49, 75, 94},
  4337  			{61, 50, 75, 94}, {61, 51, 75, 94}, {61, 52, 75, 94}, {61, 53, 75, 94}, {61, 54, 75, 94},
  4338  			{61, 55, 75, 94}, {61, 56, 75, 94}, {61, 57, 75, 94}, {61, 58, 75, 94}, {61, 59, 75, 94},
  4339  			{62, 40, 75, 94}, {62, 41, 75, 94}, {62, 42, 75, 94}, {62, 43, 75, 94}, {62, 44, 75, 94},
  4340  			{62, 45, 75, 94}, {62, 46, 75, 94}, {62, 47, 75, 94}, {62, 48, 75, 94}, {62, 49, 75, 94},
  4341  			{62, 50, 75, 94}, {62, 51, 75, 94}, {62, 52, 75, 94}, {62, 53, 75, 94}, {62, 54, 75, 94},
  4342  			{62, 55, 75, 94}, {62, 56, 75, 94}, {62, 57, 75, 94}, {62, 58, 75, 94}, {62, 59, 75, 94},
  4343  			{63, 40, 75, 94}, {63, 41, 75, 94}, {63, 42, 75, 94}, {63, 43, 75, 94}, {63, 44, 75, 94},
  4344  			{63, 45, 75, 94}, {63, 46, 75, 94}, {63, 47, 75, 94}, {63, 48, 75, 94}, {63, 49, 75, 94},
  4345  			{63, 50, 75, 94}, {63, 51, 75, 94}, {63, 52, 75, 94}, {63, 53, 75, 94}, {63, 54, 75, 94},
  4346  			{63, 55, 75, 94}, {63, 56, 75, 94}, {63, 57, 75, 94}, {63, 58, 75, 94}, {63, 59, 75, 94},
  4347  			{64, 40, 75, 94}, {64, 41, 75, 94}, {64, 42, 75, 94}, {64, 43, 75, 94}, {64, 44, 75, 94},
  4348  			{64, 45, 75, 94}, {64, 46, 75, 94}, {64, 47, 75, 94}, {64, 48, 75, 94}, {64, 49, 75, 94},
  4349  			{64, 50, 75, 94}, {64, 51, 75, 94}, {64, 52, 75, 94}, {64, 53, 75, 94}, {64, 54, 75, 94},
  4350  			{64, 55, 75, 94}, {64, 56, 75, 94}, {64, 57, 75, 94}, {64, 58, 75, 94}, {64, 59, 75, 94},
  4351  			{65, 40, 75, 94}, {65, 41, 75, 94}, {65, 42, 75, 94}, {65, 43, 75, 94}, {65, 44, 75, 94},
  4352  			{65, 45, 75, 94}, {65, 46, 75, 94}, {65, 47, 75, 94}, {65, 48, 75, 94}, {65, 49, 75, 94},
  4353  			{65, 50, 75, 94}, {65, 51, 75, 94}, {65, 52, 75, 94}, {65, 53, 75, 94}, {65, 54, 75, 94},
  4354  			{65, 55, 75, 94}, {65, 56, 75, 94}, {65, 57, 75, 94}, {65, 58, 75, 94}, {65, 59, 75, 94},
  4355  			{66, 40, 75, 94}, {66, 41, 75, 94}, {66, 42, 75, 94}, {66, 43, 75, 94}, {66, 44, 75, 94},
  4356  			{66, 45, 75, 94}, {66, 46, 75, 94}, {66, 47, 75, 94}, {66, 48, 75, 94}, {66, 49, 75, 94},
  4357  			{66, 50, 75, 94}, {66, 51, 75, 94}, {66, 52, 75, 94}, {66, 53, 75, 94}, {66, 54, 75, 94},
  4358  			{66, 55, 75, 94}, {66, 56, 75, 94}, {66, 57, 75, 94}, {66, 58, 75, 94}, {66, 59, 75, 94},
  4359  			{67, 40, 75, 94}, {67, 41, 75, 94}, {67, 42, 75, 94}, {67, 43, 75, 94}, {67, 44, 75, 94},
  4360  			{67, 45, 75, 94}, {67, 46, 75, 94}, {67, 47, 75, 94}, {67, 48, 75, 94}, {67, 49, 75, 94},
  4361  			{67, 50, 75, 94}, {67, 51, 75, 94}, {67, 52, 75, 94}, {67, 53, 75, 94}, {67, 54, 75, 94},
  4362  			{67, 55, 75, 94}, {67, 56, 75, 94}, {67, 57, 75, 94}, {67, 58, 75, 94}, {67, 59, 75, 94},
  4363  			{68, 40, 75, 94}, {68, 41, 75, 94}, {68, 42, 75, 94}, {68, 43, 75, 94}, {68, 44, 75, 94},
  4364  			{68, 45, 75, 94}, {68, 46, 75, 94}, {68, 47, 75, 94}, {68, 48, 75, 94}, {68, 49, 75, 94},
  4365  			{68, 50, 75, 94}, {68, 51, 75, 94}, {68, 52, 75, 94}, {68, 53, 75, 94}, {68, 54, 75, 94},
  4366  			{68, 55, 75, 94}, {68, 56, 75, 94}, {68, 57, 75, 94}, {68, 58, 75, 94}, {68, 59, 75, 94},
  4367  			{69, 40, 75, 94}, {69, 41, 75, 94}, {69, 42, 75, 94}, {69, 43, 75, 94}, {69, 44, 75, 94},
  4368  			{69, 45, 75, 94}, {69, 46, 75, 94}, {69, 47, 75, 94}, {69, 48, 75, 94}, {69, 49, 75, 94},
  4369  			{69, 50, 75, 94}, {69, 51, 75, 94}, {69, 52, 75, 94}, {69, 53, 75, 94}, {69, 54, 75, 94},
  4370  			{69, 55, 75, 94}, {69, 56, 75, 94}, {69, 57, 75, 94}, {69, 58, 75, 94}, {69, 59, 75, 94},
  4371  			{70, 40, 75, 94}, {70, 41, 75, 94}, {70, 42, 75, 94}, {70, 43, 75, 94}, {70, 44, 75, 94},
  4372  			{70, 45, 75, 94}, {70, 46, 75, 94}, {70, 47, 75, 94}, {70, 48, 75, 94}, {70, 49, 75, 94},
  4373  			{70, 50, 75, 94}, {70, 51, 75, 94}, {70, 52, 75, 94}, {70, 53, 75, 94}, {70, 54, 75, 94},
  4374  			{70, 55, 75, 94}, {70, 56, 75, 94}, {70, 57, 75, 94}, {70, 58, 75, 94}, {70, 59, 75, 94},
  4375  			{71, 40, 75, 94}, {71, 41, 75, 94}, {71, 42, 75, 94}, {71, 43, 75, 94}, {71, 44, 75, 94},
  4376  			{71, 45, 75, 94}, {71, 46, 75, 94}, {71, 47, 75, 94}, {71, 48, 75, 94}, {71, 49, 75, 94},
  4377  			{71, 50, 75, 94}, {71, 51, 75, 94}, {71, 52, 75, 94}, {71, 53, 75, 94}, {71, 54, 75, 94},
  4378  			{71, 55, 75, 94}, {71, 56, 75, 94}, {71, 57, 75, 94}, {71, 58, 75, 94}, {71, 59, 75, 94},
  4379  			{72, 40, 75, 94}, {72, 41, 75, 94}, {72, 42, 75, 94}, {72, 43, 75, 94}, {72, 44, 75, 94},
  4380  			{72, 45, 75, 94}, {72, 46, 75, 94}, {72, 47, 75, 94}, {72, 48, 75, 94}, {72, 49, 75, 94},
  4381  			{72, 50, 75, 94}, {72, 51, 75, 94}, {72, 52, 75, 94}, {72, 53, 75, 94}, {72, 54, 75, 94},
  4382  			{72, 55, 75, 94}, {72, 56, 75, 94}, {72, 57, 75, 94}, {72, 58, 75, 94}, {72, 59, 75, 94},
  4383  			{73, 40, 75, 94}, {73, 41, 75, 94}, {73, 42, 75, 94}, {73, 43, 75, 94}, {73, 44, 75, 94},
  4384  			{73, 45, 75, 94}, {73, 46, 75, 94}, {73, 47, 75, 94}, {73, 48, 75, 94}, {73, 49, 75, 94},
  4385  			{73, 50, 75, 94}, {73, 51, 75, 94}, {73, 52, 75, 94}, {73, 53, 75, 94}, {73, 54, 75, 94},
  4386  			{73, 55, 75, 94}, {73, 56, 75, 94}, {73, 57, 75, 94}, {73, 58, 75, 94}, {73, 59, 75, 94},
  4387  			{74, 40, 75, 94}, {74, 41, 75, 94}, {74, 42, 75, 94}, {74, 43, 75, 94}, {74, 44, 75, 94},
  4388  			{74, 45, 75, 94}, {74, 46, 75, 94}, {74, 47, 75, 94}, {74, 48, 75, 94}, {74, 49, 75, 94},
  4389  			{74, 50, 75, 94}, {74, 51, 75, 94}, {74, 52, 75, 94}, {74, 53, 75, 94}, {74, 54, 75, 94},
  4390  			{74, 55, 75, 94}, {74, 56, 75, 94}, {74, 57, 75, 94}, {74, 58, 75, 94}, {74, 59, 75, 94},
  4391  			{75, 40, 75, 94}, {75, 41, 75, 94}, {75, 42, 75, 94}, {75, 43, 75, 94}, {75, 44, 75, 94},
  4392  			{75, 45, 75, 94}, {75, 46, 75, 94}, {75, 47, 75, 94}, {75, 48, 75, 94}, {75, 49, 75, 94},
  4393  			{75, 50, 75, 94}, {75, 51, 75, 94}, {75, 52, 75, 94}, {75, 53, 75, 94}, {75, 54, 75, 94},
  4394  			{75, 55, 75, 94}, {75, 56, 75, 94}, {75, 57, 75, 94}, {75, 58, 75, 94}, {75, 59, 75, 94},
  4395  			{76, 40, 75, 94}, {76, 41, 75, 94}, {76, 42, 75, 94}, {76, 43, 75, 94}, {76, 44, 75, 94},
  4396  			{76, 45, 75, 94}, {76, 46, 75, 94}, {76, 47, 75, 94}, {76, 48, 75, 94}, {76, 49, 75, 94},
  4397  			{76, 50, 75, 94}, {76, 51, 75, 94}, {76, 52, 75, 94}, {76, 53, 75, 94}, {76, 54, 75, 94},
  4398  			{76, 55, 75, 94}, {76, 56, 75, 94}, {76, 57, 75, 94}, {76, 58, 75, 94}, {76, 59, 75, 94},
  4399  			{77, 40, 75, 94}, {77, 41, 75, 94}, {77, 42, 75, 94}, {77, 43, 75, 94}, {77, 44, 75, 94},
  4400  			{77, 45, 75, 94}, {77, 46, 75, 94}, {77, 47, 75, 94}, {77, 48, 75, 94}, {77, 49, 75, 94},
  4401  			{77, 50, 75, 94}, {77, 51, 75, 94}, {77, 52, 75, 94}, {77, 53, 75, 94}, {77, 54, 75, 94},
  4402  			{77, 55, 75, 94}, {77, 56, 75, 94}, {77, 57, 75, 94}, {77, 58, 75, 94}, {77, 59, 75, 94},
  4403  			{78, 40, 75, 94}, {78, 41, 75, 94}, {78, 42, 75, 94}, {78, 43, 75, 94}, {78, 44, 75, 94},
  4404  			{78, 45, 75, 94}, {78, 46, 75, 94}, {78, 47, 75, 94}, {78, 48, 75, 94}, {78, 49, 75, 94},
  4405  			{78, 50, 75, 94}, {78, 51, 75, 94}, {78, 52, 75, 94}, {78, 53, 75, 94}, {78, 54, 75, 94},
  4406  			{78, 55, 75, 94}, {78, 56, 75, 94}, {78, 57, 75, 94}, {78, 58, 75, 94}, {78, 59, 75, 94},
  4407  			{79, 40, 75, 94}, {79, 41, 75, 94}, {79, 42, 75, 94}, {79, 43, 75, 94}, {79, 44, 75, 94},
  4408  			{79, 45, 75, 94}, {79, 46, 75, 94}, {79, 47, 75, 94}, {79, 48, 75, 94}, {79, 49, 75, 94},
  4409  			{79, 50, 75, 94}, {79, 51, 75, 94}, {79, 52, 75, 94}, {79, 53, 75, 94}, {79, 54, 75, 94},
  4410  			{79, 55, 75, 94}, {79, 56, 75, 94}, {79, 57, 75, 94}, {79, 58, 75, 94}, {79, 59, 75, 94},
  4411  			{80, 40, 75, 94}, {80, 41, 75, 94}, {80, 42, 75, 94}, {80, 43, 75, 94}, {80, 44, 75, 94},
  4412  			{80, 45, 75, 94}, {80, 46, 75, 94}, {80, 47, 75, 94}, {80, 48, 75, 94}, {80, 49, 75, 94},
  4413  			{80, 50, 75, 94}, {80, 51, 75, 94}, {80, 52, 75, 94}, {80, 53, 75, 94}, {80, 54, 75, 94},
  4414  			{80, 55, 75, 94}, {80, 56, 75, 94}, {80, 57, 75, 94}, {80, 58, 75, 94}, {80, 59, 75, 94},
  4415  			{81, 40, 75, 94}, {81, 41, 75, 94}, {81, 42, 75, 94}, {81, 43, 75, 94}, {81, 44, 75, 94},
  4416  			{81, 45, 75, 94}, {81, 46, 75, 94}, {81, 47, 75, 94}, {81, 48, 75, 94}, {81, 49, 75, 94},
  4417  			{81, 50, 75, 94}, {81, 51, 75, 94}, {81, 52, 75, 94}, {81, 53, 75, 94}, {81, 54, 75, 94},
  4418  			{81, 55, 75, 94}, {81, 56, 75, 94}, {81, 57, 75, 94}, {81, 58, 75, 94}, {81, 59, 75, 94},
  4419  			{82, 40, 75, 94}, {82, 41, 75, 94}, {82, 42, 75, 94}, {82, 43, 75, 94}, {82, 44, 75, 94},
  4420  			{82, 45, 75, 94}, {82, 46, 75, 94}, {82, 47, 75, 94}, {82, 48, 75, 94}, {82, 49, 75, 94},
  4421  			{82, 50, 75, 94}, {82, 51, 75, 94}, {82, 52, 75, 94}, {82, 53, 75, 94}, {82, 54, 75, 94},
  4422  			{82, 55, 75, 94}, {82, 56, 75, 94}, {82, 57, 75, 94}, {82, 58, 75, 94}, {82, 59, 75, 94},
  4423  			{83, 40, 75, 94}, {83, 41, 75, 94}, {83, 42, 75, 94}, {83, 43, 75, 94}, {83, 44, 75, 94},
  4424  			{83, 45, 75, 94}, {83, 46, 75, 94}, {83, 47, 75, 94}, {83, 48, 75, 94}, {83, 49, 75, 94},
  4425  			{83, 50, 75, 94}, {83, 51, 75, 94}, {83, 52, 75, 94}, {83, 53, 75, 94}, {83, 54, 75, 94},
  4426  			{83, 55, 75, 94}, {83, 56, 75, 94}, {83, 57, 75, 94}, {83, 58, 75, 94}, {83, 59, 75, 94},
  4427  			{84, 40, 75, 94}, {84, 41, 75, 94}, {84, 42, 75, 94}, {84, 43, 75, 94}, {84, 44, 75, 94},
  4428  			{84, 45, 75, 94}, {84, 46, 75, 94}, {84, 47, 75, 94}, {84, 48, 75, 94}, {84, 49, 75, 94},
  4429  			{84, 50, 75, 94}, {84, 51, 75, 94}, {84, 52, 75, 94}, {84, 53, 75, 94}, {84, 54, 75, 94},
  4430  			{84, 55, 75, 94}, {84, 56, 75, 94}, {84, 57, 75, 94}, {84, 58, 75, 94}, {84, 59, 75, 94},
  4431  			{85, 40, 75, 94}, {85, 41, 75, 94}, {85, 42, 75, 94}, {85, 43, 75, 94}, {85, 44, 75, 94},
  4432  			{85, 45, 75, 94}, {85, 46, 75, 94}, {85, 47, 75, 94}, {85, 48, 75, 94}, {85, 49, 75, 94},
  4433  			{85, 50, 75, 94}, {85, 51, 75, 94}, {85, 52, 75, 94}, {85, 53, 75, 94}, {85, 54, 75, 94},
  4434  			{85, 55, 75, 94}, {85, 56, 75, 94}, {85, 57, 75, 94}, {85, 58, 75, 94}, {85, 59, 75, 94},
  4435  			{86, 40, 75, 94}, {86, 41, 75, 94}, {86, 42, 75, 94}, {86, 43, 75, 94}, {86, 44, 75, 94},
  4436  			{86, 45, 75, 94}, {86, 46, 75, 94}, {86, 47, 75, 94}, {86, 48, 75, 94}, {86, 49, 75, 94},
  4437  			{86, 50, 75, 94}, {86, 51, 75, 94}, {86, 52, 75, 94}, {86, 53, 75, 94}, {86, 54, 75, 94},
  4438  			{86, 55, 75, 94}, {86, 56, 75, 94}, {86, 57, 75, 94}, {86, 58, 75, 94}, {86, 59, 75, 94},
  4439  			{87, 40, 75, 94}, {87, 41, 75, 94}, {87, 42, 75, 94}, {87, 43, 75, 94}, {87, 44, 75, 94},
  4440  			{87, 45, 75, 94}, {87, 46, 75, 94}, {87, 47, 75, 94}, {87, 48, 75, 94}, {87, 49, 75, 94},
  4441  			{87, 50, 75, 94}, {87, 51, 75, 94}, {87, 52, 75, 94}, {87, 53, 75, 94}, {87, 54, 75, 94},
  4442  			{87, 55, 75, 94}, {87, 56, 75, 94}, {87, 57, 75, 94}, {87, 58, 75, 94}, {87, 59, 75, 94},
  4443  			{88, 40, 75, 94}, {88, 41, 75, 94}, {88, 42, 75, 94}, {88, 43, 75, 94}, {88, 44, 75, 94},
  4444  			{88, 45, 75, 94}, {88, 46, 75, 94}, {88, 47, 75, 94}, {88, 48, 75, 94}, {88, 49, 75, 94},
  4445  			{88, 50, 75, 94}, {88, 51, 75, 94}, {88, 52, 75, 94}, {88, 53, 75, 94}, {88, 54, 75, 94},
  4446  			{88, 55, 75, 94}, {88, 56, 75, 94}, {88, 57, 75, 94}, {88, 58, 75, 94}, {88, 59, 75, 94},
  4447  			{89, 40, 75, 94}, {89, 41, 75, 94}, {89, 42, 75, 94}, {89, 43, 75, 94}, {89, 44, 75, 94},
  4448  			{89, 45, 75, 94}, {89, 46, 75, 94}, {89, 47, 75, 94}, {89, 48, 75, 94}, {89, 49, 75, 94},
  4449  			{89, 50, 75, 94}, {89, 51, 75, 94}, {89, 52, 75, 94}, {89, 53, 75, 94}, {89, 54, 75, 94},
  4450  			{89, 55, 75, 94}, {89, 56, 75, 94}, {89, 57, 75, 94}, {89, 58, 75, 94}, {89, 59, 75, 94},
  4451  		},
  4452  	}
  4453  	bodyleft = testBody{
  4454  		label:  6,
  4455  		offset: dvid.Point3d{75, 40, 60},
  4456  		size:   dvid.Point3d{20, 20, 21},
  4457  		blockSpans: []dvid.Span{
  4458  			{1, 1, 2, 2},
  4459  			{2, 1, 2, 2},
  4460  		},
  4461  		voxelSpans: []dvid.Span{
  4462  			{60, 40, 75, 94}, {60, 41, 75, 94}, {60, 42, 75, 94}, {60, 43, 75, 94}, {60, 44, 75, 94},
  4463  			{60, 45, 75, 94}, {60, 46, 75, 94}, {60, 47, 75, 94}, {60, 48, 75, 94}, {60, 49, 75, 94},
  4464  			{60, 50, 75, 94}, {60, 51, 75, 94}, {60, 52, 75, 94}, {60, 53, 75, 94}, {60, 54, 75, 94},
  4465  			{60, 55, 75, 94}, {60, 56, 75, 94}, {60, 57, 75, 94}, {60, 58, 75, 94}, {60, 59, 75, 94},
  4466  			{61, 40, 75, 94}, {61, 41, 75, 94}, {61, 42, 75, 94}, {61, 43, 75, 94}, {61, 44, 75, 94},
  4467  			{61, 45, 75, 94}, {61, 46, 75, 94}, {61, 47, 75, 94}, {61, 48, 75, 94}, {61, 49, 75, 94},
  4468  			{61, 50, 75, 94}, {61, 51, 75, 94}, {61, 52, 75, 94}, {61, 53, 75, 94}, {61, 54, 75, 94},
  4469  			{61, 55, 75, 94}, {61, 56, 75, 94}, {61, 57, 75, 94}, {61, 58, 75, 94}, {61, 59, 75, 94},
  4470  			{62, 40, 75, 94}, {62, 41, 75, 94}, {62, 42, 75, 94}, {62, 43, 75, 94}, {62, 44, 75, 94},
  4471  			{62, 45, 75, 94}, {62, 46, 75, 94}, {62, 47, 75, 94}, {62, 48, 75, 94}, {62, 49, 75, 94},
  4472  			{62, 50, 75, 94}, {62, 51, 75, 94}, {62, 52, 75, 94}, {62, 53, 75, 94}, {62, 54, 75, 94},
  4473  			{62, 55, 75, 94}, {62, 56, 75, 94}, {62, 57, 75, 94}, {62, 58, 75, 94}, {62, 59, 75, 94},
  4474  			{63, 40, 75, 94}, {63, 41, 75, 94}, {63, 42, 75, 94}, {63, 43, 75, 94}, {63, 44, 75, 94},
  4475  			{63, 45, 75, 94}, {63, 46, 75, 94}, {63, 47, 75, 94}, {63, 48, 75, 94}, {63, 49, 75, 94},
  4476  			{63, 50, 75, 94}, {63, 51, 75, 94}, {63, 52, 75, 94}, {63, 53, 75, 94}, {63, 54, 75, 94},
  4477  			{63, 55, 75, 94}, {63, 56, 75, 94}, {63, 57, 75, 94}, {63, 58, 75, 94}, {63, 59, 75, 94},
  4478  			{64, 40, 75, 94}, {64, 41, 75, 94}, {64, 42, 75, 94}, {64, 43, 75, 94}, {64, 44, 75, 94},
  4479  			{64, 45, 75, 94}, {64, 46, 75, 94}, {64, 47, 75, 94}, {64, 48, 75, 94}, {64, 49, 75, 94},
  4480  			{64, 50, 75, 94}, {64, 51, 75, 94}, {64, 52, 75, 94}, {64, 53, 75, 94}, {64, 54, 75, 94},
  4481  			{64, 55, 75, 94}, {64, 56, 75, 94}, {64, 57, 75, 94}, {64, 58, 75, 94}, {64, 59, 75, 94},
  4482  			{65, 40, 75, 94}, {65, 41, 75, 94}, {65, 42, 75, 94}, {65, 43, 75, 94}, {65, 44, 75, 94},
  4483  			{65, 45, 75, 94}, {65, 46, 75, 94}, {65, 47, 75, 94}, {65, 48, 75, 94}, {65, 49, 75, 94},
  4484  			{65, 50, 75, 94}, {65, 51, 75, 94}, {65, 52, 75, 94}, {65, 53, 75, 94}, {65, 54, 75, 94},
  4485  			{65, 55, 75, 94}, {65, 56, 75, 94}, {65, 57, 75, 94}, {65, 58, 75, 94}, {65, 59, 75, 94},
  4486  			{66, 40, 75, 94}, {66, 41, 75, 94}, {66, 42, 75, 94}, {66, 43, 75, 94}, {66, 44, 75, 94},
  4487  			{66, 45, 75, 94}, {66, 46, 75, 94}, {66, 47, 75, 94}, {66, 48, 75, 94}, {66, 49, 75, 94},
  4488  			{66, 50, 75, 94}, {66, 51, 75, 94}, {66, 52, 75, 94}, {66, 53, 75, 94}, {66, 54, 75, 94},
  4489  			{66, 55, 75, 94}, {66, 56, 75, 94}, {66, 57, 75, 94}, {66, 58, 75, 94}, {66, 59, 75, 94},
  4490  			{67, 40, 75, 94}, {67, 41, 75, 94}, {67, 42, 75, 94}, {67, 43, 75, 94}, {67, 44, 75, 94},
  4491  			{67, 45, 75, 94}, {67, 46, 75, 94}, {67, 47, 75, 94}, {67, 48, 75, 94}, {67, 49, 75, 94},
  4492  			{67, 50, 75, 94}, {67, 51, 75, 94}, {67, 52, 75, 94}, {67, 53, 75, 94}, {67, 54, 75, 94},
  4493  			{67, 55, 75, 94}, {67, 56, 75, 94}, {67, 57, 75, 94}, {67, 58, 75, 94}, {67, 59, 75, 94},
  4494  			{68, 40, 75, 94}, {68, 41, 75, 94}, {68, 42, 75, 94}, {68, 43, 75, 94}, {68, 44, 75, 94},
  4495  			{68, 45, 75, 94}, {68, 46, 75, 94}, {68, 47, 75, 94}, {68, 48, 75, 94}, {68, 49, 75, 94},
  4496  			{68, 50, 75, 94}, {68, 51, 75, 94}, {68, 52, 75, 94}, {68, 53, 75, 94}, {68, 54, 75, 94},
  4497  			{68, 55, 75, 94}, {68, 56, 75, 94}, {68, 57, 75, 94}, {68, 58, 75, 94}, {68, 59, 75, 94},
  4498  			{69, 40, 75, 94}, {69, 41, 75, 94}, {69, 42, 75, 94}, {69, 43, 75, 94}, {69, 44, 75, 94},
  4499  			{69, 45, 75, 94}, {69, 46, 75, 94}, {69, 47, 75, 94}, {69, 48, 75, 94}, {69, 49, 75, 94},
  4500  			{69, 50, 75, 94}, {69, 51, 75, 94}, {69, 52, 75, 94}, {69, 53, 75, 94}, {69, 54, 75, 94},
  4501  			{69, 55, 75, 94}, {69, 56, 75, 94}, {69, 57, 75, 94}, {69, 58, 75, 94}, {69, 59, 75, 94},
  4502  			{70, 40, 75, 94}, {70, 41, 75, 94}, {70, 42, 75, 94}, {70, 43, 75, 94}, {70, 44, 75, 94},
  4503  			{70, 45, 75, 94}, {70, 46, 75, 94}, {70, 47, 75, 94}, {70, 48, 75, 94}, {70, 49, 75, 94},
  4504  			{70, 50, 75, 94}, {70, 51, 75, 94}, {70, 52, 75, 94}, {70, 53, 75, 94}, {70, 54, 75, 94},
  4505  			{70, 55, 75, 94}, {70, 56, 75, 94}, {70, 57, 75, 94}, {70, 58, 75, 94}, {70, 59, 75, 94},
  4506  			{71, 40, 75, 94}, {71, 41, 75, 94}, {71, 42, 75, 94}, {71, 43, 75, 94}, {71, 44, 75, 94},
  4507  			{71, 45, 75, 94}, {71, 46, 75, 94}, {71, 47, 75, 94}, {71, 48, 75, 94}, {71, 49, 75, 94},
  4508  			{71, 50, 75, 94}, {71, 51, 75, 94}, {71, 52, 75, 94}, {71, 53, 75, 94}, {71, 54, 75, 94},
  4509  			{71, 55, 75, 94}, {71, 56, 75, 94}, {71, 57, 75, 94}, {71, 58, 75, 94}, {71, 59, 75, 94},
  4510  			{72, 40, 75, 94}, {72, 41, 75, 94}, {72, 42, 75, 94}, {72, 43, 75, 94}, {72, 44, 75, 94},
  4511  			{72, 45, 75, 94}, {72, 46, 75, 94}, {72, 47, 75, 94}, {72, 48, 75, 94}, {72, 49, 75, 94},
  4512  			{72, 50, 75, 94}, {72, 51, 75, 94}, {72, 52, 75, 94}, {72, 53, 75, 94}, {72, 54, 75, 94},
  4513  			{72, 55, 75, 94}, {72, 56, 75, 94}, {72, 57, 75, 94}, {72, 58, 75, 94}, {72, 59, 75, 94},
  4514  			{73, 40, 75, 94}, {73, 41, 75, 94}, {73, 42, 75, 94}, {73, 43, 75, 94}, {73, 44, 75, 94},
  4515  			{73, 45, 75, 94}, {73, 46, 75, 94}, {73, 47, 75, 94}, {73, 48, 75, 94}, {73, 49, 75, 94},
  4516  			{73, 50, 75, 94}, {73, 51, 75, 94}, {73, 52, 75, 94}, {73, 53, 75, 94}, {73, 54, 75, 94},
  4517  			{73, 55, 75, 94}, {73, 56, 75, 94}, {73, 57, 75, 94}, {73, 58, 75, 94}, {73, 59, 75, 94},
  4518  			{74, 40, 75, 94}, {74, 41, 75, 94}, {74, 42, 75, 94}, {74, 43, 75, 94}, {74, 44, 75, 94},
  4519  			{74, 45, 75, 94}, {74, 46, 75, 94}, {74, 47, 75, 94}, {74, 48, 75, 94}, {74, 49, 75, 94},
  4520  			{74, 50, 75, 94}, {74, 51, 75, 94}, {74, 52, 75, 94}, {74, 53, 75, 94}, {74, 54, 75, 94},
  4521  			{74, 55, 75, 94}, {74, 56, 75, 94}, {74, 57, 75, 94}, {74, 58, 75, 94}, {74, 59, 75, 94},
  4522  			{75, 40, 75, 94}, {75, 41, 75, 94}, {75, 42, 75, 94}, {75, 43, 75, 94}, {75, 44, 75, 94},
  4523  			{75, 45, 75, 94}, {75, 46, 75, 94}, {75, 47, 75, 94}, {75, 48, 75, 94}, {75, 49, 75, 94},
  4524  			{75, 50, 75, 94}, {75, 51, 75, 94}, {75, 52, 75, 94}, {75, 53, 75, 94}, {75, 54, 75, 94},
  4525  			{75, 55, 75, 94}, {75, 56, 75, 94}, {75, 57, 75, 94}, {75, 58, 75, 94}, {75, 59, 75, 94},
  4526  			{76, 40, 75, 94}, {76, 41, 75, 94}, {76, 42, 75, 94}, {76, 43, 75, 94}, {76, 44, 75, 94},
  4527  			{76, 45, 75, 94}, {76, 46, 75, 94}, {76, 47, 75, 94}, {76, 48, 75, 94}, {76, 49, 75, 94},
  4528  			{76, 50, 75, 94}, {76, 51, 75, 94}, {76, 52, 75, 94}, {76, 53, 75, 94}, {76, 54, 75, 94},
  4529  			{76, 55, 75, 94}, {76, 56, 75, 94}, {76, 57, 75, 94}, {76, 58, 75, 94}, {76, 59, 75, 94},
  4530  			{77, 40, 75, 94}, {77, 41, 75, 94}, {77, 42, 75, 94}, {77, 43, 75, 94}, {77, 44, 75, 94},
  4531  			{77, 45, 75, 94}, {77, 46, 75, 94}, {77, 47, 75, 94}, {77, 48, 75, 94}, {77, 49, 75, 94},
  4532  			{77, 50, 75, 94}, {77, 51, 75, 94}, {77, 52, 75, 94}, {77, 53, 75, 94}, {77, 54, 75, 94},
  4533  			{77, 55, 75, 94}, {77, 56, 75, 94}, {77, 57, 75, 94}, {77, 58, 75, 94}, {77, 59, 75, 94},
  4534  			{78, 40, 75, 94}, {78, 41, 75, 94}, {78, 42, 75, 94}, {78, 43, 75, 94}, {78, 44, 75, 94},
  4535  			{78, 45, 75, 94}, {78, 46, 75, 94}, {78, 47, 75, 94}, {78, 48, 75, 94}, {78, 49, 75, 94},
  4536  			{78, 50, 75, 94}, {78, 51, 75, 94}, {78, 52, 75, 94}, {78, 53, 75, 94}, {78, 54, 75, 94},
  4537  			{78, 55, 75, 94}, {78, 56, 75, 94}, {78, 57, 75, 94}, {78, 58, 75, 94}, {78, 59, 75, 94},
  4538  			{79, 40, 75, 94}, {79, 41, 75, 94}, {79, 42, 75, 94}, {79, 43, 75, 94}, {79, 44, 75, 94},
  4539  			{79, 45, 75, 94}, {79, 46, 75, 94}, {79, 47, 75, 94}, {79, 48, 75, 94}, {79, 49, 75, 94},
  4540  			{79, 50, 75, 94}, {79, 51, 75, 94}, {79, 52, 75, 94}, {79, 53, 75, 94}, {79, 54, 75, 94},
  4541  			{79, 55, 75, 94}, {79, 56, 75, 94}, {79, 57, 75, 94}, {79, 58, 75, 94}, {79, 59, 75, 94},
  4542  			{80, 40, 75, 80}, {80, 40, 87, 89}, {80, 40, 93, 94},
  4543  		},
  4544  	}
  4545  	bodysplit = testBody{
  4546  		label:  5,
  4547  		offset: dvid.Point3d{75, 40, 80},
  4548  		size:   dvid.Point3d{20, 20, 10},
  4549  		blockSpans: []dvid.Span{
  4550  			{2, 1, 2, 2},
  4551  		},
  4552  		voxelSpans: []dvid.Span{
  4553  			{80, 40, 81, 86}, {80, 40, 90, 92}, // These first 2 test splits interleaved in one span.
  4554  			{80, 41, 75, 94}, {80, 42, 75, 94}, {80, 43, 75, 94}, {80, 44, 75, 94},
  4555  			{80, 45, 75, 94}, {80, 46, 75, 94}, {80, 47, 75, 94}, {80, 48, 75, 94}, {80, 49, 75, 94},
  4556  			{80, 50, 75, 94}, {80, 51, 75, 94}, {80, 52, 75, 94}, {80, 53, 75, 94}, {80, 54, 75, 94},
  4557  			{80, 55, 75, 94}, {80, 56, 75, 94}, {80, 57, 75, 94}, {80, 58, 75, 94}, {80, 59, 75, 94},
  4558  			{81, 40, 75, 94}, {81, 41, 75, 94}, {81, 42, 75, 94}, {81, 43, 75, 94}, {81, 44, 75, 94},
  4559  			{81, 45, 75, 94}, {81, 46, 75, 94}, {81, 47, 75, 94}, {81, 48, 75, 94}, {81, 49, 75, 94},
  4560  			{81, 50, 75, 94}, {81, 51, 75, 94}, {81, 52, 75, 94}, {81, 53, 75, 94}, {81, 54, 75, 94},
  4561  			{81, 55, 75, 94}, {81, 56, 75, 94}, {81, 57, 75, 94}, {81, 58, 75, 94}, {81, 59, 75, 94},
  4562  			{82, 40, 75, 94}, {82, 41, 75, 94}, {82, 42, 75, 94}, {82, 43, 75, 94}, {82, 44, 75, 94},
  4563  			{82, 45, 75, 94}, {82, 46, 75, 94}, {82, 47, 75, 94}, {82, 48, 75, 94}, {82, 49, 75, 94},
  4564  			{82, 50, 75, 94}, {82, 51, 75, 94}, {82, 52, 75, 94}, {82, 53, 75, 94}, {82, 54, 75, 94},
  4565  			{82, 55, 75, 94}, {82, 56, 75, 94}, {82, 57, 75, 94}, {82, 58, 75, 94}, {82, 59, 75, 94},
  4566  			{83, 40, 75, 94}, {83, 41, 75, 94}, {83, 42, 75, 94}, {83, 43, 75, 94}, {83, 44, 75, 94},
  4567  			{83, 45, 75, 94}, {83, 46, 75, 94}, {83, 47, 75, 94}, {83, 48, 75, 94}, {83, 49, 75, 94},
  4568  			{83, 50, 75, 94}, {83, 51, 75, 94}, {83, 52, 75, 94}, {83, 53, 75, 94}, {83, 54, 75, 94},
  4569  			{83, 55, 75, 94}, {83, 56, 75, 94}, {83, 57, 75, 94}, {83, 58, 75, 94}, {83, 59, 75, 94},
  4570  			{84, 40, 75, 94}, {84, 41, 75, 94}, {84, 42, 75, 94}, {84, 43, 75, 94}, {84, 44, 75, 94},
  4571  			{84, 45, 75, 94}, {84, 46, 75, 94}, {84, 47, 75, 94}, {84, 48, 75, 94}, {84, 49, 75, 94},
  4572  			{84, 50, 75, 94}, {84, 51, 75, 94}, {84, 52, 75, 94}, {84, 53, 75, 94}, {84, 54, 75, 94},
  4573  			{84, 55, 75, 94}, {84, 56, 75, 94}, {84, 57, 75, 94}, {84, 58, 75, 94}, {84, 59, 75, 94},
  4574  			{85, 40, 75, 94}, {85, 41, 75, 94}, {85, 42, 75, 94}, {85, 43, 75, 94}, {85, 44, 75, 94},
  4575  			{85, 45, 75, 94}, {85, 46, 75, 94}, {85, 47, 75, 94}, {85, 48, 75, 94}, {85, 49, 75, 94},
  4576  			{85, 50, 75, 94}, {85, 51, 75, 94}, {85, 52, 75, 94}, {85, 53, 75, 94}, {85, 54, 75, 94},
  4577  			{85, 55, 75, 94}, {85, 56, 75, 94}, {85, 57, 75, 94}, {85, 58, 75, 94}, {85, 59, 75, 94},
  4578  			{86, 40, 75, 94}, {86, 41, 75, 94}, {86, 42, 75, 94}, {86, 43, 75, 94}, {86, 44, 75, 94},
  4579  			{86, 45, 75, 94}, {86, 46, 75, 94}, {86, 47, 75, 94}, {86, 48, 75, 94}, {86, 49, 75, 94},
  4580  			{86, 50, 75, 94}, {86, 51, 75, 94}, {86, 52, 75, 94}, {86, 53, 75, 94}, {86, 54, 75, 94},
  4581  			{86, 55, 75, 94}, {86, 56, 75, 94}, {86, 57, 75, 94}, {86, 58, 75, 94}, {86, 59, 75, 94},
  4582  			{87, 40, 75, 94}, {87, 41, 75, 94}, {87, 42, 75, 94}, {87, 43, 75, 94}, {87, 44, 75, 94},
  4583  			{87, 45, 75, 94}, {87, 46, 75, 94}, {87, 47, 75, 94}, {87, 48, 75, 94}, {87, 49, 75, 94},
  4584  			{87, 50, 75, 94}, {87, 51, 75, 94}, {87, 52, 75, 94}, {87, 53, 75, 94}, {87, 54, 75, 94},
  4585  			{87, 55, 75, 94}, {87, 56, 75, 94}, {87, 57, 75, 94}, {87, 58, 75, 94}, {87, 59, 75, 94},
  4586  			{88, 40, 75, 94}, {88, 41, 75, 94}, {88, 42, 75, 94}, {88, 43, 75, 94}, {88, 44, 75, 94},
  4587  			{88, 45, 75, 94}, {88, 46, 75, 94}, {88, 47, 75, 94}, {88, 48, 75, 94}, {88, 49, 75, 94},
  4588  			{88, 50, 75, 94}, {88, 51, 75, 94}, {88, 52, 75, 94}, {88, 53, 75, 94}, {88, 54, 75, 94},
  4589  			{88, 55, 75, 94}, {88, 56, 75, 94}, {88, 57, 75, 94}, {88, 58, 75, 94}, {88, 59, 75, 94},
  4590  			{89, 40, 75, 94}, {89, 41, 75, 94}, {89, 42, 75, 94}, {89, 43, 75, 94}, {89, 44, 75, 94},
  4591  			{89, 45, 75, 94}, {89, 46, 75, 94}, {89, 47, 75, 94}, {89, 48, 75, 94}, {89, 49, 75, 94},
  4592  			{89, 50, 75, 94}, {89, 51, 75, 94}, {89, 52, 75, 94}, {89, 53, 75, 94}, {89, 54, 75, 94},
  4593  			{89, 55, 75, 94}, {89, 56, 75, 94}, {89, 57, 75, 94}, {89, 58, 75, 94}, {89, 59, 75, 94},
  4594  		},
  4595  	}
  4596  	body6 = testBody{
  4597  		label:  6,
  4598  		offset: dvid.Point3d{8, 10, 7},
  4599  		size:   dvid.Point3d{52, 50, 10},
  4600  		blockSpans: []dvid.Span{
  4601  			{0, 0, 0, 1},
  4602  			{0, 1, 0, 1},
  4603  		},
  4604  		voxelSpans: []dvid.Span{
  4605  			{8, 11, 9, 31}, {8, 12, 9, 59}, {8, 13, 9, 59}, {8, 14, 9, 59},
  4606  			{8, 15, 19, 59}, {8, 16, 19, 59}, {8, 17, 19, 59}, {8, 18, 19, 59},
  4607  			{8, 19, 29, 59}, {8, 20, 29, 59}, {8, 21, 29, 59}, {8, 22, 29, 59},
  4608  			{8, 23, 39, 59}, {8, 24, 39, 59}, {8, 25, 39, 59}, {8, 26, 39, 59},
  4609  			{8, 23, 39, 59}, {8, 24, 39, 59}, {8, 25, 39, 59}, {8, 26, 39, 59},
  4610  			{8, 27, 39, 59}, {8, 28, 39, 59}, {8, 29, 39, 59}, {8, 30, 39, 59},
  4611  			{8, 31, 39, 59}, {8, 32, 39, 59}, {8, 33, 39, 59}, {8, 34, 39, 59},
  4612  			{8, 35, 39, 59}, {8, 36, 39, 59}, {8, 37, 45, 59}, {8, 38, 39, 59},
  4613  			{8, 39, 39, 59}, {8, 40, 39, 59}, {8, 41, 42, 59}, {8, 42, 39, 56},
  4614  			{8, 43, 39, 59}, {8, 44, 39, 59}, {8, 45, 39, 59}, {8, 46, 39, 50},
  4615  
  4616  			{8, 11, 9, 59}, {8, 12, 9, 59}, {8, 13, 9, 59}, {8, 14, 9, 59},
  4617  			{8, 15, 19, 59}, {8, 16, 19, 59}, {8, 17, 19, 59}, {8, 18, 19, 59},
  4618  			{8, 19, 29, 59}, {8, 20, 29, 59}, {8, 21, 29, 59}, {8, 22, 29, 59},
  4619  			{8, 23, 39, 59}, {8, 24, 39, 59}, {8, 25, 39, 59}, {8, 26, 39, 59},
  4620  			{8, 23, 39, 59}, {8, 24, 39, 59}, {8, 25, 39, 59}, {8, 26, 39, 59},
  4621  			{8, 27, 39, 59}, {8, 28, 39, 59}, {8, 29, 39, 59}, {8, 30, 39, 59},
  4622  			{8, 31, 39, 59}, {8, 32, 39, 59}, {8, 33, 39, 59}, {8, 34, 39, 59},
  4623  			{8, 35, 39, 59}, {8, 36, 39, 59}, {8, 37, 45, 59}, {8, 38, 39, 59},
  4624  			{8, 39, 39, 59}, {8, 40, 39, 59}, {8, 41, 42, 59}, {8, 42, 39, 56},
  4625  			{8, 43, 39, 59}, {8, 44, 39, 59}, {8, 45, 39, 59}, {8, 46, 39, 50},
  4626  
  4627  			{9, 11, 9, 59}, {9, 12, 9, 59}, {9, 13, 9, 59}, {9, 14, 9, 59},
  4628  			{9, 15, 19, 59}, {9, 16, 19, 59}, {9, 17, 19, 59}, {9, 18, 19, 59},
  4629  			{9, 19, 29, 59}, {9, 20, 29, 59}, {9, 21, 29, 59}, {9, 22, 29, 59},
  4630  			{9, 23, 39, 59}, {9, 24, 39, 59}, {9, 25, 39, 59}, {9, 26, 39, 59},
  4631  			{9, 23, 39, 59}, {9, 24, 39, 59}, {9, 25, 39, 59}, {9, 26, 39, 59},
  4632  			{9, 27, 39, 59}, {9, 28, 39, 59}, {9, 29, 39, 59}, {9, 30, 39, 59},
  4633  			{9, 31, 39, 59}, {9, 32, 39, 59}, {9, 33, 39, 59}, {9, 34, 39, 59},
  4634  			{9, 35, 39, 59}, {9, 36, 39, 59}, {9, 37, 45, 59}, {9, 38, 39, 59},
  4635  			{9, 39, 39, 59}, {9, 40, 39, 59}, {9, 41, 42, 59}, {9, 42, 39, 56},
  4636  			{9, 43, 39, 59}, {9, 44, 39, 59}, {9, 45, 39, 59}, {9, 46, 39, 50},
  4637  
  4638  			{10, 11, 9, 59}, {10, 12, 9, 59}, {10, 13, 9, 59}, {10, 14, 9, 59},
  4639  			{10, 15, 19, 59}, {10, 16, 19, 59}, {10, 17, 19, 59}, {10, 18, 19, 59},
  4640  			{10, 19, 29, 59}, {10, 20, 29, 59}, {10, 21, 29, 59}, {10, 22, 29, 59},
  4641  			{10, 23, 39, 59}, {10, 24, 39, 59}, {10, 25, 39, 59}, {10, 26, 39, 59},
  4642  			{10, 23, 39, 59}, {10, 24, 39, 59}, {10, 25, 39, 59}, {10, 26, 39, 59},
  4643  			{10, 27, 39, 59}, {10, 28, 39, 59}, {10, 29, 39, 59}, {10, 30, 39, 59},
  4644  			{10, 31, 39, 59}, {10, 32, 39, 59}, {10, 33, 39, 59}, {10, 34, 39, 59},
  4645  			{10, 35, 39, 59}, {10, 36, 39, 59}, {10, 37, 45, 59}, {10, 38, 39, 59},
  4646  			{10, 39, 39, 59}, {10, 40, 39, 59}, {10, 41, 42, 59}, {10, 42, 39, 56},
  4647  			{10, 43, 39, 59}, {10, 44, 39, 59}, {10, 45, 39, 59}, {10, 46, 39, 50},
  4648  
  4649  			{11, 11, 9, 59}, {11, 12, 9, 59}, {11, 13, 9, 59}, {11, 14, 9, 59},
  4650  			{11, 15, 19, 59}, {11, 16, 19, 59}, {11, 17, 19, 59}, {11, 18, 19, 59},
  4651  			{11, 19, 29, 59}, {11, 20, 29, 59}, {11, 21, 29, 59}, {11, 22, 29, 59},
  4652  			{11, 23, 39, 59}, {11, 24, 39, 59}, {11, 25, 39, 59}, {11, 26, 39, 59},
  4653  			{11, 23, 39, 59}, {11, 24, 39, 59}, {11, 25, 39, 59}, {11, 26, 39, 59},
  4654  			{11, 27, 39, 59}, {11, 28, 39, 59}, {11, 29, 39, 59}, {11, 30, 39, 59},
  4655  			{11, 31, 39, 59}, {11, 32, 39, 59}, {11, 33, 39, 59}, {11, 34, 39, 59},
  4656  			{11, 35, 39, 59}, {11, 36, 39, 59}, {11, 37, 45, 59}, {11, 38, 39, 59},
  4657  			{11, 39, 39, 59}, {11, 40, 39, 59}, {11, 41, 42, 59}, {11, 42, 39, 56},
  4658  			{11, 43, 39, 59}, {11, 44, 39, 59}, {11, 45, 39, 59}, {11, 46, 39, 50},
  4659  
  4660  			{12, 11, 9, 59}, {12, 12, 9, 59}, {12, 13, 9, 59}, {12, 14, 9, 59},
  4661  			{12, 15, 19, 59}, {12, 16, 19, 59}, {12, 17, 19, 59}, {12, 18, 19, 59},
  4662  			{12, 19, 29, 59}, {12, 20, 29, 59}, {12, 21, 29, 59}, {12, 22, 29, 59},
  4663  			{12, 23, 39, 59}, {12, 24, 39, 59}, {12, 25, 39, 59}, {12, 26, 39, 59},
  4664  			{12, 23, 39, 59}, {12, 24, 39, 59}, {12, 25, 39, 59}, {12, 26, 39, 59},
  4665  			{12, 27, 39, 59}, {12, 28, 39, 59}, {12, 29, 39, 59}, {12, 30, 39, 59},
  4666  			{12, 31, 39, 59}, {12, 32, 39, 59}, {12, 33, 39, 59}, {12, 34, 39, 59},
  4667  			{12, 35, 39, 59}, {12, 36, 39, 59}, {12, 37, 45, 59}, {12, 38, 39, 59},
  4668  			{12, 39, 39, 59}, {12, 40, 39, 59}, {12, 41, 42, 59}, {12, 42, 39, 56},
  4669  			{12, 43, 39, 59}, {12, 44, 39, 59}, {12, 45, 39, 59}, {12, 46, 39, 50},
  4670  		},
  4671  	}
  4672  	body7 = testBody{
  4673  		label:  7,
  4674  		offset: dvid.Point3d{68, 10, 7},
  4675  		size:   dvid.Point3d{52, 50, 10},
  4676  		blockSpans: []dvid.Span{
  4677  			{2, 0, 0, 1},
  4678  			{2, 1, 0, 1},
  4679  		},
  4680  		voxelSpans: []dvid.Span{
  4681  			{78, 11, 9, 59}, {78, 12, 9, 59}, {78, 13, 9, 59}, {78, 14, 9, 59},
  4682  			{78, 15, 19, 59}, {78, 16, 19, 59}, {78, 17, 19, 59}, {78, 18, 19, 59},
  4683  			{78, 19, 29, 59}, {78, 20, 29, 59}, {78, 21, 29, 59}, {78, 22, 29, 59},
  4684  			{78, 23, 39, 59}, {78, 24, 39, 59}, {78, 25, 39, 59}, {78, 26, 39, 59},
  4685  			{78, 23, 39, 59}, {78, 24, 39, 59}, {78, 25, 39, 59}, {78, 26, 39, 59},
  4686  			{78, 27, 39, 59}, {78, 28, 39, 59}, {78, 29, 39, 59}, {78, 30, 39, 59},
  4687  			{78, 31, 39, 59}, {78, 32, 39, 59}, {78, 33, 39, 59}, {78, 34, 39, 59},
  4688  			{78, 35, 39, 59}, {78, 36, 39, 59}, {78, 37, 45, 59}, {78, 38, 39, 59},
  4689  			{78, 39, 39, 59}, {78, 40, 39, 59}, {78, 41, 42, 59}, {78, 42, 39, 56},
  4690  			{78, 43, 39, 59}, {78, 44, 39, 59}, {78, 45, 39, 59}, {78, 46, 39, 50},
  4691  
  4692  			{79, 11, 9, 59}, {79, 12, 9, 59}, {79, 13, 9, 59}, {79, 14, 9, 59},
  4693  			{79, 15, 19, 59}, {79, 16, 19, 59}, {79, 17, 19, 59}, {79, 18, 19, 59},
  4694  			{79, 19, 29, 59}, {79, 20, 29, 59}, {79, 21, 29, 59}, {79, 22, 29, 59},
  4695  			{79, 23, 39, 59}, {79, 24, 39, 59}, {79, 25, 39, 59}, {79, 26, 39, 59},
  4696  			{79, 23, 39, 59}, {79, 24, 39, 59}, {79, 25, 39, 59}, {79, 26, 39, 59},
  4697  			{79, 27, 39, 59}, {79, 28, 39, 59}, {79, 29, 39, 59}, {79, 30, 39, 59},
  4698  			{79, 31, 39, 59}, {79, 32, 39, 59}, {79, 33, 39, 59}, {79, 34, 39, 59},
  4699  			{79, 35, 39, 59}, {79, 36, 39, 59}, {79, 37, 45, 59}, {79, 38, 39, 59},
  4700  			{79, 39, 39, 59}, {79, 40, 39, 59}, {79, 41, 42, 59}, {79, 42, 39, 56},
  4701  			{79, 43, 39, 59}, {79, 44, 39, 59}, {79, 45, 39, 59}, {79, 46, 39, 50},
  4702  
  4703  			{80, 11, 9, 59}, {80, 12, 9, 59}, {80, 13, 9, 59}, {80, 14, 9, 59},
  4704  			{80, 15, 19, 59}, {80, 16, 19, 59}, {80, 17, 19, 59}, {80, 18, 19, 59},
  4705  			{80, 19, 29, 59}, {80, 20, 29, 59}, {80, 21, 29, 59}, {80, 22, 29, 59},
  4706  			{80, 23, 39, 59}, {80, 24, 39, 59}, {80, 25, 39, 59}, {80, 26, 39, 59},
  4707  			{80, 23, 39, 59}, {80, 24, 39, 59}, {80, 25, 39, 59}, {80, 26, 39, 59},
  4708  			{80, 27, 39, 59}, {80, 28, 39, 59}, {80, 29, 39, 59}, {80, 30, 39, 59},
  4709  			{80, 31, 39, 59}, {80, 32, 39, 59}, {80, 33, 39, 59}, {80, 34, 39, 59},
  4710  			{80, 35, 39, 59}, {80, 36, 39, 59}, {80, 37, 45, 59}, {80, 38, 39, 59},
  4711  			{80, 39, 39, 59}, {80, 40, 39, 59}, {80, 41, 42, 59}, {80, 42, 39, 56},
  4712  			{80, 43, 39, 59}, {80, 44, 39, 59}, {80, 45, 39, 59}, {80, 46, 39, 50},
  4713  
  4714  			{81, 11, 9, 59}, {81, 12, 9, 59}, {81, 13, 9, 59}, {81, 14, 9, 59},
  4715  			{81, 15, 19, 59}, {81, 16, 19, 59}, {81, 17, 19, 59}, {81, 18, 19, 59},
  4716  			{81, 19, 29, 59}, {81, 20, 29, 59}, {81, 21, 29, 59}, {81, 22, 29, 59},
  4717  			{81, 23, 39, 59}, {81, 24, 39, 59}, {81, 25, 39, 59}, {81, 26, 39, 59},
  4718  			{81, 23, 39, 59}, {81, 24, 39, 59}, {81, 25, 39, 59}, {81, 26, 39, 59},
  4719  			{81, 27, 39, 59}, {81, 28, 39, 59}, {81, 29, 39, 59}, {81, 30, 39, 59},
  4720  			{81, 31, 39, 59}, {81, 32, 39, 59}, {81, 33, 39, 59}, {81, 34, 39, 59},
  4721  			{81, 35, 39, 59}, {81, 36, 39, 59}, {81, 37, 45, 59}, {81, 38, 39, 59},
  4722  			{81, 39, 39, 59}, {81, 40, 39, 59}, {81, 41, 42, 59}, {81, 42, 39, 56},
  4723  			{81, 43, 39, 59}, {81, 44, 39, 59}, {81, 45, 39, 59}, {81, 46, 39, 50},
  4724  
  4725  			{82, 11, 9, 59}, {82, 12, 9, 59}, {82, 13, 9, 59}, {82, 14, 9, 59},
  4726  			{82, 15, 19, 59}, {82, 16, 19, 59}, {82, 17, 19, 59}, {82, 18, 19, 59},
  4727  			{82, 19, 29, 59}, {82, 20, 29, 59}, {82, 21, 29, 59}, {82, 22, 29, 59},
  4728  			{82, 23, 39, 59}, {82, 24, 39, 59}, {82, 25, 39, 59}, {82, 26, 39, 59},
  4729  			{82, 23, 39, 59}, {82, 24, 39, 59}, {82, 25, 39, 59}, {82, 26, 39, 59},
  4730  			{82, 27, 39, 59}, {82, 28, 39, 59}, {82, 29, 39, 59}, {82, 30, 39, 59},
  4731  			{82, 31, 39, 59}, {82, 32, 39, 59}, {82, 33, 39, 59}, {82, 34, 39, 59},
  4732  			{82, 35, 39, 59}, {82, 36, 39, 59}, {82, 37, 45, 59}, {82, 38, 39, 59},
  4733  			{82, 39, 39, 59}, {82, 40, 39, 59}, {82, 41, 42, 59}, {82, 42, 39, 56},
  4734  			{82, 43, 39, 59}, {82, 44, 39, 59}, {82, 45, 39, 59}, {82, 46, 39, 50},
  4735  		},
  4736  	}
  4737  	bodies = []testBody{
  4738  		body1, body2, body3, body4, bodysplit, body6, body7,
  4739  	}
  4740  )