text:
package com.clockwork.util;

import com.clockwork.math.ColorRGBA;
import com.clockwork.math.Quaternion;
import com.clockwork.math.Vector2f;
import com.clockwork.math.Vector3f;
import com.clockwork.math.Vector4f;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * BufferUtils is a helper class for generating nio buffers from
 * CW data classes such as Vectors and ColorRGBA.
 *
 *
 * @version $Id: BufferUtils.java,v 1.16 2007/10/29 16:56:18 nca Exp $
 */
public final class BufferUtils {

    private static boolean trackDirectMemory = false;
    private static ReferenceQueue<Buffer> removeCollected = new ReferenceQueue<Buffer>();
    private static ConcurrentHashMap<BufferInfo, BufferInfo> trackedBuffers = new ConcurrentHashMap<BufferInfo, BufferInfo>();
    static ClearReferences cleanupthread;

    /**
     * Set it to true if you want to enable direct memory tracking for debugging purpose.
     * Default is false.
     * To print direct memory usage use BufferUtils.printCurrentDirectMemory(StringBuilder store);
     * @param enabled
     */
    public static void setTrackDirectMemoryEnabled(boolean enabled) {
        trackDirectMemory = enabled;
    }

    /**
     * Creates a clone of the given buffer. The clone's capacity is
     * equal to the given buffer's limit.
     *
     * @param buf The buffer to clone
     * @return The cloned buffer
     */
    public static Buffer clone(Buffer buf) {
        if (buf instanceof FloatBuffer) {
            return clone((FloatBuffer) buf);
        } else if (buf instanceof ShortBuffer) {
            return clone((ShortBuffer) buf);
        } else if (buf instanceof ByteBuffer) {
            return clone((ByteBuffer) buf);
        } else if (buf instanceof IntBuffer) {
            return clone((IntBuffer) buf);
        } else if (buf instanceof DoubleBuffer) {
            return clone((DoubleBuffer) buf);
        } else {
            throw new UnsupportedOperationException();
        }
    }

    private static void onBufferAllocated(Buffer buffer) {
        /**
         * StackTraceElement[] stackTrace = new Throwable().getStackTrace(); int
         * initialIndex = 0;
         *
         * for (int i = 0; i < stackTrace.length; i++){ if
         * (!stackTrace[i].getClassName().equals(BufferUtils.class.getName())){
         * initialIndex = i; break; } }
         *
         * int allocated = buffer.capacity(); int size = 0;
         *
         * if (buffer instanceof FloatBuffer){ size = 4; }else if (buffer
         * instanceof ShortBuffer){ size = 2; }else if (buffer instanceof
         * ByteBuffer){ size = 1; }else if (buffer instanceof IntBuffer){ size =
         * 4; }else if (buffer instanceof DoubleBuffer){ size = 8; }
         *
         * allocated *= size;
         *
         * for (int i = initialIndex; i < stackTrace.length; i++){
         * StackTraceElement element = stackTrace[i]; if
         * (element.getClassName().startsWith("java")){ break; }
         *
         * try { Class clazz = Class.forName(element.getClassName()); if (i ==
         * initialIndex){
         * System.out.println(clazz.getSimpleName()+"."+element.getMethodName
         * ()+"():" + element.getLineNumber() + " allocated " + allocated);
         * }else{ System.out.println(" at " +
         * clazz.getSimpleName()+"."+element.getMethodName()+"()"); } } catch
         * (ClassNotFoundException ex) { } }
         */
        if (BufferUtils.trackDirectMemory) {

            if (BufferUtils.cleanupthread == null) {
                BufferUtils.cleanupthread = new ClearReferences();
                BufferUtils.cleanupthread.start();
            }
            if (buffer instanceof ByteBuffer) {
                BufferInfo info = new BufferInfo(ByteBuffer.class, buffer.capacity(), buffer, BufferUtils.removeCollected);
                BufferUtils.trackedBuffers.put(info, info);
            } else if (buffer instanceof FloatBuffer) {
                BufferInfo info = new BufferInfo(FloatBuffer.class, buffer.capacity() * 4, buffer, BufferUtils.removeCollected);
                BufferUtils.trackedBuffers.put(info, info);
            } else if (buffer instanceof IntBuffer) {
                BufferInfo info = new BufferInfo(IntBuffer.class, buffer.capacity() * 4, buffer, BufferUtils.removeCollected);
                BufferUtils.trackedBuffers.put(info, info);
            } else if (buffer instanceof ShortBuffer) {
                BufferInfo info = new BufferInfo(ShortBuffer.class, buffer.capacity() * 2, buffer, BufferUtils.removeCollected);
                BufferUtils.trackedBuffers.put(info, info);
            } else if (buffer instanceof DoubleBuffer) {
                BufferInfo info = new BufferInfo(DoubleBuffer.class, buffer.capacity() * 8, buffer, BufferUtils.removeCollected);
                BufferUtils.trackedBuffers.put(info, info);
            }

        }
    }

    /**
     * Generate a new FloatBuffer using the given array of Vector3f objects.
     * The FloatBuffer will be 3 * data.length long and contain the vector data
     * as data[0].x, data[0].y, data[0].z, data[1].x... etc.
     *
     * @param data array of Vector3f objects to place into a new FloatBuffer
     */
    public static FloatBuffer createFloatBuffer(Vector3f... data) {
        if (data == null) {
            return null;
        }
        FloatBuffer buff = createFloatBuffer(3 * data.length);
        for (Vector3f element : data) {
            if (element != null) {
                buff.put(element.x).put(element.y).put(element.z);
            } else {
                buff.put(0).put(0).put(0);
            }
        }
        buff.flip();
        return buff;
    }

    /**
     * Generate a new FloatBuffer using the given array of Quaternion objects.
     * The FloatBuffer will be 4 * data.length long and contain the vector data.
     *
     * @param data array of Quaternion objects to place into a new FloatBuffer
     */
    public static FloatBuffer createFloatBuffer(Quaternion... data) {
        if (data == null) {
            return null;
        }
        FloatBuffer buff = createFloatBuffer(4 * data.length);
        for (Quaternion element : data) {
            if (element != null) {
                buff.put(element.getX()).put(element.getY()).put(element.getZ()).put(element.getW());
            } else {
                buff.put(0).put(0).put(0).put(0);
            }
        }
        buff.flip();
        return buff;
    }

    /**
     * Generate a new FloatBuffer using the given array of Vector4 objects.
     * The FloatBuffer will be 4 * data.length long and contain the vector data.
     *
     * @param data array of Vector4 objects to place into a new FloatBuffer
     */
    public static FloatBuffer createFloatBuffer(Vector4f... data) {
        if (data == null) {
            return null;
        }
        FloatBuffer buff = createFloatBuffer(4 * data.length);
        for (int x = 0; x < data.length; x++) {
            if (data[x] != null) {
                buff.put(data[x].getX()).put(data[x].getY()).put(data[x].getZ()).put(data[x].getW());
            } else {
                buff.put(0).put(0).put(0).put(0);
            }
        }
        buff.flip();
        return buff;
    }

    /**
     * Generate a new FloatBuffer using the given array of float primitives.
     * @param data array of float primitives to place into a new FloatBuffer
     */
    public static FloatBuffer createFloatBuffer(float... data) {
        if (data == null) {
            return null;
        }
        FloatBuffer buff = createFloatBuffer(data.length);
        buff.clear();
        buff.put(data);
        buff.flip();
        return buff;
    }

    /**
     * Create a new FloatBuffer of an appropriate size to hold the specified
     * number of Vector3f object data.
     *
     * @param vertices
     *            number of vertices that need to be held by the newly created
     *            buffer
     * @return the requested new FloatBuffer
     */
    public static FloatBuffer createVector3Buffer(int vertices) {
        FloatBuffer vBuff = createFloatBuffer(3 * vertices);
        return vBuff;
    }

    /**
     * Create a new FloatBuffer of an appropriate size to hold the specified
     * number of Vector3f object data only if the given buffer if not already
     * the right size.
     *
     * @param buf
     *            the buffer to first check and rewind
     * @param vertices
     *            number of vertices that need to be held by the newly created
     *            buffer
     * @return the requested new FloatBuffer
     */
    public static FloatBuffer createVector3Buffer(FloatBuffer buf, int vertices) {
        if (buf != null && buf.limit() == 3 * vertices) {
            buf.rewind();
            return buf;
        }

        return createFloatBuffer(3 * vertices);
    }

    /**
     * Sets the data contained in the given color into the FloatBuffer at the
     * specified index.
     *
     * @param color
     *            the data to insert
     * @param buf
     *            the buffer to insert into
     * @param index
     *            the postion to place the data; in terms of colors not floats
     */
    public static void setInBuffer(ColorRGBA color, FloatBuffer buf,
            int index) {
        buf.position(index * 4);
        buf.put(color.r);
        buf.put(color.g);
        buf.put(color.b);
        buf.put(color.a);
    }

    /**
     * Sets the data contained in the given quaternion into the FloatBuffer at the
     * specified index.
     *
     * @param quat
     *            the Quaternion} to insert
     * @param buf
     *            the buffer to insert into
     * @param index
     *            the postion to place the data; in terms of quaternions not floats
     */
    public static void setInBuffer(Quaternion quat, FloatBuffer buf,
            int index) {
        buf.position(index * 4);
        buf.put(quat.getX());
        buf.put(quat.getY());
        buf.put(quat.getZ());
        buf.put(quat.getW());
    }

    /**
     * Sets the data contained in the given vector4 into the FloatBuffer at the
     * specified index.
     *
     * @param vec
     *            the Vector4f} to insert
     * @param buf
     *            the buffer to insert into
     * @param index
     *            the postion to place the data; in terms of vector4 not floats
     */
    public static void setInBuffer(Vector4f vec, FloatBuffer buf,
            int index) {
        buf.position(index * 4);
        buf.put(vec.getX());
        buf.put(vec.getY());
        buf.put(vec.getZ());
        buf.put(vec.getW());
    }

    /**
     * Sets the data contained in the given Vector3F into the FloatBuffer at the
     * specified index.
     *
     * @param vector
     *            the data to insert
     * @param buf
     *            the buffer to insert into
     * @param index
     *            the postion to place the data; in terms of vectors not floats
     */
    public static void setInBuffer(Vector3f vector, FloatBuffer buf, int index) {
        if (buf == null) {
            return;
        }
        if (vector == null) {
            buf.put(index * 3, 0);
            buf.put((index * 3) + 1, 0);
            buf.put((index * 3) + 2, 0);
        } else {
            buf.put(index * 3, vector.x);
            buf.put((index * 3) + 1, vector.y);
            buf.put((index * 3) + 2, vector.z);
        }
    }

    /**
     * Updates the values of the given vector from the specified buffer at the
     * index provided.
     *
     * @param vector
     *            the vector to set data on
     * @param buf
     *            the buffer to read from
     * @param index
     *            the position (in terms of vectors, not floats) to read from
     *            the buf
     */
    public static void populateFromBuffer(Vector3f vector, FloatBuffer buf, int index) {
        vector.x = buf.get(index * 3);
        vector.y = buf.get(index * 3 + 1);
        vector.z = buf.get(index * 3 + 2);
    }

    /**
     * Generates a Vector3f array from the given FloatBuffer.
     *
     * @param buff
     *            the FloatBuffer to read from
     * @return a newly generated array of Vector3f objects
     */
    public static Vector3f[] getVector3Array(FloatBuffer buff) {
        buff.clear();
        Vector3f[] verts = new Vector3f[buff.limit() / 3];
        for (int x = 0; x < verts.length; x++) {
            Vector3f v = new Vector3f(buff.get(), buff.get(), buff.get());
            verts[x] = v;
        }
        return verts;
    }

    /**
     * Copies a Vector3f from one position in the buffer to another. The index
     * values are in terms of vector number (eg, vector number 0 is postions 0-2
     * in the FloatBuffer.)
     *
     * @param buf
     *            the buffer to copy from/to
     * @param fromPos
     *            the index of the vector to copy
     * @param toPos
     *            the index to copy the vector to
     */
    public static void copyInternalVector3(FloatBuffer buf, int fromPos, int toPos) {
        copyInternal(buf, fromPos * 3, toPos * 3, 3);
    }

    /**
     * Normalize a Vector3f in-buffer.
     *
     * @param buf
     *            the buffer to find the Vector3f within
     * @param index
     *            the position (in terms of vectors, not floats) of the vector
     *            to normalize
     */
    public static void normalizeVector3(FloatBuffer buf, int index) {
        TempVars vars = TempVars.get();
        Vector3f tempVec3 = vars.vect1;
        populateFromBuffer(tempVec3, buf, index);
        tempVec3.normalizeLocal();
        setInBuffer(tempVec3, buf, index);
        vars.release();
    }

    /**
     * Add to a Vector3f in-buffer.
     *
     * @param toAdd
     *            the vector to add from
     * @param buf
     *            the buffer to find the Vector3f within
     * @param index
     *            the position (in terms of vectors, not floats) of the vector
     *            to add to
     */
    public static void addInBuffer(Vector3f toAdd, FloatBuffer buf, int index) {
        TempVars vars = TempVars.get();
        Vector3f tempVec3 = vars.vect1;
        populateFromBuffer(tempVec3, buf, index);
        tempVec3.addLocal(toAdd);
        setInBuffer(tempVec3, buf, index);
        vars.release();
    }

    /**
     * Multiply and store a Vector3f in-buffer.
     *
     * @param toMult
     *            the vector to multiply against
     * @param buf
     *            the buffer to find the Vector3f within
     * @param index
     *            the position (in terms of vectors, not floats) of the vector
     *            to multiply
     */
    public static void multInBuffer(Vector3f toMult, FloatBuffer buf, int index) {
        TempVars vars = TempVars.get();
        Vector3f tempVec3 = vars.vect1;
        populateFromBuffer(tempVec3, buf, index);
        tempVec3.multLocal(toMult);
        setInBuffer(tempVec3, buf, index);
        vars.release();
    }

    /**
     * Checks to see if the given Vector3f is equals to the data stored in the
     * buffer at the given data index.
     *
     * @param check
     *            the vector to check against - null will return false.
     * @param buf
     *            the buffer to compare data with
     * @param index
     *            the position (in terms of vectors, not floats) of the vector
     *            in the buffer to check against
     * @return true if the data is equivalent, otherwise false.
     */
    public static boolean equals(Vector3f check, FloatBuffer buf, int index) {
        TempVars vars = TempVars.get();
        Vector3f tempVec3 = vars.vect1;
        populateFromBuffer(tempVec3, buf, index);
        boolean eq = tempVec3.equals(check);
        vars.release();
        return eq;
    }

    // // -- VECTOR2F METHODS -- ////
    /**
     * Generate a new FloatBuffer using the given array of Vector2f objects.
     * The FloatBuffer will be 2 * data.length long and contain the vector data
     * as data[0].x, data[0].y, data[1].x... etc.
     *
     * @param data array of Vector2f objects to place into a new FloatBuffer
     */
    public static FloatBuffer createFloatBuffer(Vector2f... data) {
        if (data == null) {
            return null;
        }
        FloatBuffer buff = createFloatBuffer(2 * data.length);
        for (Vector2f element : data) {
            if (element != null) {
                buff.put(element.x).put(element.y);
            } else {
                buff.put(0).put(0);
            }
        }
        buff.flip();
        return buff;
    }

    /**
     * Create a new FloatBuffer of an appropriate size to hold the specified
     * number of Vector2f object data.
     *
     * @param vertices
     *            number of vertices that need to be held by the newly created
     *            buffer
     * @return the requested new FloatBuffer
     */
    public static FloatBuffer createVector2Buffer(int vertices) {
        FloatBuffer vBuff = createFloatBuffer(2 * vertices);
        return vBuff;
    }

    /**
     * Create a new FloatBuffer of an appropriate size to hold the specified
     * number of Vector2f object data only if the given buffer if not already
     * the right size.
     *
     * @param buf
     *            the buffer to first check and rewind
     * @param vertices
     *            number of vertices that need to be held by the newly created
     *            buffer
     * @return the requested new FloatBuffer
     */
    public static FloatBuffer createVector2Buffer(FloatBuffer buf, int vertices) {
        if (buf != null && buf.limit() == 2 * vertices) {
            buf.rewind();
            return buf;
        }

        return createFloatBuffer(2 * vertices);
    }

    /**
     * Sets the data contained in the given Vector2F into the FloatBuffer at the
     * specified index.
     *
     * @param vector
     *            the data to insert
     * @param buf
     *            the buffer to insert into
     * @param index
     *            the postion to place the data; in terms of vectors not floats
     */
    public static void setInBuffer(Vector2f vector, FloatBuffer buf, int index) {
        buf.put(index * 2, vector.x);
        buf.put((index * 2) + 1, vector.y);
    }

    /**
     * Updates the values of the given vector from the specified buffer at the
     * index provided.
     *
     * @param vector
     *            the vector to set data on
     * @param buf
     *            the buffer to read from
     * @param index
     *            the position (in terms of vectors, not floats) to read from
     *            the buf
     */
    public static void populateFromBuffer(Vector2f vector, FloatBuffer buf, int index) {
        vector.x = buf.get(index * 2);
        vector.y = buf.get(index * 2 + 1);
    }

    /**
     * Generates a Vector2f array from the given FloatBuffer.
     *
     * @param buff
     *            the FloatBuffer to read from
     * @return a newly generated array of Vector2f objects
     */
    public static Vector2f[] getVector2Array(FloatBuffer buff) {
        buff.clear();
        Vector2f[] verts = new Vector2f[buff.limit() / 2];
        for (int x = 0; x < verts.length; x++) {
            Vector2f v = new Vector2f(buff.get(), buff.get());
            verts[x] = v;
        }
        return verts;
    }

    /**
     * Copies a Vector2f from one position in the buffer to another. The index
     * values are in terms of vector number (eg, vector number 0 is postions 0-1
     * in the FloatBuffer.)
     *
     * @param buf
     *            the buffer to copy from/to
     * @param fromPos
     *            the index of the vector to copy
     * @param toPos
     *            the index to copy the vector to
     */
    public static void copyInternalVector2(FloatBuffer buf, int fromPos, int toPos) {
        copyInternal(buf, fromPos * 2, toPos * 2, 2);
    }

    /**
     * Normalize a Vector2f in-buffer.
     *
     * @param buf
     *            the buffer to find the Vector2f within
     * @param index
     *            the position (in terms of vectors, not floats) of the vector
     *            to normalize
     */
    public static void normalizeVector2(FloatBuffer buf, int index) {
        TempVars vars = TempVars.get();
        Vector2f tempVec2 = vars.vect2d;
        populateFromBuffer(tempVec2, buf, index);
        tempVec2.normalizeLocal();
        setInBuffer(tempVec2, buf, index);
        vars.release();
    }

    /**
     * Add to a Vector2f in-buffer.
     *
     * @param toAdd
     *            the vector to add from
     * @param buf
     *            the buffer to find the Vector2f within
     * @param index
     *            the position (in terms of vectors, not floats) of the vector
     *            to add to
     */
    public static void addInBuffer(Vector2f toAdd, FloatBuffer buf, int index) {
        TempVars vars = TempVars.get();
        Vector2f tempVec2 = vars.vect2d;
        populateFromBuffer(tempVec2, buf, index);
        tempVec2.addLocal(toAdd);
        setInBuffer(tempVec2, buf, index);
        vars.release();
    }

    /**
     * Multiply and store a Vector2f in-buffer.
     *
     * @param toMult
     *            the vector to multiply against
     * @param buf
     *            the buffer to find the Vector2f within
     * @param index
     *            the position (in terms of vectors, not floats) of the vector
     *            to multiply
     */
    public static void multInBuffer(Vector2f toMult, FloatBuffer buf, int index) {
        TempVars vars = TempVars.get();
        Vector2f tempVec2 = vars.vect2d;
        populateFromBuffer(tempVec2, buf, index);
        tempVec2.multLocal(toMult);
        setInBuffer(tempVec2, buf, index);
        vars.release();
    }

    /**
     * Checks to see if the given Vector2f is equals to the data stored in the
     * buffer at the given data index.
     *
     * @param check
     *            the vector to check against - null will return false.
     * @param buf
     *            the buffer to compare data with
     * @param index
     *            the position (in terms of vectors, not floats) of the vector
     *            in the buffer to check against
     * @return true if the data is equivalent, otherwise false.
     */
    public static boolean equals(Vector2f check, FloatBuffer buf, int index) {
        TempVars vars = TempVars.get();
        Vector2f tempVec2 = vars.vect2d;
        populateFromBuffer(tempVec2, buf, index);
        boolean eq = tempVec2.equals(check);
        vars.release();
        return eq;
    }

    ////  -- INT METHODS -- ////
    /**
     * Generate a new IntBuffer using the given array of ints. The IntBuffer
     * will be data.length long and contain the int data as data[0], data[1]...
     * etc.
     *
     * @param data
     *            array of ints to place into a new IntBuffer
     */
    public static IntBuffer createIntBuffer(int... data) {
        if (data == null) {
            return null;
        }
        IntBuffer buff = createIntBuffer(data.length);
        buff.clear();
        buff.put(data);
        buff.flip();
        return buff;
    }

    /**
     * Create a new int[] array and populate it with the given IntBuffer's
     * contents.
     *
     * @param buff
     *            the IntBuffer to read from
     * @return a new int array populated from the IntBuffer
     */
    public static int[] getIntArray(IntBuffer buff) {
        if (buff == null) {
            return null;
        }
        buff.clear();
        int[] inds = new int[buff.limit()];
        for (int x = 0; x < inds.length; x++) {
            inds[x] = buff.get();
        }
        return inds;
    }

    /**
     * Create a new float[] array and populate it with the given FloatBuffer's
     * contents.
     *
     * @param buff
     *            the FloatBuffer to read from
     * @return a new float array populated from the FloatBuffer
     */
    public static float[] getFloatArray(FloatBuffer buff) {
        if (buff == null) {
            return null;
        }
        buff.clear();
        float[] inds = new float[buff.limit()];
        for (int x = 0; x < inds.length; x++) {
            inds[x] = buff.get();
        }
        return inds;
    }

    //// -- GENERAL DOUBLE ROUTINES -- ////
    /**
     * Create a new DoubleBuffer of the specified size.
     *
     * @param size
     *            required number of double to store.
     * @return the new DoubleBuffer
     */
    public static DoubleBuffer createDoubleBuffer(int size) {
        DoubleBuffer buf = ByteBuffer.allocateDirect(8 * size).order(ByteOrder.nativeOrder()).asDoubleBuffer();
        buf.clear();
        onBufferAllocated(buf);
        return buf;
    }

    /**
     * Create a new DoubleBuffer of an appropriate size to hold the specified
     * number of doubles only if the given buffer if not already the right size.
     *
     * @param buf
     *            the buffer to first check and rewind
     * @param size
     *            number of doubles that need to be held by the newly created
     *            buffer
     * @return the requested new DoubleBuffer
     */
    public static DoubleBuffer createDoubleBuffer(DoubleBuffer buf, int size) {
        if (buf != null && buf.limit() == size) {
            buf.rewind();
            return buf;
        }

        buf = createDoubleBuffer(size);
        return buf;
    }

    /**
     * Creates a new DoubleBuffer with the same contents as the given
     * DoubleBuffer. The new DoubleBuffer is seperate from the old one and
     * changes are not reflected across. If you want to reflect changes,
     * consider using Buffer.duplicate().
     *
     * @param buf
     *            the DoubleBuffer to copy
     * @return the copy
     */
    public static DoubleBuffer clone(DoubleBuffer buf) {
        if (buf == null) {
            return null;
        }
        buf.rewind();

        DoubleBuffer copy;
        if (isDirect(buf)) {
            copy = createDoubleBuffer(buf.limit());
        } else {
            copy = DoubleBuffer.allocate(buf.limit());
        }
        copy.put(buf);

        return copy;
    }

    //// -- GENERAL FLOAT ROUTINES -- ////
    /**
     * Create a new FloatBuffer of the specified size.
     *
     * @param size
     *            required number of floats to store.
     * @return the new FloatBuffer
     */
    public static FloatBuffer createFloatBuffer(int size) {
        FloatBuffer buf = ByteBuffer.allocateDirect(4 * size).order(ByteOrder.nativeOrder()).asFloatBuffer();
        buf.clear();
        onBufferAllocated(buf);
        return buf;
    }

    /**
     * Copies floats from one position in the buffer to another.
     *
     * @param buf
     *            the buffer to copy from/to
     * @param fromPos
     *            the starting point to copy from
     * @param toPos
     *            the starting point to copy to
     * @param length
     *            the number of floats to copy
     */
    public static void copyInternal(FloatBuffer buf, int fromPos, int toPos, int length) {
        float[] data = new float[length];
        buf.position(fromPos);
        buf.get(data);
        buf.position(toPos);
        buf.put(data);
    }

    /**
     * Creates a new FloatBuffer with the same contents as the given
     * FloatBuffer. The new FloatBuffer is seperate from the old one and changes
     * are not reflected across. If you want to reflect changes, consider using
     * Buffer.duplicate().
     *
     * @param buf
     *            the FloatBuffer to copy
     * @return the copy
     */
    public static FloatBuffer clone(FloatBuffer buf) {
        if (buf == null) {
            return null;
        }
        buf.rewind();

        FloatBuffer copy;
        if (isDirect(buf)) {
            copy = createFloatBuffer(buf.limit());
        } else {
            copy = FloatBuffer.allocate(buf.limit());
        }
        copy.put(buf);

        return copy;
    }

    //// -- GENERAL INT ROUTINES -- ////
    /**
     * Create a new IntBuffer of the specified size.
     *
     * @param size
     *            required number of ints to store.
     * @return the new IntBuffer
     */
    public static IntBuffer createIntBuffer(int size) {
        IntBuffer buf = ByteBuffer.allocateDirect(4 * size).order(ByteOrder.nativeOrder()).asIntBuffer();
        buf.clear();
        onBufferAllocated(buf);
        return buf;
    }

    /**
     * Create a new IntBuffer of an appropriate size to hold the specified
     * number of ints only if the given buffer if not already the right size.
     *
     * @param buf
     *            the buffer to first check and rewind
     * @param size
     *            number of ints that need to be held by the newly created
     *            buffer
     * @return the requested new IntBuffer
     */
    public static IntBuffer createIntBuffer(IntBuffer buf, int size) {
        if (buf != null && buf.limit() == size) {
            buf.rewind();
            return buf;
        }

        buf = createIntBuffer(size);
        return buf;
    }

    /**
     * Creates a new IntBuffer with the same contents as the given IntBuffer.
     * The new IntBuffer is seperate from the old one and changes are not
     * reflected across. If you want to reflect changes, consider using
     * Buffer.duplicate().
     *
     * @param buf
     *            the IntBuffer to copy
     * @return the copy
     */
    public static IntBuffer clone(IntBuffer buf) {
        if (buf == null) {
            return null;
        }
        buf.rewind();

        IntBuffer copy;
        if (isDirect(buf)) {
            copy = createIntBuffer(buf.limit());
        } else {
            copy = IntBuffer.allocate(buf.limit());
        }
        copy.put(buf);

        return copy;
    }

    //// -- GENERAL BYTE ROUTINES -- ////
    /**
     * Create a new ByteBuffer of the specified size.
     *
     * @param size
     *            required number of ints to store.
     * @return the new IntBuffer
     */
    public static ByteBuffer createByteBuffer(int size) {
        ByteBuffer buf = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
        buf.clear();
        onBufferAllocated(buf);
        return buf;
    }

    /**
     * Create a new ByteBuffer of an appropriate size to hold the specified
     * number of ints only if the given buffer if not already the right size.
     *
     * @param buf
     *            the buffer to first check and rewind
     * @param size
     *            number of bytes that need to be held by the newly created
     *            buffer
     * @return the requested new IntBuffer
     */
    public static ByteBuffer createByteBuffer(ByteBuffer buf, int size) {
        if (buf != null && buf.limit() == size) {
            buf.rewind();
            return buf;
        }

        buf = createByteBuffer(size);
        return buf;
    }

    public static ByteBuffer createByteBuffer(byte... data) {
        ByteBuffer bb = createByteBuffer(data.length);
        bb.put(data);
        bb.flip();
        return bb;
    }

    public static ByteBuffer createByteBuffer(String data) {
        byte[] bytes = data.getBytes();
        ByteBuffer bb = createByteBuffer(bytes.length);
        bb.put(bytes);
        bb.flip();
        return bb;
    }

    /**
     * Creates a new ByteBuffer with the same contents as the given ByteBuffer.
     * The new ByteBuffer is seperate from the old one and changes are not
     * reflected across. If you want to reflect changes, consider using
     * Buffer.duplicate().
     *
     * @param buf
     *            the ByteBuffer to copy
     * @return the copy
     */
    public static ByteBuffer clone(ByteBuffer buf) {
        if (buf == null) {
            return null;
        }
        buf.rewind();

        ByteBuffer copy;
        if (isDirect(buf)) {
            copy = createByteBuffer(buf.limit());
        } else {
            copy = ByteBuffer.allocate(buf.limit());
        }
        copy.put(buf);

        return copy;
    }

    //// -- GENERAL SHORT ROUTINES -- ////
    /**
     * Create a new ShortBuffer of the specified size.
     *
     * @param size
     *            required number of shorts to store.
     * @return the new ShortBuffer
     */
    public static ShortBuffer createShortBuffer(int size) {
        ShortBuffer buf = ByteBuffer.allocateDirect(2 * size).order(ByteOrder.nativeOrder()).asShortBuffer();
        buf.clear();
        onBufferAllocated(buf);
        return buf;
    }

    /**
     * Create a new ShortBuffer of an appropriate size to hold the specified
     * number of shorts only if the given buffer if not already the right size.
     *
     * @param buf
     *            the buffer to first check and rewind
     * @param size
     *            number of shorts that need to be held by the newly created
     *            buffer
     * @return the requested new ShortBuffer
     */
    public static ShortBuffer createShortBuffer(ShortBuffer buf, int size) {
        if (buf != null && buf.limit() == size) {
            buf.rewind();
            return buf;
        }

        buf = createShortBuffer(size);
        return buf;
    }

    public static ShortBuffer createShortBuffer(short... data) {
        if (data == null) {
            return null;
        }
        ShortBuffer buff = createShortBuffer(data.length);
        buff.clear();
        buff.put(data);
        buff.flip();
        return buff;
    }

    /**
     * Creates a new ShortBuffer with the same contents as the given ShortBuffer.
     * The new ShortBuffer is seperate from the old one and changes are not
     * reflected across. If you want to reflect changes, consider using
     * Buffer.duplicate().
     *
     * @param buf
     *            the ShortBuffer to copy
     * @return the copy
     */
    public static ShortBuffer clone(ShortBuffer buf) {
        if (buf == null) {
            return null;
        }
        buf.rewind();

        ShortBuffer copy;
        if (isDirect(buf)) {
            copy = createShortBuffer(buf.limit());
        } else {
            copy = ShortBuffer.allocate(buf.limit());
        }
        copy.put(buf);

        return copy;
    }

    /**
     * Ensures there is at least the required number of entries left after the current position of the
     * buffer. If the buffer is too small a larger one is created and the old one copied to the new buffer.
     * @param buffer buffer that should be checked/copied (may be null)
     * @param required minimum number of elements that should be remaining in the returned buffer
     * @return a buffer large enough to receive at least the required number of entries, same position as
     * the input buffer, not null
     */
    public static FloatBuffer ensureLargeEnough(FloatBuffer buffer, int required) {
        if (buffer != null) {
            buffer.limit(buffer.capacity());
        }
        if (buffer == null || (buffer.remaining() < required)) {
            int position = (buffer != null ? buffer.position() : 0);
            FloatBuffer newVerts = createFloatBuffer(position + required);
            if (buffer != null) {
                buffer.flip();
                newVerts.put(buffer);
                newVerts.position(position);
            }
            buffer = newVerts;
        }
        return buffer;
    }

    public static IntBuffer ensureLargeEnough(IntBuffer buffer, int required) {
        if (buffer != null) {
            buffer.limit(buffer.capacity());
        }
        if (buffer == null || (buffer.remaining() < required)) {
            int position = (buffer != null ? buffer.position() : 0);
            IntBuffer newVerts = createIntBuffer(position + required);
            if (buffer != null) {
                buffer.flip();
                newVerts.put(buffer);
                newVerts.position(position);
            }
            buffer = newVerts;
        }
        return buffer;
    }

    public static ShortBuffer ensureLargeEnough(ShortBuffer buffer, int required) {
        if (buffer != null) {
            buffer.limit(buffer.capacity());
        }
        if (buffer == null || (buffer.remaining() < required)) {
            int position = (buffer != null ? buffer.position() : 0);
            ShortBuffer newVerts = createShortBuffer(position + required);
            if (buffer != null) {
                buffer.flip();
                newVerts.put(buffer);
                newVerts.position(position);
            }
            buffer = newVerts;
        }
        return buffer;
    }

    public static ByteBuffer ensureLargeEnough(ByteBuffer buffer, int required) {
        if (buffer != null) {
            buffer.limit(buffer.capacity());
        }
        if (buffer == null || (buffer.remaining() < required)) {
            int position = (buffer != null ? buffer.position() : 0);
            ByteBuffer newVerts = createByteBuffer(position + required);
            if (buffer != null) {
                buffer.flip();
                newVerts.put(buffer);
                newVerts.position(position);
            }
            buffer = newVerts;
        }
        return buffer;
    }

    public static void printCurrentDirectMemory(StringBuilder store) {
        long totalHeld = 0;
        long heapMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

        boolean printStout = store == null;
        if (store == null) {
            store = new StringBuilder();
        }
        if (trackDirectMemory) {
            // make a new set to hold the keys to prevent concurrency issues.
            int fBufs = 0, bBufs = 0, iBufs = 0, sBufs = 0, dBufs = 0;
            int fBufsM = 0, bBufsM = 0, iBufsM = 0, sBufsM = 0, dBufsM = 0;
            for (BufferInfo b : BufferUtils.trackedBuffers.values()) {
                if (b.type == ByteBuffer.class) {
                    totalHeld += b.size;
                    bBufsM += b.size;
                    bBufs++;
                } else if (b.type == FloatBuffer.class) {
                    totalHeld += b.size;
                    fBufsM += b.size;
                    fBufs++;
                } else if (b.type == IntBuffer.class) {
                    totalHeld += b.size;
                    iBufsM += b.size;
                    iBufs++;
                } else if (b.type == ShortBuffer.class) {
                    totalHeld += b.size;
                    sBufsM += b.size;
                    sBufs++;
                } else if (b.type == DoubleBuffer.class) {
                    totalHeld += b.size;
                    dBufsM += b.size;
                    dBufs++;
                }
            }

            store.append("Existing buffers: ").append(BufferUtils.trackedBuffers.size()).append("\n");
            store.append("(b: ").append(bBufs).append("  f: ").append(fBufs).append("  i: ").append(iBufs).append("  s: ").append(sBufs).append("  d: ").append(dBufs).append(")").append("\n");
            store.append("Total   heap memory held: ").append(heapMem / 1024).append("kb\n");
            store.append("Total direct memory held: ").append(totalHeld / 1024).append("kb\n");
            store.append("(b: ").append(bBufsM / 1024).append("kb  f: ").append(fBufsM / 1024).append("kb  i: ").append(iBufsM / 1024).append("kb  s: ").append(sBufsM / 1024).append("kb  d: ").append(dBufsM / 1024).append("kb)").append("\n");
        } else {
            store.append("Total   heap memory held: ").append(heapMem / 1024).append("kb\n");
            store.append("Only heap memory available, if you want to monitor direct memory use BufferUtils.setTrackDirectMemoryEnabled(true) during initialization.").append("\n");
        }
        if (printStout) {
            System.out.println(store.toString());
        }
    }
    private static final AtomicBoolean loadedMethods = new AtomicBoolean(false);
    private static Method cleanerMethod = null;
    private static Method cleanMethod = null;
    private static Method viewedBufferMethod = null;
    private static Method freeMethod = null;

    private static Method loadMethod(String className, String methodName) {
        try {
            Method method = Class.forName(className).getMethod(methodName);
            method.setAccessible(true);
            return method;
        } catch (NoSuchMethodException ex) {
            return null; // the method was not found
        } catch (SecurityException ex) {
            return null; // setAccessible not allowed by security policy
        } catch (ClassNotFoundException ex) {
            return null; // the direct buffer implementation was not found
        }
    }

    private static void loadCleanerMethods() {
        // If its already true, exit, if not, set it to true.
        if (BufferUtils.loadedMethods.getAndSet(true)) {
            return;
        }
        // This could potentially be called many times if used from multiple
        // threads
        synchronized (BufferUtils.loadedMethods) {
            // Oracle JRE / OpenJDK
            cleanerMethod = loadMethod("sun.nio.ch.DirectBuffer", "cleaner");
            cleanMethod = loadMethod("sun.misc.Cleaner", "clean");
            viewedBufferMethod = loadMethod("sun.nio.ch.DirectBuffer", "viewedBuffer");
            if (viewedBufferMethod == null) {
                // They changed the name in Java 7 (???)
                viewedBufferMethod = loadMethod("sun.nio.ch.DirectBuffer", "attachment");
            }

            // Apache Harmony
            ByteBuffer bb = BufferUtils.createByteBuffer(1);
            Class<?> clazz = bb.getClass();
            try {
                freeMethod = clazz.getMethod("free");
            } catch (NoSuchMethodException ex) {
            } catch (SecurityException ex) {
            }
        }
    }

    /**
     * Direct buffers are garbage collected by using a phantom reference and a
     * reference queue. Every once a while, the JVM checks the reference queue and
     * cleans the direct buffers. However, as this doesn't happen
     * immediately after discarding all references to a direct buffer, it's
     * easy to OutOfMemoryError yourself using direct buffers. This function
     * explicitly calls the Cleaner method of a direct buffer.
     *
     * @param toBeDestroyed
     *          The direct buffer that will be "cleaned". Utilizes reflection.
     *
     */
    public static void destroyDirectBuffer(Buffer toBeDestroyed) {
        if (!isDirect(toBeDestroyed)) {
            return;
        }

        BufferUtils.loadCleanerMethods();

        try {
            if (freeMethod != null) {
                freeMethod.invoke(toBeDestroyed);
            } else {
                Object cleaner = cleanerMethod.invoke(toBeDestroyed);
                if (cleaner != null) {
                    cleanMethod.invoke(cleaner);
                } else {
                    // Try the alternate approach of getting the viewed buffer first
                    Object viewedBuffer = viewedBufferMethod.invoke(toBeDestroyed);
                    if (viewedBuffer != null) {
                        destroyDirectBuffer((Buffer) viewedBuffer);
                    } else {
                        Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "Buffer cannot be destroyed: {0}", toBeDestroyed);
                    }
                }
            }
        } catch (IllegalAccessException ex) {
            Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex);
        } catch (SecurityException ex) {
            Logger.getLogger(BufferUtils.class.getName()).log(Level.SEVERE, "{0}", ex);
        }
    }

    /*
     * FIXME when java 1.5 supprt is dropped - replace calls to this method with Buffer.isDirect
     *
     * Buffer.isDirect() is only java 6. Java 5 only have this method on Buffer subclasses :
     * FloatBuffer, IntBuffer, ShortBuffer, ByteBuffer,DoubleBuffer, LongBuffer.
     * CharBuffer has been excluded as we don't use it.
     *
     */
    private static boolean isDirect(Buffer buf) {
        if (buf instanceof FloatBuffer) {
            return ((FloatBuffer) buf).isDirect();
        }
        if (buf instanceof IntBuffer) {
            return ((IntBuffer) buf).isDirect();
        }
        if (buf instanceof ShortBuffer) {
            return ((ShortBuffer) buf).isDirect();
        }
        if (buf instanceof ByteBuffer) {
            return ((ByteBuffer) buf).isDirect();
        }
        if (buf instanceof DoubleBuffer) {
            return ((DoubleBuffer) buf).isDirect();
        }
        if (buf instanceof LongBuffer) {
            return ((LongBuffer) buf).isDirect();
        }
        throw new UnsupportedOperationException(" BufferUtils.isDirect was called on " + buf.getClass().getName());
    }

    private static class BufferInfo extends PhantomReference<Buffer> {

        private Class type;
        private int size;

        public BufferInfo(Class type, int size, Buffer referent, ReferenceQueue<? super Buffer> q) {
            super(referent, q);
            this.type = type;
            this.size = size;
        }
    }

    private static class ClearReferences extends Thread {

        ClearReferences() {
            this.setDaemon(true);
        }

        @Override
        public void run() {
            try {
                while (true) {
                    Reference<? extends Buffer> toclean = BufferUtils.removeCollected.remove();
                    BufferUtils.trackedBuffers.remove(toclean);
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
Asian Anthology
No Comments on Asian Anthology
Title: Asian Anthology, New Writing Vol. 1
Editor: Ivy Ngeow
Publisher: Leopard Print London
Spring Onions by Yang Ming
Like most devotees, Ning's mother, Suyin, spent her Saturday afternoons visiting Singapore's Chinese temples. For the past year, she had meticulously listed them on a piece of neatly folded foolscap paper and visited one each weekend after closing her steamed bun shop for the day. She arrived at the temple each week with two red plastic bags containing fruit. Ning stood next to her mother, hands clasped, observing her overturn the bags: apples and oranges tumbled out onto the table. Suyin assembled them on two paper plates in groups of five and placed them at the altar. It was done so mechanically that Ning swore her mother could have done it with her eyes closed.
That Saturday, Ning had accompanied her mother to Thian Hock Keng for prayers. Ning was a month away from an examination that had the potential to define her future. After learning about her daughter's dismal mid-year test results, Ning's mother had found it hard to sleep. Ning's older brother, Ren, on the other hand, had fared much better in his academic studies. A student highly regarded by his peers, Ning's mother did not need to worry about her son. Ning had never wanted to be part of this prayer nonsense but, at her mother's insistence, she dragged her feet to the temple. She considered it a waste of her time; she would rather film a series of life hack videos for TikTok than standing idly at the temple.
"Ma, why do you offer spring onions to Confucius?" Ning asked. Instead of fruit, Ning's mother had prepared a plate of spring onions and steamed buns as offerings to the Confucius statue. Outside, heavy rain fell on the ground like water gushing through a drain. Ning cast a glance at the temple's rooftop, its curved ridges and elongated eaves with upturned swallow-tail decoration blocking the grey skies. Fat raindrops began to whip Ning's legs, causing her to retreat further into the temple's statue shelter. Ning's mother had followed her usual practice of waiting for fifteen minutes for the gods to 'eat' the offerings before clearing them away. Ning wondered if they liked spring onions; she certainly did not.
"Spring onion is 聪 in Mandarin. Cong. It means intelligence. You will need it for your exams," Ning's mother replied, folding her arms across her chest.
The smell of the incense coil burning in the main hall spread through the air. Ning was surprised to find the smell soothing and she likened it to sandalwood incense sticks from her favourite aromatherapy shop.
"My friends say praying to Confucius will help you in your exams," Ning's mother said as she rummaged in her bag for her phone. She fished it out and began to tap away.
Ning wanted very much to tell her mother that she was going to fail her upcoming examinations, and no amount of prayers or offerings to any deities would work but she couldn't summon the courage.
"Time to clear the table," her mother said, walking towards the altar. Putting her hands together, her mother uttered a few inaudible sentences and bowed to the statue three times before shoving the offerings into the plastic bags. Ning followed suit, bowing grudgingly.
Under the minimal lighting, her mother had a pallid face; her yellow-stained nails and dark circles sagged under her eyes. She wondered why she hadn't noticed those hands and face marked with endless strife and pain.
On a one-way street, a solitary car lumbered past them. Ning sidestepped puddles of water scattered along the pavement while swinging the bag of spring onions recklessly.
"Stop that," her mother said, her voice echoing through the empty street.
"It's just spring onions!" Ning exclaimed in defiance.
Her mother slapped her daughter's head lightly. "I need to cook these tonight. You think what, I'm going to throw it away, is it?" her mother said, gripping a half-smoked cigarette between her forefinger and third finger. Ning heard her mother mumbling some words in Hokkien as she turned away. She rolled her eyes at the thought of eating a plate of stir-fry spring onions or any dish with spring onions in it.
If Ning could harness any power from a higher being, she would remove every stalk of spring onion from existence. Her mother's phone rang as they turned at the corner shophouse. Ning stepped back to give her some privacy. A group of young, giggling girls traipsed past them, enthusiastically discussing a hip coffee joint. Ning surreptitiously crept closer towards her mother, trying to listen in on the conversation. But she could only hear laconic replies that consisted of, "yes", "no" and "I understand". Her voice seemed restrained.
"Who was that?" Ning asked.
"Just somebody. Why so kaypoh?" Ning's mother asked, clicking her tongue.
Ning knew her mother deployed this snappy attitude to fob her off whenever Ning became too much of a busybody for her own good. The skies had finally cleared, releasing an earthy petrichor — a scent Ning secretly adored. The afternoon sun peeked out of the grey clouds, creating a golden halo with glorious rays of light around them.
Ning watched snippets of TikTok videos on the train home. Images of a mother and daughter duo swaying and jumping in one frame and morphing into each other in the next frame. A muscular man struggling to tear into an apple with his bare hands while a young man used a knife to cut an apple. A middle-aged woman synchronising her dance moves with a little girl. These entertaining yet addictive videos usually amused her, but Ning couldn't seem to shake that mysterious phone call off her mind. Why did her mother lower her voice? Or why did she sound so serious? The 'whys' inundated her mind throughout the entire journey, until her mother nudged her elbow to motion her to get off the train.
"Make sure you finish up all the spring onions later," Ning's mother remarked as they ambled through the housing blocks.
"I'm not going to eat any spring onions," said Ning. Those words had rolled out of her mouth faster than her mind could stop them.
Ning's mother glared at her with an expression as stiff as a starched uniform and Ning knew what came after this was going to be torture.
"Ma, I'm going to fail my exams next month. There's no point for me to eat those awful vegetables," Ning said, pursing her lips. She cast her eyes on the ground as though something incredible had just skipped across her feet. A group of boys ran past them, yelling, Eh, where are we going ah? Let's go to the playground. Their voices echoed through the communal void deck.
"And what are you going to do if you fail your exams?"
"Ma, I want to make buns, just like you."
Ning's mother closed her eyes and clenched her hands into fists. The last time Ning had witnessed this inscrutable face was three years ago when she returned home from grandma's place, and had seen her mother sitting on the kitchen stool, staring into nothingness. Ning had pushed open the door to her parents' room, only to find it in a chaotic mess — a smashed family photo frame was on the floor.
Before Ning could say anything else, her mother walked towards the lift lobby. She was surprised her mother hadn't rebuked her for speaking out.
In the kitchen, Ning quickly tore the omelette apart, only to discover an absence of spring onions. She grinned quietly to herself, thinking she had convinced her mother to exclude that awful vegetable.
Later that week, Ning parked herself at the side table in the bun shop, working on her Maths assignment. The afternoon news on the radio blared loudly in the background. She stared at the Pythagoras Theorem question and doodled aimlessly on the foolscap paper until her mind was drawn to her mobile phone. She tapped her TikTok app when, out of the corner of her eye, she saw Mrs Lim peering into the shop.
"Eh, ah girl, so hardworking! Where's your mummy?" Mrs Lim asked, raising her voice above the static crackling noises.
"Hi, Mrs Lim! She's in the kitchen making baos with Chen," Ning replied, pointing towards the back of their tiny shop, where their cramped kitchen was located. "Do you want your usual Char Siew Bao or Big Chicken Bao?"
Mrs Lim, a regular customer of Tan's Bun Shop for years, beamed upon hearing those words. Ning gave her a wide smile. Mrs Lim rarely hesitated to buy more steamed buns whenever she patronised the shop.
"Just give me five Char Siew Baos and five Big Chicken Baos," Mrs Lim said.
Ning pulled out the second tier of the bun steamer display cabinet and used a pair of silver tongs to pick those flavours. She enjoyed giving those soft and fluffy buns a little squeeze on the side as she placed them into the polystyrene boxes. She felt that was the least she could do as a daughter – assisting her mother and, at the same time, learning the trade. Halfway through, she heard a series of quick footsteps from behind her and before Ning could turn around, her mother was already standing next to her.
"Go and do your homework. I will help Mrs Lim with her order," Ning's mum said as she smoothed away a few strands of hair from her eyes. Ning gently placed the tongs on the table and nodded silently at Mrs Lim, whose face had already become annoyed. Ning grabbed her phone from the table and slunk away.
Inside the kitchen, a stack of large bamboo steamers formed a tower on an industrial stove. They were probably the last batch of assorted steamed buns that would be sold for the day, Ning thought. White steam swirled up in the clammy air.
On the other side, Chen, the ever-loyal shop assistant, was cleaning a dough mixer as he whistled and swayed to a catchy Chinese tune. Originally from Johor, Chen had been crossing the Causeway to work at the shop since Ning was born. Two small portions of leftover dough and a small bowl of barbecue pork were left on the table. Usually, these remnants would be thrown away at the end of the day, as Ning's mother believed in the freshness of ingredients.
Ning whipped out her phone and filmed the first part of a video, cut out a tiny piece of the dough, flattened it with a wooden rolling pin and filled it with a spoonful of barbecue pork. For the second part, she slowly gathered the pleat of the dough to seal up the filling, but the pleat looked odd. Chen glided towards Ning and commented, "Not bad. But still need a lot more practice."
Ning hushed him as the video was still recording.
"But you are getting better now. In the past, your baos looked so funny. If I have more time, I can teach you more things," Chen said, dousing the floor with warm water.
"I'm free on weekends or when Ma goes out to buy Toto," Ning said enthusiastically.
"No point. I'm going to look for a new job."
"Why? Has Ma found someone to replace you?" Ning asked, giving a quizzical look.
"She didn't tell you anything?" Chen asked. Ning shook her head. "Your ma is going to sell this shop."
Words became trapped in Ning's throat. The air grew cold. Sell the shop? Why would her mother even consider selling it? Those questions whirled in her mind like a gale barrelling through an open field. Ning's mother had barely scraped through her secondary school education. In her teens, she had repeatedly failed her exams and, like any hot-headed teenage girl with raging hormones, she got involved with boys and bad company. She eventually left school at the age of 15, much to her mother's chagrin. No amount of words could persuade her to return to school, until her grandma received a call from the police late one afternoon, informing her that her granddaughter had been involved in a gang fight which had led to the accidental death of an elderly passer-by.
Ning's mother was sent to a probation home for girls for two years. It was at that place where she had encountered a God-loving youth worker who persuaded her to think about her future and about the people who loved her. Upon her release from the girls' home, Ning's mother trudged home, only to discover her family wanted nothing to do with her. Out of kindness, they provided her a bed in which to sleep. Due to her bad record and a lack of qualifications, she worked several odd jobs to get by, until a kind elderly man who owned a steamed bun shop had taken her in and imparted his bun-making skills to her.
Those thoughts were interrupted when she heard a loud shriek floating from the shop front. Ning stepped out of the kitchen and caught Mrs Lim flinging her arms at her mother, remarking, "Crazy woman! You think your bao shop is the best in Singapore, is it?' If not for your daughter, I wouldn't even step into your shop." Mrs Lim spat on the ground before stomping off.
"She thinks she is a big shot! Everyone must kowtow to her," Ning's mother fumed, slapping the thick receipt book on the counter. It didn't come as a surprise to Ning, as Mrs Lim was probably one of those disgruntled customers her mother had offended on a regular basis. Ever since Ning's father had abandoned the family on the day her mother stared into nothingness, business had gone downhill. Multicoloured graffiti had repeatedly been sprayed across their shop's rolling shutter with words like, O$P$ and Go to hell! Ning's mother had surmised the vandalism was the loan sharks' doing.
Already bestowed with the moribund steamed bun shop and heavily burdened with two young children, Ning's mother balanced her life between reviving the shop and paying off her good-for-nothing ex-husband's mounting debts. Ning witnessed the relentless spirit of those loan sharks sauntering into their shop on random sultry afternoons. The men, no younger than twenty-five years old, had blond hair and a uniformed phoenix tattoo on their forearms. They appeared harmless at first but what came out of their mouths was nothing but coarse language. This had led Ning's mother to a nervous breakdown, and she eventually became short-tempered.
As years went by, customers dwindled. Ning found herself greeted by bags of cold steamed buns at home every day. Ning's mother always shrugged it off with, "We made so many baos today. These were the leftovers."
"But Ma, Mrs Lim was just…"Ning protested, still holding on to her phone. Her mother quickly interjected.
"Stop playing with your phone. What's the point of doing all those videos? Can earn money or not? Ning, my friend just recommended me a tutor for you. She said he's a very good tutor. Can teach you Maths. I know it's too late but at least he can teach you what he can."
Ning gasped. Tutor? But how could her mother afford it?
Ning's head weighed a ton when her best friend, Farah, rambled on about her latest TikTok and Instagram videos during recess. She raved about the number of views she had garnered in a day. Farah's monologue suddenly changed subject, and she asked Ning if she'd like to study for their upcoming exams with her after school. Ning knew Farah was the more hardworking person of the two of them. Even her social media videos yielded more views and likes than hers. She forced a lop-sided smile. She wanted to tell her about the shop and the sudden change in her mother's behaviour, but she couldn't form the words in her mind. Before Ning could say anything, she saw their form teacher, Madam Nadia, walking towards them. Farah greeted her like any obedient child before slinking away.
Madam Nadia pulled Ning aside to a quiet section of the corridor. She interrogated Ning about the Maths assignment — Ning had completely forgotten about it. She sheepishly replied and said she left it in the shop but it was a lie. Madam Nadia raised her eyebrows sceptically, and with a straight face, she broke the news to Ning that, if she failed her upcoming exams, she would have to repeat another year. Ning acknowledged it with a nod and disappeared, but not before Madam Nadia requested to see Ning's mother, to which Ning lied that her mother was too busy.
At 8 that evening, Ning's mother returned to their modest three-room flat with a bag of assorted steamed buns. She was on the phone, speaking in a low voice. She didn't notice Ning sitting on the sofa watching a variety game show where contestants had to guess the price of household items. Ning quickly lowered the volume of the television, when she distinctively heard her mother saying, "The price is too low. I will consider selling it if the price is higher."
Ning was about to confront her mother when her brother, Ren, shouted at her for stealing his favourite blue gel pen. Ning glared at him, grabbed his pen from the coffee table and tossed it to him. Ning's mother untied the bag of buns and passed her improved steamed Pork bun to them to try. But Ren scrutinised the bag before settling on the lotus flavour bun instead and disappeared into his room. Ning obediently picked the lukewarm bun off her mother's hands.
She sank her teeth into the bun. The more she chewed, the more she felt a strange and bitter taste on her tongue. She spat out a morsel of the filling and discovered a slimy green vegetable — spring onions! Ning's mother scolded her for wasting the filling as she and Chen had spent the whole afternoon improving the flavours. A strange feeling inexplicably invaded Ning, and in one swift movement, she ripped the bun apart and threw it on the floor.
About the Book: Crocodiles in the city, street food fandom, a psychic club meeting in a Penang beach resort. Asian Anthology: New Writing Vol. 1 is a showcase of short stories and place writing by both new and more established prize-winning writers. Some unexpected, a few surreal and others traditional, these are 23 compelling stories of irony, humanity and satire, exploring a range of subject matter to reveal a glimpse of modern Asian society and culture: a funeral in India, a hotel encounter in Japan, a sleepless night in Hong Kong. Modern themes such as the chilling consequences of the environmental impact of logging, deforestation and the barbarism of the shark's fin soup delicacy press on our collective conscience. In the pieces on place writing, the outsider's view gives insight into the white-guy-in-Asia trope: backpacker, courier and expat company manager. But no Asian fiction is complete without stories of food, family conflict, redemption and reconciliation. Surprising and entertaining, this anthology captures the paradox of richness, diversity and humour that is Asian culture.
Contributors: Rumaizah Abu Bakar, Patrick Burns, Cheung Louie, E.P. Chiew, Mason Croft, MK Eidson, Marc de Faoite, Jenny Hor, Nenad Jovancic, Lynett Khoh, Doc Krinberg, V.S. Lai, Ewan Lawrie, Winston Lim, Y.K. Lim, Yvonne Lyon, Sandeep Kumar Mishra, Ivy Ngeow, Krishnaveni Panikker, Sylvia Petter, Shafiqah Alliah Razman, San Lin Tun and Yang Ming.
Editor/Author's Bio: Ivy Ngeow was born and raised in Johor Bahru, Malaysia. She holds an MA in Writing from Middlesex University, where she won the 2005 Middlesex University Literary Press Prize out of almost 1500 entrants worldwide. Her debut, Cry of the Flying Rhino (2017), was awarded the International Proverse Prize in Hong Kong. Her novels include Overboard (2020) and Heart of Glass (2018). She lives in London.
Tags Asian Anthology, Ivy Ngeow, Malaysia, Yang Ming
← If My Life were Only a Dream → An Exotic Box of Treats

redpajama_set_name: RedPajamaCommonCrawl


Lifestyle intervention may reduce the development of type 2 diabetes among high-risk individuals. The aim of this study was to explore how older adults perceived their own lifestyle and being at increased risk for type 2 diabetes while they participated in a lifestyle intervention programme.A nested qualitative study was performed with 26 participants (mean age 68 years) in the VEND-RISK Study. Participants had previously participated in the HUNT3 Study and the HUNT DE-PLAN Study, where their risk for developing type 2 diabetes (FIND-RISC ≥ 15) had been identified. The data were analysed using systematic text condensation.Two main themes were identified. The first theme was having resources available for an active lifestyle, which included having a family and being part of a social network, having a positive attitude toward life, and maintaining established habits from childhood to the present. The second theme was being at increased risk for type 2 diabetes, which included varied reactions to the information on increased risk, how lifestyle intervention raised awareness about risk behaviour, and health-related worries and ambitions as type 2 diabetes prevention.Assessing a participant's resources could improve the outcomes of lifestyle intervention programmes. Both family history and risk perception could be used in preventive strategies to enhance changes in lifestyle.The VEND-RISK Study was registered in ClinicalTrials.gov on April 26, 2010, with the registration number NCT01135901 .


text:
Welcome to "The Kinetic LiNK" (K-LiNK) is Functional Free Motion Resistance
The principles behind The Kinetic LiNK are largely associated with the kinetic link principle. The principle that body segments generate high end-point velocity by accelerating and decelerating adjacent links, using internal and external muscle torques applied to the body segments in a sequential manner from proximal to distal, from massive to least massive, and from the most fixed point to the most free point.
The kinetic link principle is applied when different body segments rotate during throwing, sprinting, bounding, and kicking. These actions have been likened to the motion of a bullwhip. If segmental rotations are free to occur at the distal end, the body's base-segments in contact with the ground act like the handle of a bull-whip. Just as the tip of the bullwhip can be made to travel at supersonic speed, the small distal segments of the hand and foot can be made to travel very fast by the sequential acceleration and deceleration of the body segments once resistance is applied throughout motion.
About The Inventor
Rephel Martin is the inventor and creator of "Function FreeMotion Resistance Training" and "The K-Link". The innovation behind the K-LiNK was to create an environment to allow athletes to teach themselves what "IT" feels like while adding specific resistance but not restriction to athletic movement. "IT" is the link between feeling the movement happen and understanding what these sports specific movements translate into.
The Dover, New Jersey native competed in Track and Field at UNC-Charlotte, where he excelled in the long jump and triple jump. While at Charlotte, He earned All-America notice in the triple jump at the 2000 NCAA Outdoor Championships and earned All-Conference USA honors eight times in the long jump, triple jump and 55m dash. He is a two-time conference champion in the long jump and three-time triple jump conference champion, and was selected Conference USA Indoor Athlete of the Year in 2000, and Charlotte indoor and outdoor team MVP in 2000. Rephel also competed at the USATF national championship level in both the long and the triple jump.
Martin currently holds the Conf-USA record in the long jump at 26'5" (8.05m), and recorded a personal best 53'9" in the triple jump, and 6.37 seconds in the 55-meter dash. Martin has earned USATF level one coaching certification, USTFCCCA Combined Events certification, and is AFAA personal training certified.
Collegiate Athletic Achievements
2000 NCAA All-American in the triple jump (16.17m, ranked seventh nationally)
Conference USA Male Athlete of the Year (2000)
Two-time Penn Relays winner in the triple and long jump
Five-time Conference USA champion
Current Conference USA record holder in the long jump (26' 5")
2004 Olympic Trials qualifier
Fourth place in the triple jump at the 2000 USATF National Indoor Championships
Tenth place in the triple jump at the 2001 USATF National Outdoor Championships
Long jump 26' 5" (8.05m)
Triple jump 53' 6.5" (16.32m)
55m dash 6.37
100m dash 10.67


text:
Home Music News Foo Fighters Announce They Are Starting Work On A New Album!
Foo Fighters Announce They Are Starting Work On A New Album!
Nova News
Foo Fighters have revealed that they are set to make a return to the studio to begin working on a new record.
According to CoS, frontman Dave Grohl made the announcement during the group's headlining set at Rock in Rio Brasil over the weekend: "We go home next week and we start making a new Foo Fighters record."
Back in August of this year, stick man Taylor Hawkins claimed that the rockers aimed to drop the follow-up to 2017's Concrete and Gold in 2020. Hawkins explained that Grohl had a number of demos in the pipeline:
"Well, from what I've heard from our fearless leader Dave Grohl, he has a lot of demos that he's worked on and I think we'll start, once this tour is over… I think not too soon after that we'll start the process of putting the songs together as a band,".
"It's a long process, we do a lot of demoing and stuff, but I think that we'll have, I'm hoping, I think we'll have a new record by next year. We should," Hawkins concluded.
Meanwhile, Foo Fighters fans can look forward to a rake of semi-regular archival releases in the lead up to next year's 25th anniversary of the band's eponymous debut.
Don't forget you can keep up-to-date on all things Nova over on our Instagram page – follow us for all the craziness of radio life coupled with news, sports and LOTS of cool competitions! Click here…
New Record
Previous articleSlipknot React To Postponed Metallica Tour
Next articlePolice Called After Goose Smashes Taxi Window
https://www.nova.ie/
Rick Rubin Calls Paul McCartney "The Best Of All Bass Players"
Dave Grohl To Star In Super Bowl Advert
U2 Release Reimagined Version Of 'With Or Without You'
Mick Ronson Remembered
Led Zeppelin Drop An Epic Remaster Of 'Rock And Roll'!


Koro had the most liked content!
On Landroval I have a 74 guardian (my highest level) in the Gap of Rohan, doing a lot of the dunlandings vs Rohirrim quests. I can't wait to enter Rohan and experience the horse lords!
Anyone playing on the Legendary Servers?
I know @Daizey started something on the Legendary server a while back, but not sure how that was going. Been quiet on Landroval, though I will be playing quite a bit this summer (when I'm not in the mountains). I've avoided the Legendary as I was under the impression you have to be a sub in order to access it.
Thank you all for the wonderful birthday wishes! Ya'll are way too nice to me.
Hope it's a great one my friend!!
Has anyone been to Erebor yet? Or Dale-lands? I'm only 74 and about to start Rohan. Wondering what people think of the later parts of the game, past Mordor's expansion.
Only the best to you!!!
Hope you have a great day! You're da best dude! "É NÓIS!"
Hope you enjoy your day Koro!
Happy Birthday!!!!!! Now tell me what you want for your birthday so I don't get you something stupid.
Happy Happy Birthday to the wonderful Koro! Hope you have an awesome day.


Since time immemorial, dogs have become part of human life in a great way. It's without a doubt that dogs have successfully advanced from being just domestic animals. Nowadays they live under the same roof as their owners.
As if that not enough, they share names with human beings depending on gender. This is getting more interesting as time passes by.
The future of dogs, however, looks like it might turn from better to best. You will be amazed by puppy names for boys in most homesteads.
Without much ado, let's discuss how you will name that dog.
Don't get it twisted though, this is just some of the most brilliant, popular male puppy names. You also realize that these names are somewhat projectable even from a distance. You can thus call your dog from a distance and it's able to hear you clearly.
Careful scrutiny will tell you that some of these names are in the list of top dog names. The names are at your disposal; knock yourself out.
Actually, these names have been in use for long enough to make every dog owner aspire to use them. When one of these names is mentioned, it rings a bell and hints on the context.
Among these names, Carter takes the crown home. This name is just but a taste for many. It sounds like power and beauty no wonder many dog owners prefer it. This is also a name that commands a certain degree of respect. The rest of the names are also unique and every dog owner needing a special name should consider them.
These names are likely to be assigned to leaders. So if your instincts tell you that your dog may assume such a role, these names are suitable.
Neo would win the cherry-pick since it means new in Greek and gift in Tswana. This means that this name suits a new dog or a puppy. Also, if your dog is a gift, calling it new is staying the course since the name suggests the source.
A cool name as many would call is jargon for something pleasant and worth the while. When it comes to male dog names, it becomes a sensitive topic. If you need your dog's name to sound legendary, here is a list that will make you hit the jackpot.
Evidently, cool dog names also need to be unique. This means that they are not frequently used but still create a healthy match. These names are rare but very familiar to those who seek them. Naming male dogs have been made easier by the inclusion of these names. Your peers will find your dog name cool and may also emulate your male dog naming.
If you want a dog name that is least likely to be in use, this is your category. So as you choose a male dog name for your new canine friend, utilize one of these. Check more great names here.
Did you know that puppies are like babies? They also require reaching a certain age for their senses to properly develop. The most important senses in a puppy are eyesight and hearing. These two help the puppy to learn their name and any other sort of training. Usually, intelligence in a puppy starts at 12 weeks. At this age, training the puppy on habits and routines is easy. Mastering its name at this age will also be as easy as riding a tricycle. So, to give new male dog names to a puppy, wait until it's at least 12 weeks old.


text:
Ambassador's Welcome
About Jordan
Facts About Jordan
Jordan-Singapore Relations
Links to Jordan
Why Jordan
Visit Jordan
Study in Jordan
Invest in Jordan
Jordanian Passports
Jordan Pass
Register with the Embassy (Jordanian Community)
Among the reasons that make Jordan an attractive location for Singaporean investments are:
Conducive bilateral legal framework:
Jordan and Singapore concluded a Free Trade Agreement and Bilateral Investment Treaty in 2004. Furthermore, Jordan and Singapore are currently undergoing negotiations to sign an avoidance of Double Taxation Agreement which has already been signed in first initials and will hopefully be concluded in 2020.
A Gateway to the World
Jordan's strategic location at the crossroads between Europe, Asia and Africa combined with its extensive free trade and bilateral agreements with other countries give foreign investors access to over one billion consumers.
Jordan has free trade and association agreements with the United States, Canada, the European Union and other Arab countries. Investing in Jordan gives access to the Middle East and GCC and the Arab Region.
Port of Aqaba
Stability and Security
Jordan enjoys a high level of stability and security, and as a result continues to attract foreign investors. According to the Gallup Law and Order Study of 2018, Jordan is ranked as the 22nd most secure country in the world and the second safest in the Arab world.
Strong Banking and Financial Institutions
There is a comprehensive legal framework in Jordan that guarantees confidence in banking and financial transactions in the country. It also ensures transparency, adherence to international monetary standards and protection of capital.
The banking sector in Jordan is well developed by regional standards. There are 23 banks in Jordan, 16 Jordanian banks and 9 foreign Banks.
Jordan is currently ranked 75 out of 190 economies in the World Bank's Doing Business Report. Jordan's ranking has jumped 29 places in 2020, and it was selected among the top reformers. Jordan ranks fourth, on par with Australia and the United States in the Doing Business category related to the ease of getting credit.
Investor Friendly Environment
Jordan's laws and regulations relating to foreign investment provide the following privileges and guarantees, inter alia:
– No restrictions on foreign ownership except in a limited number of economic activities.
– Foreign investors may wholly own investments in Development Zones and Free Zones.
– National treatment, free movement of capital, protection against expropriation and options to resort to alternative dispute settlement mechanisms.
– Equal treatment to both Jordanian and non-Jordanian investors.
– No restrictions on the transfer of capital, revenues and profits abroad.
– No restrictions on the transfer of salaries and compensations abroad by foreign workers.
Special Economic Zones:
Jordan has established two types of special economic zones in various regions of the country: Development Zones and Free Zones. These zones are dedicated to various fields of business and industries and are equipped with all the needs of investors from infrastructure to services. Investing in these zones provides exemptions from customs duties, income tax, sales tax on goods and services offered and consumed within the zones, and export tax.
Developed ICT
Jordan is the regional hub and leader in ICT, with a steady inflow of 5000 to 6000 ICT graduates from universities annually joining the labor force. Jordan produces 75% of the Arabic internet.
Copyright © 2023 Embassy of the Hashemite Kingdom of Jordan to Singapore


the Delhi assembly passed the Right to Information Bill 2001, which proposes to bring about more transparency in governance, on April 9. "The bill seeks to provide each citizen the right to information," said Sheila Dixit, Delhi's chief minister. But this right is subjected to certain conditions -- information threatening public interest will not be disclosed.
As per the provisions of the bill, Delhi's residents can now get access to certain information after paying a prescribed fee to the authority concerned. The fee will not exceed the cost of processing. The bill states that the officers concerned should either provide information within 30 days of the date of the receipt of the application or give reasons for not doing so. According to the bill, strict disciplinary action will be taken against those officials who fail to do so. People can then appeal to the Public Grievance Commission against such officials.The commission's decision shall be final in this regard. The government proposes to make the officers more responsive and accountable by establishing a state council with the chief minister as its chairperson.
"The bill does not specify the details of punishment in case of non-compliance by the authorities. This is a major lacuna without which the bill fails to address," says Surendra Mohan, a social scientist. The corporate sector should have been also covered under the bill, he added.
Among the states that have passed the right to information bill include Karnataka, Goa and Rajasthan. Experts feel that the experience in these states illustrates the urgent need for strict legislation. "For example, Rajasthan passed the Right to Information Bill in May 2000. But the experience of Janwad panchayat shows that despite sustained efforts, it took one year and a high court directive to obtain the required information," says Aruna Roy, an activist of the Mazdoor Kisan Shakti Sangathan, a Rajasthan-based non-governmental organisation. A joint committee of the parliament is now examining the Union government's bill on the right to information.


text:
Home News Fury: There is so much pressure on my fights
Fury: There is so much pressure on my fights
Fury returns for fifth fight on Saturday night live on BT Sport
Jonathan Nagioff
Tommy Fury fights for the fifth time as a professional on Saturday night Photo Credit: Round 'N' Bout Media/Queensberry Promotions
Tommy Fury says the expectation is on him heading into every fight, but insists his only focus is on learning his craft.
Fury (4-0, 3 KOs) fights for the fifth time as a professional on the undercard of Anthony Cacace's British Super Featherweight title defence against Lyon Woodstock at the Copper Box Arena, with an opponent to be confirmed.
The 21-year-old, younger brother of WBC Heavyweight champion, Tyson Fury shot to fame on reality show, Love Island in the summer of 2019 and has amassed over 3m followers on Instagram alone.
Despite recognising the pressure on his shoulders, the Manchester man says he won't let that effect his performances in the early stages of his career.
"When I take these fights now, there's so much pressure on it," Fury told Queensberry Promotions YouTube channel.
"Because, I've got all my audience on Instagram and social media looking at it, I've got all the boxing audience from the last name perspective looking at it.
"But it all just falls off. When I get in the ring I don't care about that. When I get in the ring it's about my learning stage, my apprenticeship, that's what I'd say, because that's what it is.
"I'm learning on the job, it's hard, it's a hard game, but I know what I've signed up for and there's no beating around the bush, it's a hard game and I'm ready for it."
Fury secured a showreel second round knockout out Genadij Krajevskij in his last fight in November to extend his unbeaten record.
A post shared by Tommy TNT Fury (@tommytntfury)
'TNT' trains alongside his dad, John Fury at Jimmy Egan's boxing academy, where Tyson first started out and heads to his brother's new Morecambe gym on a weekly basis.
The Light Heavyweight prospects admits the two-time Heavyweight champion, who is on the brink of securing an undisputed title showdown with unified titlist, Anthony Joshua in the Spring, provides him with additional incentive.
"Tyson's always been a big part of my career," Fury added.
"Motivational wise he's always been there, ever since I started training. I remember being eight and nine in Warrington we were always training and teaching me how to counter the body shots.
"Even now we go down to Tyson's once, twice a week, we do little bits with Tyson.
"It's good because whenever you get them down days, you get to go there and see him train and everything that he's been through, it's motivational."
Should he come through successfully on Saturday night, Fury is hopeful his promoter Frank Warren can keep him as active as possible this year, after featuring just once during a pandemic-stricken 2020.
'TNT' admits he is in a comfortable position financially and is boxing solely to achieve his goals of becoming a world champion and vows to achieve this feat.
"I'm training like I'm challenger all the time and I still am," he added via a press release.
"That's the best part about it. I've not achieved anything in boxing and it's not about the money.
"I'm not boxing for the money now. I can live the life I have now without boxing.
"This shows I'm not doing it for a few quid or to get my name out there. I'm doing it because I love the sport and I made a promise to myself that I'd be a World champion.
"It is a long hard road ahead. There will be a lot of good times, a lot of bad times but we'll get there.
"I know times are hard, but I am just hoping that Frank can get me out as many times as possible this year, and I know I'm lucky to get out boxing at the moment."
Anthony Cacace
lyon woodstock
queensberry promotions
Tommy Fury
Previous articleKaisy Khademi vs Ijaz Ahmed – Big Fight Preview & Predictions
Next articleCanelo Alvarez vs Avni Yildirim – Big Fight Preview & Predictions
http://www.proboxing-fans.com


'Agnes' can be difficult to establish, which is unusual for a rugosa rose. But once established the shrub is exceptionally winter hardy, especially for a yellow blooming rugosa. The unusual shiny deep green leaves provide a wonderful contrast to the pale blooms.
Rugosa 'Alba' produces the "whitest of white" blooms. The buds are very long with a blush pink tinge. Rugoss 'Alba' is the wild rose often seen growing along the seashores, along with Rugosa 'Rubra'. This is undoubtedly the hardiest rose to be found. Water well until they are established, then the should only need water in drought periods. They are partial to manure and top dressings of kelp meal, do not use commercial fertilzer as they leaves will burn. 'Rubra' will sucker easily and form a nice hedge. They are perfect to prevent soil erosion on banks. They will also reproduce easily from seed and set very large red hips. Forms a very nice tall hedge, or use at the back of the border and in perennial gardens. Large range hips are produced in fall, and foliage may turn yellow orange after the first hard frost.
'Blanc Double de Coubert' is a hybrid with extremely fragrant white blooms. It blooms heavily in early spring, then nearly continuously all season, beginning earlier than many roses. It is one of the best white blooming roses. Although it will tolerate part shade, best flowering and disease resistance is achieved in full sun. Delicate petals may be spoiled by rain. 'Blanc Double de Coubert' creates a nice hedge, however allow enough space for good air circulation, planting 5 feet apart. Plants that grow into one another if planted closer together should be pruned to control size. Use as specimen plant, small groupings, foundation planting or in cottage gardens. Deadhead spent blooms to encourage reblooming. A small number of orange-red hips are formed in fall. This is an exceptionally hardy and disease resistant rose bush, tolerating poor soil, salt spray and windy conditions. Susceptible to aphids. Crown protection is advised to guard against damage to top growth. Own root rugosas will regrow true even after dieback to the crown. May be hardy as far as zone 2.
'Dart's Dash' is covered in blooms in June, and then repeats well all summer. The dense habit makes 'Dart's Dash' a wonderful short hedge, or use as a specimen plant with its' striking bloom color. Also serves the border of perennial garden well. The plant grows vigorously and naturally maintains good health. Fall produces huge orange-red hips and interesting foliage colors. By seasons' end, the plant is more susceptible to powdery mildew. May be hardy as far as zone 2.
'F J Grootendorst' grows vigorously with lush foliage and a somewhat bushy habit. It is one of the Rugosas that will tolerate some light shade, and will also tolerate poorer soils. The petals have frilled edges on carnation-like flowers, blooming in a deep pink to light red depending on the soil and conditions. A profusion of blooms appears in spring, then reblooms quickly, essentially continuously in bloom. Makes an excellent hedge or small group and mass plantings. A full grown shrub in bloom makes an impressive statement. Also grows well in a large container. Unfortunately "F J Grootendorst' does not produce hips. This shrub rose may also be referred to as 'Grootendorst Red' or the common names Hedgehog rose, Ramanas rose, Japanese rose or Sea tomato. Although not quite as hardy as the other Rugosa Roses, 'Grootendorst' will still thrive in zones 3 and 4 if adequately protected. The tall canes are a bit more difficult to protect (see creative ideas for protection) but will grow back quickly and true from its' "own roots". Responds well to pruning, so it is easy to maintain a smaller size.
Like the other 'Grootendorst' Rugosas, Alba will tolerate some light shade and is more tolerant of poorer soils. It nonetheless is an excellent free flowering shrub rose that can make a dramatic statement as a specimen, in a hedge, in perennial gardens or in a large container. Alba is a bit more fragrant than the other 'Grootendorst' roses. Although not quite as hardy as the other Rugosa Roses, 'Grootendorst' will still thrive in zones 3 and 4 if adequately protected. The tall canes are a bit more difficult to protect (see creative ideas for protection) but will grow back quickly and true from its' "own roots". Responds well to pruning, so it is easy to maintain a smaller size.
One of the smaller, more compact Rugosas, this rose bush holds a more rounded form at about 3-4'. Floriferous bloomer with delicate 3 inch blooms of pale pink with an exquisite fragrance. Will tolerate some shade. The blooms are followed by large bright red hips, and will sometimes display both blooms and hips later in the season. Foliage turns deep maroon then yellow orange in fall. Very disease resistant and hardy.
'Grootendorst Supreme' is always blooming with clusters of dark red carnation like blooms. The bright foliage is a terrific contrast to the nonstop display of red blooms. This is a very reliable and hardy shrub rose, beautiful to use all over the gardens or in a hedge. Will tolerate light shade.
Disease Resistance: Very good resistance, somewhat susceptible to black sopt and fungal disease.
This stunning rose bush produces nonstop pink-violet 3 inch flowers. 'Hansa' is a common rugosa that is super hardy, easy to establish and easy to grow. Abandoned plants continue to flourish and bloom profusely being completely neglected. Huge scarlet-red hips are produced in fall. An elegant vase shape makes it a perfect specimen plant, or use it in perennial gardens and mixed borders. 'Hansa' produces suckers readily, so it is difficult to keep maintained in a manicured garden, but will form a nice hedge. The shrub grows so vigorously, it should be pruned down at least two thirds every other year to prevent it from becoming leggy, also removing dead wood and overly large canes. Give it plenty of room and let it go 'wild'.
'Jens Munk' is a hybrid Explorer rugosa rose. Spent blooms need to be deadheaded to encourage additional blooming. The shrub stays neat in a smaller mounded shrub, making it a beauty in the front of a garden, as a specimen plant or as foundation plantings. The shrub grows quite vigorously and is tolerant of part shade. May be hardy as far as zone 2.


text:
Join in a Special LGBTQ History Month Screening & Discussion
SCREENING & DISCUSSION
Thursday, October 17 - 7:00pm
Unity Temple on the Plaza
Free Admission at the Door Tonight
AUDIENCE AWARD WINNER — 2019 Frameline San Francisco LGBTQ Film Festival and the OUTFEST LA Film Festival
An audience response and discussion led by Samantha Ruggles of the Kansas City Center for Inclusion follows the screening.
This dynamic documentary takes us into the lives of three high school athletes—all at different stages of their athletic seasons, personal lives, and unique paths as transgender teens.
Their stories span across the U.S.—from Sarah, a skier and teen policymaker in New Hampshire, to Andraya, a track star in Connecticut openly transitioning into her authentic self. The film centers on Mack Beggs, who made headlines last year when he became the Texas State Champion in wrestling and was heralded as a hero by some while receiving hate and threats from others.
Trans athletes have to work harder than their cisgender peers in order to thrive in their field while also having the courage and resilience to face daily harassment and discrimination. The kids in this film have found sports as a way to channel the negativity around them into a positive, to gain a sense of self-worth and validation. This film is their urgent, articulate plea for acceptance.
Director: MICHAEL BARNETT
88 minutes | USA | 2019


Live assist is a real-time complement to your support program that utilizes the World wide web to give you with the quickly, friendly, one-on-one particular technical assistance you deserve. If you never have an accountant speak to us at Accounting Help – and we will clarify why you want an accountant and the likely fees. One more part of accounting involves compliance with government regulations pertaining to revenue tax reporting. Aid desk for Accounts and Invoice ManagementLarger organizations have a number of suppliers to handle and massive ledgers to be tracked, so that each payment is accomplished properly and in time.
Utilizing accounting and accounting computer software as a tool to grow a tiny company is mainly a foreign and unknown concept to several modest business owners. These organizations also install the most current software in your firm's premises that can support you to monitor your accounting records. There are even colleges and universities that now supply free recorded lectures, notes, and class videos.
We specialise in using cloud-based accounting solutions that make your life less difficult. Make contact with the professionals at ELO Prof LLC and to discuss what interim accounting services may well be proper for your organization or how we can offer you the accounting help you call for. As a expert intimately familiar with a business client's financials, stepping beyond tax prep and bookkeeping into a consultant role makes sense for each the client and your accounting practice. For some organizations, employing spreadsheets, or even handwritten ledgers, will do. For most, nevertheless, the ease and efficiency of accounting application make it the better choice. If you want to discover the fundamentals of accounting and bookkeeping or in fact find out how to do double entry bookkeeping you have discovered the appropriate internet site.
Jurnal adalah sebuah software akuntansi on-line untuk mengatur sistem pembukuan yang lebih baik bagi pemilik Usaha Kecil & Menengah. I've tried to offer you with links to some superb free accounting and bookkeeping coaching. The professionals functioning in these organizations help to kind the right organizational structure of the accounts division. Bookkeepers or anybody can update their skills or learn about accounting and bookkeeping by pursuing free on the internet accounting and bookkeeping courses. At M3 Accounting + Analytics, we go to great lengths to develop a team of professionals who will go the extra mile for you when resolving your support issues. Even when the firm desires to apply for a loan it is effortlessly sanctioned as the accounting help vendor ensures that every single and every single transaction is accurately maintained throughout the monetary year.
Vendor/Supplier Assist deskWhen managing a lot of suppliers/vendors, chances are higher that a handful of suppliers may possibly not be shown the right service which might have an effect on retention. We are driven to help make your company become more streamlined, far more efficient and of course, more profitable. As an seasoned group of On-line Accountants, we use cutting edge technology to provide you the most committed accounting assistance, adding true worth to your company exactly where it matters most. We can aid you deal with such items as e-shops and e-commerce, as well as how to link your on-line systems to your accounting technique. Subscribe and receive our newsletter with amazing accounting and enterprise suggestions delivered to your inbox each month.