The Smell of Molten Projects in the Morning

Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.

Category: Photography & Images

Taking & making images.

  • NP-BX1 Lithium-ion Batteries: Sony vs. Wasabi

    With this NP-BX1 battery test fixture in hand:

    Sony NP-BX1 battery holder
    Sony NP-BX1 battery holder

    The discharge tests run at 250 mA, which is probably a bit low, as the HDR-AS30V camera can capture video for about two hours on a single battery. Given the Sony’s nominal 1.24 A·h (love that precision!) capacity and derating the Wasabi’s ambitious 1.6 A·h, two hours suggests a current around 500 mA would be more appropriate, but we’ll go with a lower current for now.

    Oddly, the two Wasabi batteries (green & blue traces) outperform the Sony OEM battery (red and purple) in terms of voltage:

    Sony NP-BX1 - OEM Wasabi - 2014-01-28
    Sony NP-BX1 – OEM Wasabi – 2014-01-28

    I can’t explain the small kink just before the big dropoff for both Wasabi batteries. Perhaps the protection circuitry behind the battery terminals has a slight peculiarity?

    Looking at the total energy delivered, however:

    Sony NP-BX1 - OEM Wasabi - Wh - 2014-01-28
    Sony NP-BX1 – OEM Wasabi – Wh – 2014-01-28

    The Sony battery says it’ll deliver 4.5 W·h and actually produces 4.8 W·h. The Wasabi batteries claim 5.7 W·h and don’t even come close at 4.25 W·h.

    I cross-checked those results by importing the CSV data into a spreadsheet, computing the point-by-point power, finding the average, and then multiplying by the total test time in hours. Doing it a couple different ways says you can eyeball a reasonable value by multiplying the median voltage by the test current to get average wattage, then multiplying by the total test time to get W·h. That’s within a few percent, which is good enough for me.

    The camera’s power supply undoubtedly has a low-voltage cutoff, but it’s a single-cell battery and they might just run it down around 2.8 V; in that case, the Sony batteries will last longer. If the voltage cutout is 3.5 V, similar to the Canon camera, then the Wasabi batteries win.

    I don’t have enough experience with the camera or the batteries to predict anything based on actual use.

  • Renaming Files With Sequential Numbers, Plus Moviemaking Therefrom

    The avconv (formerly ffmpeg) image-to-video programs expect sequentially numbered files, with the numbers in a fixed-width part of the file name, thusly: dsc00001.jpg.

    Given a set of files (previously normalized to lowercase) like this:

    ll | head
    total 286576
    -rwxr-xr-x 1 ed ed 595708 Jan 23 19:14 dsc00940.jpg
    -rwxr-xr-x 1 ed ed 515561 Jan 23 19:14 dsc00941.jpg
    -rwxr-xr-x 1 ed ed 580190 Jan 23 19:14 dsc00942.jpg
    -rwxr-xr-x 1 ed ed 571387 Jan 23 19:14 dsc00943.jpg
    -rwxr-xr-x 1 ed ed 573207 Jan 23 19:14 dsc00944.jpg
    -rwxr-xr-x 1 ed ed 571086 Jan 23 19:14 dsc00945.jpg
    -rwxr-xr-x 1 ed ed 571600 Jan 23 19:14 dsc00946.jpg
    -rwxr-xr-x 1 ed ed 571547 Jan 23 19:14 dsc00947.jpg
    -rwxr-xr-x 1 ed ed 565706 Jan 23 19:15 dsc00948.jpg
    

    A Bash one-liner loop does the renumbering:

    sn=1 ; for f in *jpg ; do printf -v dn 'dsc%05d.jpg' "$(( sn++ ))" ; mv $f $dn ; done
    

    The results look pretty much like you’d expect:

    ll | head
    total 286556
    -rwxr-xr-x 1 ed ed 595708 Jan 23 19:14 dsc00001.jpg
    -rwxr-xr-x 1 ed ed 515561 Jan 23 19:14 dsc00002.jpg
    -rwxr-xr-x 1 ed ed 580190 Jan 23 19:14 dsc00003.jpg
    -rwxr-xr-x 1 ed ed 571387 Jan 23 19:14 dsc00004.jpg
    -rwxr-xr-x 1 ed ed 573207 Jan 23 19:14 dsc00005.jpg
    -rwxr-xr-x 1 ed ed 571086 Jan 23 19:14 dsc00006.jpg
    -rwxr-xr-x 1 ed ed 571600 Jan 23 19:14 dsc00007.jpg
    -rwxr-xr-x 1 ed ed 571547 Jan 23 19:14 dsc00008.jpg
    -rwxr-xr-x 1 ed ed 565706 Jan 23 19:15 dsc00009.jpg
    

    Because you’re renaming the files anyway, don’t bother to normalize ’em:

    sn=1 ; for f in *JPG ; do printf -v dn 'dsc%05d.jpg' "$(( sn++ ))" ; mv $f $dn ; done
    

    And, of course, you can fetch ’em from the camera while doing that:

    sn=1 ; for f in /mnt/part/DCIM/100MSDCF/*JPG ; do printf -v dn 'dsc%05d.jpg' "$(( sn++ ))" ; cp -a $f $dn ; done
    

    That leaves the DSC*JPG original files on the camera, where you can delete all of them in one operation when you’re happy with the results.

    If you don’t need the full resolution, reserialize and resize each picture on the fly:

    sn=1 ; for f in /mnt/part/DCIM/100MSDCF/*JPG ; do printf -v dn 'dsc%05d.jpg' "$(( sn++ ))" ; convert $f -resize 50% $dn ; done
    

    That’s based on combining several hints turned up by the usual Google search.

    To assemble a quick-and-simple movie from the images:

    avconv -r 30 -i dsc%05d.jpg -q 5 movie.mp4
    

    The image quality certainly isn’t up to what you (well, I) would expect from a 1920×1080 “HD” file, but the Sony HDR-AS30V Zeiss camera lens seems to be a fisheye pinhole (170° view angle, 2.5 mm f/2.8) backed with relentless image compression:

    Sony HDR-AS30V Action Camera
    Sony HDR-AS30V Action Camera

    Memo to Self: It’s not worth creating and remembering Yet Another Script.

  • Changing the Case of a FAT File Name

    While converting a stop-action series of images from the HDR-AS30V into a movie, I wanted change all the image files on a USB Flash drive from DSC00008.JPG to dsc00008.jpg, so as to simplify typing their names.

    Alas, because the camera’s exFAT filesystem cares not one whit about case, the obvious command doesn’t work:

    rename 's/JPG/jpg/' /mnt/part/*
    /mnt/part/DSC00008.JPG not renamed: /mnt/part/DSC00008.jpg already exists
    

    So you must do each piece in two steps:

    rename 's/JPG/jpgx/' /mnt/part/*
    rename 's/jpgx/jpg/' /mnt/part/*
    rename 's/DSC/dscx/' /mnt/part/*
    rename 's/dscx/dsc/' /mnt/part/*
    

    Obvious once you see it, I suppose…

    See the comments for a better way:

    rename 'y/A-Z/a-z/' *JPG
    
  • Sony NP-BX1 Battery Test Fixture

    The Sony HDR-AS30V “action camera” uses NP-BX1 lithium batteries (3.7 V @ 1.24 A·h = 4.6 W·h) that are, of course, a completely different size and shape than any other lithium battery on the planet.

    So.

    Tweaking a few dimensions in the Canon NB-6L source code, tinkering with the layout of the contact pins, and shazam Yet Another 3D Printed Battery Test Fixture:

    NP-BX1 Holder - show layout
    NP-BX1 Holder – show layout

    It builds nicely, although the contact pin tunnels are a bit too close to the top of the case:

    Sony NP-BX1 Holder - on platform
    Sony NP-BX1 Holder – on platform

    After reaming out the contact pin holes to the proper diameters & depths, then gluing the plugs in place, it works just as you’d expect:

    Sony NP-BX1 battery holder
    Sony NP-BX1 battery holder

    It’s worth noting that the Wasabi charger accepts the batteries upside-down, with the conspicuous chevron against the charger body. It’s definitely not the way all the other chargers work. The keying recesses on the battery (corresponding to the blocks in the solid model) lie along the bottom edge of the contact surface, so flipping the battery over means they’ll hold it in place, but … oh, well.

    That grotty Powerpole connector last saw use in some random benchtop lashup. At some point I’ll be forced to start making more of those.

    The OpenSCAD source code:

    // Holder for Sony NP-BX1 Li-Ion battery
    // Ed Nisley KE4ZNU January 2013
    
    include <MCAD/boxes.scad>
    
    // Layout options
    
    Layout = "Show";					//  Show Build Fit Case Lid Pins Plugs AlignPins
    
    //- Extrusion parameters - must match reality!
    //  Print with +2 shells and 3 solid layers
    
    ThreadThick = 0.20;
    ThreadWidth = 0.40;
    
    HoleWindage = 0.2;
    
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    
    Protrusion = 0.1;			// make holes end cleanly
    
    inch = 25.4;
    
    BuildOffset = 3.0;			// clearance for build layout
    
    Gap = 8.0;					// separation for Fit parts
    
    //- Battery dimensions - rationalized from several samples
    //  Coordinate origin at battery corner by contact plates on bottom surface
    
    BatteryLength = 43.0;
    BatteryWidth = 30.0;
    BatteryThick =  9.5;
    
    ContactWidth = 2.90;
    ContactLength = 4.30;
    ContactRecess = 0.90;
    
    ContactOC = 10.0;			// center-to-center across contact face
    ContactOffset = 6.20;		// offset from battery edge
    ContactHeight = 6.30;		// offset from battery bottom plane
    
    AlignThick = 2.75;			// alignment recesses on contact face
    AlignDepth = 1.70;			// into face
    AlignWidth1 = 3.70;			// across face at contacts
    AlignWidth2 = 3.60;			//  ... other edge
    
    //- Pin dimensions
    
    PinTipDia = 1.6;
    PinTipLength = 10.0;
    
    PinTaperLength = 2.3;
    
    PinShaftDia = 2.4;
    PinShaftLength = 6.8;
    
    PinFerruleDia = 3.1;
    PinFerruleLength = 2.0;
    
    PinLength = PinTipLength + PinTaperLength + PinShaftLength + PinFerruleLength;
    
    ExtendRelax = 1.5 + ContactRecess;		// pin extension when no battery is present
    ExtendOvertravel = 1.0;					//  ... beyond engaged position
    
    //- Spring dimensions
    
    SpringDia = 3.1;						// coil OD
    SpringMax = 9.3;
    SpringLength = SpringMax - 0.5;			// slightly compressed
    SpringMin = 4.5;
    
    SpringPlugOD = IntegerMultiple(5.0,ThreadWidth);		// plug retaining the spring
    SpringPlugID = 2.0;
    SpringPlugLength = IntegerMultiple(4.0,ThreadWidth);
    SpringPlugSides = 3*4;
    
    SpringTravel = ExtendRelax + ExtendOvertravel;
    
    //- Holder dimensions
    
    GuideRadius = ThreadWidth;			// friction fit ridges
    GuideOffset = 7;					// from compartment corners
    WallThick = 4*ThreadWidth;			// holder sidewalls
    
    BaseThick = 6*ThreadThick;			// bottom of holder to bottom of battery
    TopThick = 6*ThreadThick;			// top of battery to top of holder
    
    ThumbRadius = 10.0;			// thumb opening at end of battery
    
    CornerRadius = 3*ThreadThick;			// nice corner rounding
    
    CaseLength = SpringPlugLength + SpringLength + PinLength - ExtendRelax
    			+ BatteryLength + GuideRadius + WallThick;
    CaseWidth = 2*WallThick + 2*GuideRadius + BatteryWidth;
    CaseThick = BaseThick + BatteryThick + TopThick;
    
    AlignPinOD = 1.75;			// lid alignment pins - filament snippets
    AlignPinLength = 5.0;
    AlignPinInset = 7.0;
    AlignPinOffset = -3.75;		//  from centerline - choose to miss contact pins
    
    //- XY origin at front left battery corner, Z on platform below that
    
    CaseLengthOffset = -(SpringPlugLength + SpringLength + PinLength - ExtendRelax);
    CaseWidthOffset = -(WallThick + GuideRadius);
    CaseThickOffset = BaseThick;
    
    LidLength = ExtendRelax - CaseLengthOffset;
    
    echo(str("Contact pin tip dia: ",PinTipDia));
    echo(str("Drill depth to taper end: ",
    		 (SpringPlugLength + SpringLength + PinFerruleLength + PinShaftLength + PinTaperLength),
    		 " -- Dia: ",PinShaftDia));
    echo(str("            to ferrule end: ",
    		  (SpringPlugLength + SpringLength + PinFerruleLength),
    		 " -- Dia: ",PinFerruleDia));
    echo(str("            to plug end: ",SpringPlugLength,
    		 " -- Dia: ",SpringPlugOD));
    
    //----------------------
    // Useful routines
    
    module PolyCyl(Dia,Height,ForceSides=0) {			// based on nophead's polyholes
    
      Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
    
      FixDia = Dia / cos(180/Sides);
    
      cylinder(r=(FixDia + HoleWindage)/2,
               h=Height,
    	   $fn=Sides);
    }
    
    module ShowPegGrid(Space = 10.0,Size = 1.0) {
    
      Range = floor(50 / Space);
    
    	for (x=[-Range:Range])
    	  for (y=[-Range:Range])
    		translate([x*Space,y*Space,Size/2])
    		  %cube(Size,center=true);
    
    }
    
    //-------------------
    
    //-- Guides for tighter friction fit
    
    module Guides() {
      	  translate([GuideOffset,-GuideRadius,CaseThickOffset])
    		PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4);
    	  translate([GuideOffset,(BatteryWidth + GuideRadius),CaseThickOffset])
    		PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4);
    	  translate([(BatteryLength - GuideOffset),-GuideRadius,CaseThickOffset])
    		PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4);
    	  translate([(BatteryLength - GuideOffset),(BatteryWidth + GuideRadius),CaseThickOffset])
    		PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4);
    	  translate([(BatteryLength + GuideRadius),GuideOffset/2,CaseThickOffset])
    		PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4);
    	  translate([(BatteryLength + GuideRadius),(BatteryWidth - GuideOffset/2),CaseThickOffset])
    		PolyCyl(2*GuideRadius,(BatteryThick - Protrusion),4);
    
    }
    
    //-- Contact pins (holes therefore)
    
    module PinShape() {
    
      union() {
    	cylinder(r=(PinTipDia + HoleWindage)/2,h=(PinTipLength + Protrusion),$fn=6);
    
    	translate([0,0,PinTipLength])
    	  cylinder(r=(PinShaftDia + HoleWindage)/2,
    			   h=(PinTaperLength + PinShaftLength + Protrusion),$fn=6);
    
    	translate([0,0,(PinLength - PinFerruleLength)])
    	  cylinder(r=(PinFerruleDia + HoleWindage)/2,
    				h=(PinFerruleLength + Protrusion),$fn=6);
    
    	translate([0,0,(PinLength)])
    	  cylinder(r=(SpringDia + HoleWindage)/2,
    				h=(SpringLength + Protrusion),$fn=6);
    
    	translate([0,0,(PinLength + SpringLength - HoleWindage)])	// windage for hole length
    	  cylinder(r=(SpringPlugOD + HoleWindage)/2,h=3*SpringPlugLength,$fn=SpringPlugSides);
    
    //	  translate([0,0,(PinLength + SpringLength + SpringPlugLength)])
    //	  cylinder(r=(SpringPlugOD + HoleWindage)/2,h=2*SpringPlugLength,$fn=SpringPlugSides);	// extend hole
      }
    
    }
    
    module PinAssembly() {
    
      translate([ExtendRelax,ContactOffset,CaseThickOffset + ContactHeight]) {
    	rotate([0,270,0]) {
    	  PinShape();												// pins
    	  translate([0,(1*ContactOC),0])
    		PinShape();
    	}
      }
    
    }
    
    //-- Alignment pins
    
    module AlignPins() {
    
    	for (x=[-1,1])
    		translate([x*(LidLength - 2*AlignPinInset)/2,AlignPinOffset,0])
    			rotate(45)
    			PolyCyl(AlignPinOD,AlignPinLength);
    }
    
    //-- Case with origin at battery corner
    
    module Case() {
    
      difference() {
    
    	union() {
    
    	  difference() {
    		translate([(CaseLength/2 + CaseLengthOffset),
    				  (CaseWidth/2 + CaseWidthOffset),
    				  (CaseThick/2)])
    		  roundedBox([CaseLength,CaseWidth,CaseThick],CornerRadius); 	// basic case shape
    
    		translate([-ExtendOvertravel,-GuideRadius,CaseThickOffset])
    		  cube([(BatteryLength + GuideRadius + ExtendOvertravel),
    				(BatteryWidth + 2* GuideRadius),
    				(BatteryThick + Protrusion)]);						// battery space
    
    	  }
    
    	  Guides();
    
    	  translate([-ExtendOvertravel,-GuideRadius,BaseThick])
    		cube([(AlignDepth + ExtendOvertravel),
    			  (AlignWidth1 + GuideRadius),
    			  AlignThick]);											// alignment blocks
    	  translate([-ExtendOvertravel,
    				 (BatteryWidth - AlignWidth2),
    				 BaseThick])
    		cube([(AlignDepth + ExtendOvertravel),
    			  (AlignWidth2 + GuideRadius),
    			  AlignThick]);
    
    	}
    
    	translate([(-ExtendOvertravel),
    			   (CaseWidthOffset - Protrusion),
    			   (CaseThickOffset + BatteryThick)])
    	  cube([CaseLength,
    		    (CaseWidth + 2*Protrusion),
    		    (TopThick + Protrusion)]);								// battery access
    
    	translate([(CaseLengthOffset - Protrusion),
    			   (CaseWidthOffset - Protrusion),
    			   (CaseThickOffset + BatteryThick)])
    	  cube([(CaseLength + 2*Protrusion),
    		    (CaseWidth + 2*Protrusion),
    		    (TopThick + Protrusion)]);								// battery insertion allowance
    
    	translate([(BatteryLength - Protrusion),
    			    (CaseWidth/2 + CaseWidthOffset),
    			    (CaseThickOffset + ThumbRadius)])
    	  rotate([90,0,0])
    		rotate([0,90,0])
    		  cylinder(r=ThumbRadius,
    				   h=(WallThick + GuideRadius + 2*Protrusion),
    				   $fn=22);											// remove thumb notch
    
    	PinAssembly();
    
    	translate([-LidLength/2,BatteryWidth/2,CaseThick - TopThick - (AlignPinLength - TopThick/2)])
    		AlignPins();
      }
    
    }
    
    module Lid() {
    
      difference() {
    	translate([0,0,(CaseThick/2 - BaseThick - BatteryThick)])
    	  roundedBox([LidLength,
    				 CaseWidth,CaseThick],CornerRadius);
    
    	translate([0,0,-(CaseThick/2)])
    	  cube([(LidLength + 2*Protrusion),
    		    (CaseWidth + 2*Protrusion),
    		    (CaseThick)],center=true);
    
    	translate([-ExtendRelax,0,-(AlignPinLength - TopThick/2)])
    		AlignPins();
      }
    
    }
    
    module PlugShape() {
    
      difference() {
    	cylinder(r=SpringPlugOD/2,h=SpringPlugLength,$fn=SpringPlugSides);
    	translate([0,0,-Protrusion])
    	  PolyCyl(SpringPlugID,(SpringPlugLength + 2*Protrusion),SpringPlugSides);
      }
    }
    
    module Plugs() {
      translate([0,ContactOC,0])
    	PlugShape();
      translate([0,-ContactOC,0])
    	PlugShape();
    }
    
    //-------------------
    // Build it!
    
    ShowPegGrid();
    
    if (Layout == "Case")
      Case();
    
    if (Layout == "Lid")
      Lid();
    
    if (Layout == "Plugs")
    	for (i=[-1:1])
    		translate([i*1.5*SpringPlugOD,0,0])
    			Plugs();
    
    if (Layout == "Pins")
      PinShape();
    
    if (Layout == "AlignPins")
      AlignPins();
    
    if (Layout == "Show") {								// reveal pin assembly
      difference() {
    	Case();
    
    	translate([(CaseLengthOffset - Protrusion),
    			   (CaseWidthOffset - Protrusion + WallThick + ContactOffset + ContactOC),
    			   (BaseThick + ContactHeight)])
    	  cube([(-CaseLengthOffset + Protrusion),
    			 (CaseWidth + 2*Protrusion),
    			 CaseThick + BaseThick - ContactHeight + Protrusion]);
    
    	translate([(CaseLengthOffset - Protrusion),
    			   (CaseWidthOffset - Protrusion),
    			   -Protrusion])
    	  cube([(-CaseLengthOffset + Protrusion),
    			 (WallThick + GuideRadius + ContactOffset + Protrusion),
    			 CaseThick]);
      }
    
      translate([ExtendRelax,ContactOffset,(CaseThickOffset + ContactHeight)]) {	// pins
    	rotate([0,270,0]) {
    	  %PinShape();
    //	  translate([0,(2*ContactOC),0])
    //		%PinShape();
    	}
      }
    
      translate([CaseLengthOffset,ContactOffset,(CaseThickOffset + ContactHeight)])
    	rotate([0,90,0])
    	  PlugShape();
    }
    
    if (Layout == "Build") {
      translate([-(CaseLength/2 + CaseLengthOffset),-(CaseWidthOffset - BuildOffset),0])
    	Case();
      translate([CaseWidth/2,(CaseLengthOffset/2 - BuildOffset),0])
    	rotate([0,0,90])
    	  Lid();
      for (i=[-1:1])
    	translate([CaseLengthOffset/2 + i*1.5*SpringPlugOD,-CaseWidth/2,0])
    		Plugs();
    }
    
    if (Layout == "Fit") {
      Case();
      translate([(-LidLength/2 + ExtendRelax),
    			(CaseWidth/2 + CaseWidthOffset),
    			(BaseThick + BatteryThick + Gap)])
    	  Lid();
      translate([ExtendRelax,ContactOffset,CaseThickOffset + ContactHeight]) {	// pins
    	rotate([0,270,0]) {
    	  %PinShape();
    	  translate([0,(1*ContactOC),0])
    		%PinShape();
    	}
      }
    
      translate([CaseLengthOffset,
    			(ContactOffset + ContactOC),
    			(CaseThickOffset + ContactHeight)])
      rotate([0,90,0])
    	Plugs();
    
      translate([-LidLength/2,BatteryWidth/2,CaseThick])
    #	AlignPins();
    
    }
    
  • Canon vs. Wasabi NB-6LH Batteries

    Our Larval Engineer reported that her camera, which is my old Casio pocket camera, has begun fading away, so we’re getting her a shiny new camera of her very own. Being a doting father, I picked up a pair of Wasabi NB-6L batteries (and a charger, it not costing much more for the package) so she’s never without electrons, and did the usual rundown test on all three batteries:

    Canon NB-6L - 2014 OEM vs Wasabi
    Canon NB-6L – 2014 OEM vs Wasabi

    Fairly obviously, the Wasabi batteries aren’t first tier products, but they’re definitely better than that bottom-dollar crap from eBay.

  • Unsealed Camera Box

    Used to be, back in the day, that when you got a box full of shiny new electronics, it bore stickers: “Do not accept if seal is broken” or “Factory sealed” or “Genuine product” or something like that. When you slit the seal, you had some confidence that the last person to look in the box sat at the end of their production line; I’ll grant you that counterfeit stickers have become cheap & readily available, but it’s the principle of the thing.

    Nowadays, a shiny new Canon camera arrives in a box with a tab tucked into a slit:

    Canon Camera box - unopened and unsealed
    Canon Camera box – unopened and unsealed

    The box looked unopened and everything inside seemed in order, but … even though I’d seen this before on other cameras, it’s still disconcerting.

    I’m unsure of the story about laminate flooring in the camera box.

  • Monthly Image: Ice Crystals

    The recent bout of single-digit (Fahrenheit!) temperatures produced ice crystals on some of our leakier windows:

    Window Ice Feathers
    Window Ice Feathers
    Window Ice Spines
    Window Ice Spines
    Window Ice Feathers
    Window Ice Feathers
    Window Ice Feathers
    Window Ice Feathers

    The windows came with the house, date back to 1955, do have storm windows, and we’ll grant the next owners the joy and delight of replacing them…