text:
package com.handmark.pulltorefresh.library;

import mdn.vtvsport.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import com.handmark.pulltorefresh.library.internal.FlipLoadingLayout;
import com.handmark.pulltorefresh.library.internal.LoadingLayout;
import com.handmark.pulltorefresh.library.internal.RotateLoadingLayout;

public abstract class PullToRefreshBase<T extends View> extends LinearLayout
		implements IPullToRefresh<T> {
	// ===========================================================
	// Constants
	// ===========================================================

	static final boolean DEBUG = false;

	static final String LOG_TAG = "PullToRefresh";
	static final float FRICTION = 2.0f;

	public static final int SMOOTH_SCROLL_DURATION_MS = 200;
	public static final int SMOOTH_SCROLL_LONG_DURATION_MS = 325;

	static final Mode DEFAULT_MODE = Mode.PULL_DOWN_TO_REFRESH;

	static final String STATE_STATE = "ptr_state";
	static final String STATE_MODE = "ptr_mode";
	static final String STATE_CURRENT_MODE = "ptr_current_mode";
	static final String STATE_DISABLE_SCROLLING_REFRESHING = "ptr_disable_scrolling";
	static final String STATE_SHOW_REFRESHING_VIEW = "ptr_show_refreshing_view";
	static final String STATE_SUPER = "ptr_super";

	// ===========================================================
	// Fields
	// ===========================================================

	private int mTouchSlop;
	private float mLastMotionX;
	private float mLastMotionY;
	private float mInitialMotionY;

	private boolean mIsBeingDragged = false;
	private State mState = State.RESET;
	private Mode mMode = DEFAULT_MODE;

	private Mode mCurrentMode;
	T mRefreshableView;
	private FrameLayout mRefreshableViewWrapper;

	private boolean mShowViewWhileRefreshing = true;
	private boolean mDisableScrollingWhileRefreshing = true;
	private boolean mFilterTouchEvents = true;
	private boolean mOverScrollEnabled = true;

	private Interpolator mScrollAnimationInterpolator;
	private AnimationStyle mLoadingAnimationStyle;

	private LoadingLayout mHeaderLayout;
	private LoadingLayout mFooterLayout;

	private int mHeaderHeight;
	private int mFooterHeight;

	private OnRefreshListener<T> mOnRefreshListener;
	private OnRefreshListener2<T> mOnRefreshListener2;
	private OnPullEventListener<T> mOnPullEventListener;

	private SmoothScrollRunnable mCurrentSmoothScrollRunnable;

	// ===========================================================
	// Constructors
	// ===========================================================

	public PullToRefreshBase(Context context) {
		super(context);
		init(context, null);
	}

	public PullToRefreshBase(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context, attrs);
	}

	public PullToRefreshBase(Context context, Mode mode) {
		super(context);
		mMode = mode;
		init(context, null);
	}

	@Override
	public void addView(View child, int index, ViewGroup.LayoutParams params) {
		if (DEBUG) {
			Log.d(LOG_TAG, "addView: " + child.getClass().getSimpleName());
		}

		final T refreshableView = getRefreshableView();

		if (refreshableView instanceof ViewGroup) {
			((ViewGroup) refreshableView).addView(child, index, params);
		} else {
			throw new UnsupportedOperationException(
					"Refreshable View is not a ViewGroup so can't addView");
		}
	}

	@Override
	public final Mode getCurrentMode() {
		return mCurrentMode;
	}

	@Override
	public final boolean getFilterTouchEvents() {
		return mFilterTouchEvents;
	}

	@Override
	public final Mode getMode() {
		return mMode;
	}

	@Override
	public final T getRefreshableView() {
		return mRefreshableView;
	}

	@Override
	public final boolean getShowViewWhileRefreshing() {
		return mShowViewWhileRefreshing;
	}

	@Override
	public final State getState() {
		return mState;
	}

	/**
	 * @deprecated Use the value from getCurrentMode() instead
	 * @return true if the current mode is Mode.PULL_DOWN_TO_REFRESH
	 */
	public final boolean hasPullFromTop() {
		return mCurrentMode == Mode.PULL_DOWN_TO_REFRESH;
	}

	@Override
	public final boolean isDisableScrollingWhileRefreshing() {
		return mDisableScrollingWhileRefreshing;
	}

	@Override
	public final boolean isPullToRefreshEnabled() {
		return mMode != Mode.DISABLED;
	}

	@Override
	public final boolean isPullToRefreshOverScrollEnabled() {
		return VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD
				&& mOverScrollEnabled
				&& OverscrollHelper
						.isAndroidOverScrollEnabled(mRefreshableView);
	}

	@Override
	public final boolean isRefreshing() {
		return mState == State.REFRESHING || mState == State.MANUAL_REFRESHING;
	}

	@Override
	public final boolean onInterceptTouchEvent(MotionEvent event) {

		if (!isPullToRefreshEnabled()) {
			return false;
		}

		final int action = event.getAction();

		if (action == MotionEvent.ACTION_CANCEL
				|| action == MotionEvent.ACTION_UP) {
			mIsBeingDragged = false;
			return false;
		}

		if (action != MotionEvent.ACTION_DOWN && mIsBeingDragged) {
			return true;
		}

		switch (action) {
		case MotionEvent.ACTION_MOVE: {
			// If we're refreshing, and the flag is set. Eat all MOVE events
			if (mDisableScrollingWhileRefreshing && isRefreshing()) {
				return true;
			}

			if (isReadyForPull()) {
				final float y = event.getY();
				final float dy = y - mLastMotionY;
				final float yDiff = Math.abs(dy);
				final float xDiff = Math.abs(event.getX() - mLastMotionX);

				if (yDiff > mTouchSlop
						&& (!mFilterTouchEvents || yDiff > xDiff)) {
					if (mMode.canPullDown() && dy >= 1f && isReadyForPullDown()) {
						mLastMotionY = y;
						mIsBeingDragged = true;
						if (mMode == Mode.BOTH) {
							mCurrentMode = Mode.PULL_DOWN_TO_REFRESH;
						}
					} else if (mMode.canPullUp() && dy <= -1f
							&& isReadyForPullUp()) {
						mLastMotionY = y;
						mIsBeingDragged = true;
						if (mMode == Mode.BOTH) {
							mCurrentMode = Mode.PULL_UP_TO_REFRESH;
						}
					}
				}
			}
			break;
		}
		case MotionEvent.ACTION_DOWN: {
			if (isReadyForPull()) {
				mLastMotionY = mInitialMotionY = event.getY();
				mLastMotionX = event.getX();
				mIsBeingDragged = false;
			}
			break;
		}
		}

		return mIsBeingDragged;
	}

	@Override
	public final void onRefreshComplete() {
		if (isRefreshing()) {
			setState(State.RESET);
		}
	}

	@Override
	public final boolean onTouchEvent(MotionEvent event) {

		if (!isPullToRefreshEnabled()) {
			return false;
		}

		// If we're refreshing, and the flag is set. Eat the event
		if (mDisableScrollingWhileRefreshing && isRefreshing()) {
			return true;
		}

		if (event.getAction() == MotionEvent.ACTION_DOWN
				&& event.getEdgeFlags() != 0) {
			return false;
		}

		switch (event.getAction()) {
		case MotionEvent.ACTION_MOVE: {
			if (mIsBeingDragged) {
				mLastMotionY = event.getY();
				pullEvent();
				return true;
			}
			break;
		}

		case MotionEvent.ACTION_DOWN: {
			if (isReadyForPull()) {
				mLastMotionY = mInitialMotionY = event.getY();
				return true;
			}
			break;
		}

		case MotionEvent.ACTION_CANCEL:
		case MotionEvent.ACTION_UP: {
			if (mIsBeingDragged) {
				mIsBeingDragged = false;

				if (mState == State.RELEASE_TO_REFRESH) {

					if (null != mOnRefreshListener) {
						setState(State.REFRESHING, true);
						mOnRefreshListener.onRefresh(this);
						return true;

					} else if (null != mOnRefreshListener2) {
						setState(State.REFRESHING, true);
						if (mCurrentMode == Mode.PULL_DOWN_TO_REFRESH) {
							mOnRefreshListener2.onPullDownToRefresh(this);
						} else if (mCurrentMode == Mode.PULL_UP_TO_REFRESH) {
							mOnRefreshListener2.onPullUpToRefresh(this);
						}
						return true;
					}
				}

				// If we haven't returned by here, then we're not in a state
				// to pull, so just reset
				setState(State.RESET);

				return true;
			}
			break;
		}
		}

		return false;
	}

	@Override
	public final void setDisableScrollingWhileRefreshing(
			boolean disableScrollingWhileRefreshing) {
		mDisableScrollingWhileRefreshing = disableScrollingWhileRefreshing;
	}

	@Override
	public final void setFilterTouchEvents(boolean filterEvents) {
		mFilterTouchEvents = filterEvents;
	}

	@Override
	public void setLastUpdatedLabel(CharSequence label) {
		if (null != mHeaderLayout) {
			mHeaderLayout.setSubHeaderText(label);
		}
		if (null != mFooterLayout) {
			mFooterLayout.setSubHeaderText(label);
		}

		// Refresh Height as it may have changed
		refreshLoadingViewsHeight();
	}

	@Override
	public void setLoadingDrawable(Drawable drawable) {
		setLoadingDrawable(drawable, Mode.BOTH);
	}

	@Override
	public void setLoadingDrawable(Drawable drawable, Mode mode) {
		if (null != mHeaderLayout && mode.canPullDown()) {
			mHeaderLayout.setLoadingDrawable(drawable);
		}
		if (null != mFooterLayout && mode.canPullUp()) {
			mFooterLayout.setLoadingDrawable(drawable);
		}

		// The Loading Height may have changed, so refresh
		refreshLoadingViewsHeight();
	}

	@Override
	public void setLongClickable(boolean longClickable) {
		getRefreshableView().setLongClickable(longClickable);
	}

	@Override
	public final void setMode(Mode mode) {
		if (mode != mMode) {
			if (DEBUG) {
				Log.d(LOG_TAG, "Setting mode to: " + mode);
			}
			mMode = mode;
			updateUIForMode();
		}
	}

	public void setOnPullEventListener(OnPullEventListener<T> listener) {
		mOnPullEventListener = listener;
	}

	@Override
	public final void setOnRefreshListener(OnRefreshListener<T> listener) {
		mOnRefreshListener = listener;
		mOnRefreshListener2 = null;
	}

	@Override
	public final void setOnRefreshListener(OnRefreshListener2<T> listener) {
		mOnRefreshListener2 = listener;
		mOnRefreshListener = null;
	}

	@Override
	public void setPullLabel(CharSequence pullLabel) {
		setPullLabel(pullLabel, Mode.BOTH);
	}

	@Override
	public void setPullLabel(CharSequence pullLabel, Mode mode) {
		if (null != mHeaderLayout && mode.canPullDown()) {
			mHeaderLayout.setPullLabel(pullLabel);
		}
		if (null != mFooterLayout && mode.canPullUp()) {
			mFooterLayout.setPullLabel(pullLabel);
		}
	}

	/**
	 * @deprecated This simple calls setMode with an appropriate mode based on
	 *             the passed value.
	 *
	 * @param enable
	 *            Whether Pull-To-Refresh should be used
	 */
	public final void setPullToRefreshEnabled(boolean enable) {
		setMode(enable ? DEFAULT_MODE : Mode.DISABLED);
	}

	@Override
	public final void setPullToRefreshOverScrollEnabled(boolean enabled) {
		mOverScrollEnabled = enabled;
	}

	@Override
	public final void setRefreshing() {
		setRefreshing(true);
	}

	@Override
	public final void setRefreshing(boolean doScroll) {
		if (!isRefreshing()) {
			setState(State.MANUAL_REFRESHING, doScroll);
		}
	}

	@Override
	public void setRefreshingLabel(CharSequence refreshingLabel) {
		setRefreshingLabel(refreshingLabel, Mode.BOTH);
	}

	@Override
	public void setRefreshingLabel(CharSequence refreshingLabel, Mode mode) {
		if (null != mHeaderLayout && mode.canPullDown()) {
			mHeaderLayout.setRefreshingLabel(refreshingLabel);
		}
		if (null != mFooterLayout && mode.canPullUp()) {
			mFooterLayout.setRefreshingLabel(refreshingLabel);
		}
	}

	@Override
	public void setReleaseLabel(CharSequence releaseLabel) {
		setReleaseLabel(releaseLabel, Mode.BOTH);
	}

	@Override
	public void setReleaseLabel(CharSequence releaseLabel, Mode mode) {
		if (null != mHeaderLayout && mode.canPullDown()) {
			mHeaderLayout.setReleaseLabel(releaseLabel);
		}
		if (null != mFooterLayout && mode.canPullUp()) {
			mFooterLayout.setReleaseLabel(releaseLabel);
		}
	}

	public void setScrollAnimationInterpolator(Interpolator interpolator) {
		mScrollAnimationInterpolator = interpolator;
	}

	@Override
	public final void setShowViewWhileRefreshing(boolean showView) {
		mShowViewWhileRefreshing = showView;
	}

	/**
	 * Called when the UI has been to be updated to be in the
	 * {@link State#PULL_TO_REFRESH} state.
	 */
	void onPullToRefresh() {
		switch (mCurrentMode) {
		case PULL_UP_TO_REFRESH:
			mFooterLayout.pullToRefresh();
			break;
		case PULL_DOWN_TO_REFRESH:
			mHeaderLayout.pullToRefresh();
			break;
		}
	}

	/**
	 * Called when the UI has been to be updated to be in the
	 * {@link State#REFRESHING} or {@link State#MANUAL_REFRESHING} state.
	 *
	 * @param doScroll
	 *            - Whether the UI should scroll for this event.
	 */
	void onRefreshing(final boolean doScroll) {
		if (mMode.canPullDown()) {
			mHeaderLayout.refreshing();
		}
		if (mMode.canPullUp()) {
			mFooterLayout.refreshing();
		}

		if (doScroll) {
			if (mShowViewWhileRefreshing) {
				smoothScrollTo(mCurrentMode == Mode.PULL_DOWN_TO_REFRESH ? -mHeaderHeight
						: mFooterHeight);
			} else {
				smoothScrollTo(0);
			}
		}

		// Call the deprecated method
		setRefreshingInternal(doScroll);
	}

	/**
	 * Called when the UI has been to be updated to be in the
	 * {@link State#RELEASE_TO_REFRESH} state.
	 */
	void onReleaseToRefresh() {
		switch (mCurrentMode) {
		case PULL_UP_TO_REFRESH:
			mFooterLayout.releaseToRefresh();
			break;
		case PULL_DOWN_TO_REFRESH:
			mHeaderLayout.releaseToRefresh();
			break;
		}
	}

	/**
	 * Called when the UI has been to be updated to be in the
	 * {@link State#RESET} state.
	 */
	void onReset() {
		mIsBeingDragged = false;

		if (mMode.canPullDown()) {
			mHeaderLayout.reset();
		}
		if (mMode.canPullUp()) {
			mFooterLayout.reset();
		}

		smoothScrollTo(0);

		// Call the deprecated method
		resetHeader();
	}

	/**
	 * Used internally for adding view. Need because we override addView to
	 * pass-through to the Refreshable View
	 */
	protected final void addViewInternal(View child, int index,
			ViewGroup.LayoutParams params) {
		super.addView(child, index, params);
	}

	/**
	 * Used internally for adding view. Need because we override addView to
	 * pass-through to the Refreshable View
	 */
	protected final void addViewInternal(View child,
			ViewGroup.LayoutParams params) {
		super.addView(child, -1, params);
	}

	protected LoadingLayout createLoadingLayout(Context context, Mode mode,
			TypedArray attrs) {
		return mLoadingAnimationStyle.createLoadingLayout(context, mode, attrs);
	}

	/**
	 * This is implemented by derived classes to return the created View. If you
	 * need to use a custom View (such as a custom ListView), override this
	 * method and return an instance of your custom class.
	 *
	 * Be sure to set the ID of the view in this method, especially if you're
	 * using a ListActivity or ListFragment.
	 *
	 * @param context
	 *            Context to create view with
	 * @param attrs
	 *            AttributeSet from wrapped class. Means that anything you
	 *            include in the XML layout declaration will be routed to the
	 *            created View
	 * @return New instance of the Refreshable View
	 */
	protected abstract T createRefreshableView(Context context,
			AttributeSet attrs);

	protected final int getFooterHeight() {
		return mFooterHeight;
	}

	protected final LoadingLayout getFooterLayout() {
		return mFooterLayout;
	}

	protected final int getHeaderHeight() {
		return mHeaderHeight;
	}

	protected final LoadingLayout getHeaderLayout() {
		return mHeaderLayout;
	}

	protected int getPullToRefreshScrollDuration() {
		return SMOOTH_SCROLL_DURATION_MS;
	}

	protected int getPullToRefreshScrollDurationLonger() {
		return SMOOTH_SCROLL_LONG_DURATION_MS;
	}

	protected FrameLayout getRefreshableViewWrapper() {
		return mRefreshableViewWrapper;
	}

	/**
	 * Allows Derivative classes to handle the XML Attrs without creating a
	 * TypedArray themsevles
	 *
	 * @param a
	 *            - TypedArray of PullToRefresh Attributes
	 */
	protected void handleStyledAttributes(TypedArray a) {
	}

	/**
	 * Implemented by derived class to return whether the View is in a mState
	 * where the user can Pull to Refresh by scrolling down.
	 *
	 * @return true if the View is currently the correct mState (for example,
	 *         top of a ListView)
	 */
	protected abstract boolean isReadyForPullDown();

	/**
	 * Implemented by derived class to return whether the View is in a mState
	 * where the user can Pull to Refresh by scrolling up.
	 *
	 * @return true if the View is currently in the correct mState (for example,
	 *         bottom of a ListView)
	 */
	protected abstract boolean isReadyForPullUp();

	/**
	 * Called by {@link #onRestoreInstanceState(Parcelable)} so that derivative
	 * classes can handle their saved instance state.
	 *
	 * @param savedInstanceState
	 *            - Bundle which contains saved instance state.
	 */
	protected void onPtrRestoreInstanceState(Bundle savedInstanceState) {
	}

	/**
	 * Called by {@link #onSaveInstanceState()} so that derivative classes can
	 * save their instance state.
	 *
	 * @param saveState
	 *            - Bundle to be updated with saved state.
	 */
	protected void onPtrSaveInstanceState(Bundle saveState) {
	}

	@Override
	protected final void onRestoreInstanceState(Parcelable state) {
		if (state instanceof Bundle) {
			Bundle bundle = (Bundle) state;

			mMode = Mode.mapIntToValue(bundle.getInt(STATE_MODE, 0));
			mCurrentMode = Mode.mapIntToValue(bundle.getInt(STATE_CURRENT_MODE,
					0));

			mDisableScrollingWhileRefreshing = bundle.getBoolean(
					STATE_DISABLE_SCROLLING_REFRESHING, true);
			mShowViewWhileRefreshing = bundle.getBoolean(
					STATE_SHOW_REFRESHING_VIEW, true);

			// Let super Restore Itself
			super.onRestoreInstanceState(bundle.getParcelable(STATE_SUPER));

			State viewState = State
					.mapIntToValue(bundle.getInt(STATE_STATE, 0));
			if (viewState == State.REFRESHING
					|| viewState == State.MANUAL_REFRESHING) {
				setState(viewState, true);
			}

			// Now let derivative classes restore their state
			onPtrRestoreInstanceState(bundle);
			return;
		}

		super.onRestoreInstanceState(state);
	}

	@Override
	protected final Parcelable onSaveInstanceState() {
		Bundle bundle = new Bundle();

		// Let derivative classes get a chance to save state first, that way we
		// can make sure they don't overrite any of our values
		onPtrSaveInstanceState(bundle);

		bundle.putInt(STATE_STATE, mState.getIntValue());
		bundle.putInt(STATE_MODE, mMode.getIntValue());
		bundle.putInt(STATE_CURRENT_MODE, mCurrentMode.getIntValue());
		bundle.putBoolean(STATE_DISABLE_SCROLLING_REFRESHING,
				mDisableScrollingWhileRefreshing);
		bundle.putBoolean(STATE_SHOW_REFRESHING_VIEW, mShowViewWhileRefreshing);
		bundle.putParcelable(STATE_SUPER, super.onSaveInstanceState());

		return bundle;
	}

	/**
	 * @deprecated This is a deprecated callback. If you're overriding this
	 *             method then use
	 *             {@link #setOnPullEventListener(OnPullEventListener)
	 *             setOnPullEventListener()} instead to be notified when the
	 *             state changes to {@link State#RESET RESET}. This deprecated
	 *             method will be removed in the future.
	 */
	protected void resetHeader() {
	}

	/**
	 * Helper method which just calls scrollTo() but with a zero x value.
	 *
	 * @param y
	 */
	protected final void setHeaderScroll(int y) {
		scrollTo(0, y);
	}

	/**
	 * @deprecated This is a deprecated callback. If you're overriding this
	 *             method then use
	 *             {@link #setOnPullEventListener(OnPullEventListener)
	 *             setOnPullEventListener()} instead to be notified when the
	 *             state changes to {@link State#REFRESHING REFRESHING} or
	 *             {@link State#MANUAL_REFRESHING MANUAL_REFRESHING}. This
	 *             deprecated method will be removed in the future.
	 */
	protected void setRefreshingInternal(final boolean doScroll) {
	}

	/**
	 * Smooth Scroll to Y position using the default duration of
	 * {@value #SMOOTH_SCROLL_DURATION_MS} ms.
	 *
	 * @param y
	 *            - Y position to scroll to
	 */
	protected final void smoothScrollTo(int y) {
		smoothScrollTo(y, getPullToRefreshScrollDuration());
	}

	/**
	 * Smooth Scroll to Y position using the longer default duration of
	 * {@value #SMOOTH_SCROLL_LONG_DURATION_MS} ms.
	 *
	 * @param y
	 *            - Y position to scroll to
	 */
	protected final void smoothScrollToLonger(int y) {
		smoothScrollTo(y, getPullToRefreshScrollDurationLonger());
	}

	/**
	 * Updates the View State when the mode has been set. This does not do any
	 * checking that the mode is different to current state so always updates.
	 */
	protected void updateUIForMode() {
		// Remove Header, and then add Header Loading View again if needed
		if (this == mHeaderLayout.getParent()) {
			removeView(mHeaderLayout);
		}
		if (mMode.canPullDown()) {
			addViewInternal(mHeaderLayout, 0, new LinearLayout.LayoutParams(
					ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT));
		}

		// Remove Footer, and then add Footer Loading View again if needed
		if (this == mFooterLayout.getParent()) {
			removeView(mFooterLayout);
		}
		if (mMode.canPullUp()) {
			addViewInternal(mFooterLayout, new LinearLayout.LayoutParams(
					ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT));
		}

		// Hide Loading Views
		refreshLoadingViewsHeight();

		// If we're not using Mode.BOTH, set mCurrentMode to mMode, otherwise
		// set it to pull down
		mCurrentMode = (mMode != Mode.BOTH) ? mMode : Mode.PULL_DOWN_TO_REFRESH;
	}

	private void addRefreshableView(Context context, T refreshableView) {
		mRefreshableViewWrapper = new FrameLayout(context);
		mRefreshableViewWrapper.addView(refreshableView,
				ViewGroup.LayoutParams.MATCH_PARENT,
				ViewGroup.LayoutParams.MATCH_PARENT);
		addViewInternal(mRefreshableViewWrapper, new LinearLayout.LayoutParams(
				LayoutParams.MATCH_PARENT, 0, 1.0f));
	}

	@SuppressWarnings("deprecation")
	private void init(Context context, AttributeSet attrs) {
		setOrientation(LinearLayout.VERTICAL);

		ViewConfiguration config = ViewConfiguration.get(context);
		mTouchSlop = config.getScaledTouchSlop();

		// Styleables from XML
		TypedArray a = context.obtainStyledAttributes(attrs,
				R.styleable.PullToRefresh);

		if (a.hasValue(R.styleable.PullToRefresh_ptrMode)) {
			mMode = Mode.mapIntToValue(a.getInteger(
					R.styleable.PullToRefresh_ptrMode, 0));
		}

		mLoadingAnimationStyle = AnimationStyle.mapIntToValue(a.getInteger(
				R.styleable.PullToRefresh_ptrAnimationStyle, 1));

		// Refreshable View
		// By passing the attrs, we can add ListView/GridView params via XML
		mRefreshableView = createRefreshableView(context, attrs);
		addRefreshableView(context, mRefreshableView);

		// We need to create now layouts now
		mHeaderLayout = createLoadingLayout(context, Mode.PULL_DOWN_TO_REFRESH,
				a);
		mFooterLayout = createLoadingLayout(context, Mode.PULL_UP_TO_REFRESH, a);

		// Styleables from XML
		if (a.hasValue(R.styleable.PullToRefresh_ptrHeaderBackground)) {
			Drawable background = a
					.getDrawable(R.styleable.PullToRefresh_ptrHeaderBackground);
			if (null != background) {
				setBackgroundDrawable(background);
			}
		}
		if (a.hasValue(R.styleable.PullToRefresh_ptrAdapterViewBackground)) {
			Drawable background = a
					.getDrawable(R.styleable.PullToRefresh_ptrAdapterViewBackground);
			if (null != background) {
				mRefreshableView.setBackgroundDrawable(background);
			}
		}
		if (a.hasValue(R.styleable.PullToRefresh_ptrOverScroll)) {
			mOverScrollEnabled = a.getBoolean(
					R.styleable.PullToRefresh_ptrOverScroll, true);
		}

		// Let the derivative classes have a go at handling attributes, then
		// recycle them...
		handleStyledAttributes(a);
		a.recycle();

		// Finally update the UI for the modes
		updateUIForMode();
	}

	private boolean isReadyForPull() {
		switch (mMode) {
		case PULL_DOWN_TO_REFRESH:
			return isReadyForPullDown();
		case PULL_UP_TO_REFRESH:
			return isReadyForPullUp();
		case BOTH:
			return isReadyForPullUp() || isReadyForPullDown();
		}
		return false;
	}

	private void measureView(View child) {
		ViewGroup.LayoutParams p = child.getLayoutParams();
		if (p == null) {
			p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
		}

		int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, p.width);
		int lpHeight = p.height;
		int childHeightSpec;
		if (lpHeight > 0) {
			childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
					MeasureSpec.EXACTLY);
		} else {
			childHeightSpec = MeasureSpec.makeMeasureSpec(0,
					MeasureSpec.UNSPECIFIED);
		}
		child.measure(childWidthSpec, childHeightSpec);
	}

	/**
	 * Actions a Pull Event
	 *
	 * @return true if the Event has been handled, false if there has been no
	 *         change
	 */
	private void pullEvent() {
		final int newScrollY;
		final int itemHeight;

		switch (mCurrentMode) {
		case PULL_UP_TO_REFRESH:
			newScrollY = Math.round(Math.max(mInitialMotionY - mLastMotionY, 0)
					/ FRICTION);
			itemHeight = mFooterHeight;
			break;
		case PULL_DOWN_TO_REFRESH:
		default:
			newScrollY = Math.round(Math.min(mInitialMotionY - mLastMotionY, 0)
					/ FRICTION);
			itemHeight = mHeaderHeight;
			break;
		}

		setHeaderScroll(newScrollY);

		if (newScrollY != 0) {
			float scale = Math.abs(newScrollY) / (float) itemHeight;
			switch (mCurrentMode) {
			case PULL_UP_TO_REFRESH:
				mFooterLayout.onPullY(scale);
				break;
			case PULL_DOWN_TO_REFRESH:
				mHeaderLayout.onPullY(scale);
				break;
			}

			if (mState != State.PULL_TO_REFRESH
					&& itemHeight >= Math.abs(newScrollY)) {
				setState(State.PULL_TO_REFRESH);
			} else if (mState == State.PULL_TO_REFRESH
					&& itemHeight < Math.abs(newScrollY)) {
				setState(State.RELEASE_TO_REFRESH);
			}
		}
	}

	/**
	 * Re-measure the Loading Views height, and adjust internal padding as
	 * necessary
	 */
	private void refreshLoadingViewsHeight() {
		mHeaderHeight = mFooterHeight = 0;

		if (mMode.canPullDown()) {
			measureView(mHeaderLayout);
			mHeaderHeight = mHeaderLayout.getMeasuredHeight();
		}
		if (mMode.canPullUp()) {
			measureView(mFooterLayout);
			mFooterHeight = mFooterLayout.getMeasuredHeight();
		}

		// Hide Loading Views
		switch (mMode) {
		case DISABLED:
			setPadding(0, 0, 0, 0);
		case BOTH:
			setPadding(0, -mHeaderHeight, 0, -mFooterHeight);
			break;
		case PULL_UP_TO_REFRESH:
			setPadding(0, 0, 0, -mFooterHeight);
			break;
		case PULL_DOWN_TO_REFRESH:
		default:
			setPadding(0, -mHeaderHeight, 0, 0);
			break;
		}
	}

	private void setState(State state, final boolean... params) {
		mState = state;
		if (DEBUG) {
			Log.d(LOG_TAG, "State: " + mState.name());
		}

		switch (mState) {
		case RESET:
			onReset();
			break;
		case PULL_TO_REFRESH:
			onPullToRefresh();
			break;
		case RELEASE_TO_REFRESH:
			onReleaseToRefresh();
			break;
		case REFRESHING:
		case MANUAL_REFRESHING:
			onRefreshing(params[0]);
			break;
		}

		// Call OnPullEventListener
		if (null != mOnPullEventListener) {
			mOnPullEventListener.onPullEvent(this, mState, mCurrentMode);
		}
	}

	/**
	 * Smooth Scroll to Y position using the specific duration
	 *
	 * @param y
	 *            - Y position to scroll to
	 * @param duration
	 *            - Duration of animation in milliseconds
	 */
	private final void smoothScrollTo(int y, long duration) {
		if (null != mCurrentSmoothScrollRunnable) {
			mCurrentSmoothScrollRunnable.stop();
		}

		if (getScrollY() != y) {
			if (null == mScrollAnimationInterpolator) {
				// Default interpolator is a Decelerate Interpolator
				mScrollAnimationInterpolator = new DecelerateInterpolator();
			}
			mCurrentSmoothScrollRunnable = new SmoothScrollRunnable(
					getScrollY(), y, duration);
			post(mCurrentSmoothScrollRunnable);
		}
	}

	public static enum AnimationStyle {
		/**
		 * This is the default for Android-PullToRefresh. Allows you to use any
		 * drawable, which is automatically rotated and used as a Progress Bar.
		 */
		ROTATE,

		/**
		 * This is the old default, and what is commonly used on iOS. Uses an
		 * arrow image which flips depending on where the user has scrolled.
		 */
		FLIP;

		/**
		 * Maps an int to a specific mode. This is needed when saving state, or
		 * inflating the view from XML where the mode is given through a attr
		 * int.
		 *
		 * @param modeInt
		 *            - int to map a Mode to
		 * @return Mode that modeInt maps to, or PULL_DOWN_TO_REFRESH by
		 *         default.
		 */
		public static AnimationStyle mapIntToValue(int modeInt) {
			switch (modeInt) {
			case 0x0:
			default:
				return ROTATE;
			case 0x1:
				return FLIP;
			}
		}

		public LoadingLayout createLoadingLayout(Context context, Mode mode,
				TypedArray attrs) {
			switch (this) {
			case ROTATE:
			default:
				return new RotateLoadingLayout(context, mode, attrs);
			case FLIP:
				return new FlipLoadingLayout(context, mode, attrs);
			}
		}
	}

	public static enum Mode {
		/**
		 * Disable all Pull-to-Refresh gesture handling
		 */
		DISABLED(0x0),

		/**
		 * Only allow the user to Pull Down from the top to refresh, this is the
		 * default.
		 */
		PULL_DOWN_TO_REFRESH(0x1),

		/**
		 * Only allow the user to Pull Up from the bottom to refresh.
		 */
		PULL_UP_TO_REFRESH(0x2),

		/**
		 * Allow the user to both Pull Down from the top, and Pull Up from the
		 * bottom to refresh.
		 */
		BOTH(0x3);

		/**
		 * Maps an int to a specific mode. This is needed when saving state, or
		 * inflating the view from XML where the mode is given through a attr
		 * int.
		 *
		 * @param modeInt
		 *            - int to map a Mode to
		 * @return Mode that modeInt maps to, or PULL_DOWN_TO_REFRESH by
		 *         default.
		 */
		public static Mode mapIntToValue(int modeInt) {
			switch (modeInt) {
			case 0x0:
				return DISABLED;
			case 0x1:
			default:
				return PULL_DOWN_TO_REFRESH;
			case 0x2:
				return PULL_UP_TO_REFRESH;
			case 0x3:
				return BOTH;
			}
		}

		private int mIntValue;

		// The modeInt values need to match those from attrs.xml
		Mode(int modeInt) {
			mIntValue = modeInt;
		}

		/**
		 * @return true if this mode permits Pulling Down from the top
		 */
		boolean canPullDown() {
			return this == PULL_DOWN_TO_REFRESH || this == BOTH;
		}

		/**
		 * @return true if this mode permits Pulling Up from the bottom
		 */
		boolean canPullUp() {
			return this == PULL_UP_TO_REFRESH || this == BOTH;
		}

		int getIntValue() {
			return mIntValue;
		}

	}

	/**
	 * Simple Listener that allows you to be notified when the user has scrolled
	 * to the end of the AdapterView. See (
	 * {@link PullToRefreshAdapterViewBase#setOnLastItemVisibleListener}.
	 *
	 * @author Chris Banes
	 *
	 */
	public static interface OnLastItemVisibleListener {

		/**
		 * Called when the user has scrolled to the end of the list
		 */
		public void onLastItemVisible();

	}

	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================

	/**
	 * Listener that allows you to be notified when the user has started or
	 * finished a touch event. Useful when you want to append extra UI events
	 * (such as sounds). See (
	 * {@link PullToRefreshAdapterViewBase#setOnPullEventListener}.
	 *
	 * @author Chris Banes
	 *
	 */
	public static interface OnPullEventListener<V extends View> {

		/**
		 * Called when the internal state has been changed, usually by the user
		 * pulling.
		 *
		 * @param refreshView
		 *            - View which has had it's state change.
		 * @param state
		 *            - The new state of View.
		 * @param direction
		 *            - One of {@link Mode#PULL_UP_TO_REFRESH} or
		 *            {@link Mode#PULL_UP_TO_REFRESH} depending on which
		 *            direction the user is pulling. Only useful when
		 *            <var>state</var> is {@link State#PULL_TO_REFRESH} or
		 *            {@link State#RELEASE_TO_REFRESH}.
		 */
		public void onPullEvent(final PullToRefreshBase<V> refreshView,
				State state, Mode direction);

	}

	/**
	 * Simple Listener to listen for any callbacks to Refresh.
	 *
	 * @author Chris Banes
	 */
	public static interface OnRefreshListener<V extends View> {

		/**
		 * onRefresh will be called for both Pull Down from top, and Pull Up
		 * from Bottom
		 */
		public void onRefresh(final PullToRefreshBase<V> refreshView);

	}

	/**
	 * An advanced version of the Listener to listen for callbacks to Refresh.
	 * This listener is different as it allows you to differentiate between Pull
	 * Ups, and Pull Downs.
	 *
	 * @author Chris Banes
	 */
	public static interface OnRefreshListener2<V extends View> {

		/**
		 * onPullDownToRefresh will be called only when the user has Pulled Down
		 * from the top, and released.
		 */
		public void onPullDownToRefresh(final PullToRefreshBase<V> refreshView);

		/**
		 * onPullUpToRefresh will be called only when the user has Pulled Up
		 * from the bottom, and released.
		 */
		public void onPullUpToRefresh(final PullToRefreshBase<V> refreshView);

	}

	public static enum State {

		/**
		 * When the UI is in a state which means that user is not interacting
		 * with the Pull-to-Refresh function.
		 */
		RESET(0x0),

		/**
		 * When the UI is being pulled by the user, but has not been pulled far
		 * enough so that it refreshes when released.
		 */
		PULL_TO_REFRESH(0x1),

		/**
		 * When the UI is being pulled by the user, and has
		 * been pulled far enough so that it will refresh when released.
		 */
		RELEASE_TO_REFRESH(0x2),

		/**
		 * When the UI is currently refreshing, caused by a pull gesture.
		 */
		REFRESHING(0x8),

		/**
		 * When the UI is currently refreshing, caused by a call to
		 * {@link PullToRefreshBase#setRefreshing() setRefreshing()}.
		 */
		MANUAL_REFRESHING(0x9);

		/**
		 * Maps an int to a specific state. This is needed when saving state.
		 *
		 * @param stateInt
		 *            - int to map a State to
		 * @return State that stateInt maps to
		 */
		public static State mapIntToValue(int stateInt) {
			switch (stateInt) {
			default:
			case 0x0:
				return RESET;
			case 0x1:
				return PULL_TO_REFRESH;
			case 0x2:
				return RELEASE_TO_REFRESH;
			case 0x8:
				return REFRESHING;
			case 0x9:
				return MANUAL_REFRESHING;
			}
		}

		private int mIntValue;

		State(int intValue) {
			mIntValue = intValue;
		}

		int getIntValue() {
			return mIntValue;
		}
	}

	final class SmoothScrollRunnable implements Runnable {

		static final int ANIMATION_DELAY = 10;

		private final Interpolator mInterpolator;
		private final int mScrollToY;
		private final int mScrollFromY;
		private final long mDuration;

		private boolean mContinueRunning = true;
		private long mStartTime = -1;
		private int mCurrentY = -1;

		public SmoothScrollRunnable(int fromY, int toY, long duration) {
			mScrollFromY = fromY;
			mScrollToY = toY;
			mInterpolator = mScrollAnimationInterpolator;
			mDuration = duration;
		}

		@Override
		public void run() {

			/**
			 * Only set mStartTime if this is the first time we're starting,
			 * else actually calculate the Y delta
			 */
			if (mStartTime == -1) {
				mStartTime = System.currentTimeMillis();
			} else {

				/**
				 * We do do all calculations in long to reduce software float
				 * calculations. We use 1000 as it gives us good accuracy and
				 * small rounding errors
				 */
				long normalizedTime = (1000 * (System.currentTimeMillis() - mStartTime))
						/ mDuration;
				normalizedTime = Math.max(Math.min(normalizedTime, 1000), 0);

				final int deltaY = Math.round((mScrollFromY - mScrollToY)
						* mInterpolator
								.getInterpolation(normalizedTime / 1000f));
				mCurrentY = mScrollFromY - deltaY;
				setHeaderScroll(mCurrentY);
			}

			// If we're not at the target Y, keep going...
			if (mContinueRunning && mScrollToY != mCurrentY) {
				// if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
				// SDK16.postOnAnimation(PullToRefreshBase.this, this);
				// } else {
				postDelayed(this, ANIMATION_DELAY);
				// }
			}
		}

		public void stop() {
			mContinueRunning = false;
			removeCallbacks(this);
		}
	}

}

redpajama_set_name: RedPajamaGithub


My novel is more than 170,000 words without the back story, which I had to cull because it was 70,000 words. I tried eliminating it; the book was a shallow disaster. I've tried summarising; it interrupted the story without explaining what was going on. The problem is that the culture and setting are predicated on an event 70 years before the story begins. This is key to the protagonist's behaviour, attitude and circumstances.
The villain is involved 5 years before the story starts and works behind the scenes against the protagonist, who thinks the villain is dead. But if I don't introduce the back story involving him, a lot of the story doesn't make sense and characters' reactions are hard to understand – especially in later books. I'm grateful for any suggestions.
Wow, Henry, I can see you've got a lot to squeeze in. And it's far too much for the reader to catch up with. We need to restructure your story. This is what I would do.
DOES the story have to be this complex? Has it run away with you as you've added events and complications?
I frequently get myself into this kind of fix. I invent far more than I need. At some stage, I take a hard look and decide what I can streamline.
Take a blank sheet of paper and write down only the most important pieces of history. How do you decide that those are? They're what help your readers understand the problems of your protagonist.
From other information you've told me, I know you're writing a dystopia. There's no better model than other novels that do it well – try Fahrenheit 451 and Nineteen Eighty-Four. Both have a heck of a lot of explaining to do, but never overwhelm the reader. They begin with the protagonist on an ordinary day, coping with a feeling they don't fit with the world. This is accessible and relatable to everyone, and lets the reader connect with the character's humanity. So look at your world's problems in terms of what disturbs or distresses your protagonist in their normal life.
Both those novels do eventually reveal a lot of back story. We do get to World 101 – why it's in such a mess, on a knife edge and who made it that way. But we don't find out for some considerable time. First, we bed in with the characters. When the larger chunks of back story are revealed, they are parallel to the protagonist's state of mind. They come at a stage where the character is curious to ask these deeper questions: how did we go so wrong? How can I get out of it?
If you do this, you will see how little of your back story you need to get the plot running. Concentrate on the characters and what makes life hard for them – and preferably harder than for other people in the story, so that they are the canary in the coal mine. The protagonists of Fahrenheit 451 and Nineteen Eighty-Four are first and foremost unhappy misfits. Second, they are echoing a sense of humanity gone wrong.
Even so, the authors might not have told us everything they had developed. So while you're simplifying, look out for ideas you could leave out (even if you're proud of them).
You made the back story this complex because it interests you, right? It's become as important as the present story.
For instance, your villain had his heyday before your narrative starts. Why not write that story? And the main events happened 70 years before – that could be another story.
You could twine them together as parallel narratives – like The Godfather. Vito Corleone's life is one strand: his son, Michael Corleone, is living in the world Vito made.
Now I can understand why you might not have thought to spotlight these stories. The outcomes, as we know, must be that baddies triumphed – a downbeat ending. But some books go like that – especially books about worlds. Think of A Game of Thrones – an epic series where some characters succeed and some fail. Your villain's victory could surely be a dramatic story. People must have opposed him; he can't have got away without a fight. Even if he succeeds, you could also suggest a twinkle of hope, a scrap of resistance that won't stay quiet for ever.
You could also begin with a character growing up in the world, and having it explained – like Suldrun in Jack Vance's Lyonesse series.
What would you say to Henry? Are there any books you would add to his reading list? Share in the comments!
Dystopias, Nineteen-Eighty-Four and Fahrenheit 451 are among the books and topics tackled in Nail Your Novel: Bring Characters to Life. Out now in all formats, including (ahem) combustible.
I've had this question from Kate Calcutt.
How important is the title of a book?
The more famous you are, the less hard your title has to work. Iain Banks graduated from The Wasp Factory to The Business. Would you have picked up The Business if it had been his first? Barbara Vine gets away with No Night Is Too Long because her name already tells readers what they're getting. Which is just as well because No Night Is Too Long has zero stopping power and is darn hard to remember.
If you've got a long-running series, you can coast with the later titles. The first needs to audition with bells and whistles, but later titles can trade on insider knowledge. Mockingjay would be a challenge to remember unless you'd been primed by The Hunger Games. But it's really a title that says 'welcome back'.
But if you don't have much already on the shelves, your title is your one chance to make a reader stop and consider spending time with you. It is your novel's chat-up line in a place with hundreds of suitors. It needs to thrum with promise, intrigue.
Kate also said: I'm considering a title change from 'In the Background', to 'Life, Captured'.
I'm afraid both of those fall at the first hurdle. They're so vague that they can't give a flavour of the book, and a reader is likely to pass them by in favour of a title that makes a strong case for what it's about. Both these titles could describe just about any story.
Now, you might argue that we want our books to appeal to the widest number of readers. And I'm sure if there was a genre category called 'for anyone who likes a good read' we would all hope our book belonged in it. But marketing can't be about 'vagueness' or 'everyone'. It's about specifics, individuals and distinctiveness.
So what are the specifics of Kate's book? She described her novel to me as contemporary female fiction – the story of a woman's life as observed by those in the background of her holiday photos.
Now this is an interesting concept and I can understand why she's toying with those titles. But they didn't make me want to pick the book up. In The Background might work with a stunning cover. But titles are seen just as often without their artwork, so we can't rely on that.
So what shall we do to find a better title? We need to brainstorm.
I'm not saying I'll get a better title in this post, but here's a starter. Only Kate knows what really mirrors the soul of the book.
Find words that suggest photos, snapshots, images, likenesses, portraits. Exposure. Shot. Frame. Lens. Subject. Picture. I got down to 'image' and I found 'angel' – a nice emotive word. Photos aren't the only interesting concept here. Let's look up watchers, onlookers, witnesses. And moments. Even jigsaws, as this novel seems to present a life in pieces. Or chorus, as the piecemeal narrative is like the commentary of a Greek chorus. What about biography, as it's the story of a life? Make a huge list of possible nouns.
Now start another list of verbs and adjectives that could go with those. You're looking for something surprising or emotive. The blurred girl? Background is a good word if we use it strongly. Could that go with something?
Don't stop with single words. List questions, enigmas, dilemmas that might arise from the book's concept.
Find idioms that use all the words you've listed. And book titles – Amazon is useful for this, as is my beloved Library Thing. Song titles too. As good titles set up a frisson, you can get a powerful effect from altering a phrase that's already familiar. Look at Anthony Burgess showing off (as ever) with a novel called Nineteen Eighty-Five.
In my scoot around LibraryThing I found a novel called Autobiography of a Family Photo by Jacqueline Woodson. That's got an intriguing vibe so it's definitely worth looking at other titles that are similar. There's also The Photograph by Penelope Lively. The descriptions of these two novels necessarily explain the title, which could give you extra ideas to explore.
The perfect title might already be in your novel, hidden in a line of dialogue, or introspection, or a description.
Your book needs to woo the right kind of readers, so you need to capture the right tone. Note, especially, the emotions that titles evoke – that's the promise to the reader. And avoid misleading ones. Although 'witness' is good for the brainstorming list, if you put it in the title you might give the impression that it's a crime novel.
Write a shortlist of titles. Force yourself to come up with many more than you need. Then put them away and come back when you've forgotten what they are. Try the best ones out on friends, then go back to Amazon to see how your shortlist compares with the books already out in the marketplace.
You'll find some more notes on titles in this post by Ray Harvey aka Journal Pulp.
Do you struggle to think up titles? Do you have any tips? Share in the comments! And if you want to continue brainstorming Kate's book – or if you think of a possible title share it here!
Got to explain my story's world… but how do I avoid exposition?
I have a client who has written an ambitious novel set in a dystopia. It's a powerful idea, but he hadn't made me understand the world. I was constantly confused about what the characters were doing and why the scenes he showed me were significant.
He explained he was trying to avoid exposition – for which he gets a stack of brownie points, if not actual brownies. But how should he fill the gaps?
Neither of us even uttered the words 'explanatory prologue'. I'm saying them here for the sake of completeness. A prologue describing the world is not, generally, a good way to captivate a reader. They want to plunge into the story and bond with characters, not sit down for a lecture.
Exposition is when the author tells the reader something they need to understand and is obvious about it. So a pair of characters natter about a subject they don't need to talk about. 'I have to go and clean the neutron drive, Susan. As you know, we're on a big spaceship and have been for many months.' Unless the line is to show an ironic character quirk, this is the author shoving his face between the characters.
But if you give the reader too little context, they don't know where they are or what anything means to the characters. Yours truly, Baffled.
The only sin of exposition is that it is unnatural. So you find ways to slip this material in without breaking the fourth wall.
If the world is new to the character, like Harry Potter's entrance to Hogwarts, your task is simple. Get the reader curious, then show them all the mad stuff. But if the world isn't new to the character, you have to be more subtle.
Here's how George Orwell does it in Nineteen Eighty-Four.
He begins with a tour of Winston Smith's ordinary life. We have a day in April (relatable, familiar) and clocks striking thirteen (borderline normal, and strange enough to intrigue us). Winston is hurrying along in the wind to his grotty apartment block (normal). The lift is out of order (relatable) because of Hate Week (crikey, what's that?). There's a poster: 'Big Brother is Watching You' (intriguing and sinister). Inside his mostly familiar apartment is a telescreen, which he can't turn off (weird). Outside his window there's a sign in a distorted form of English (skewed and forbidding). He tries to find a place where the screen can't see him (exactly as we might, because it isn't nice being watched). Why is he hiding? To do something we take for granted – he is writing in a diary.
This sequence is explaining the world but it's totally natural. (Historical novelists have to do it too.) It's showing a piece of life that we would recognise, and intriguing us with what's distorted. Even better, Orwell has added the character's need: privacy to be himself. Because a world isn't about things, it's about people.
At any time in a story, we might have to convey lumps of information that the characters know but the readers don't – for instance, what spelunking is, how a horseshoe is made. Explaining a world is no different.
Exposition is simply when you do it badly.
Let's have some more examples of authors who explain their characters' worlds with style – share in the comments!
COMPETITION WINNERS If you get this blog by email, you might have had trouble with the post I whipped up first thing announcing the winners of the Future Life special edition. I loused up the link to the Red Blog – it should have been this. Doh. Scoot to the bottom of the post for the results. And note to self: medicate with coffee before hitting publish.


Warranty: All of our products are guaranteed for life. If they break ship them back to us and we will fix them for free. Forever. This covers functional and structural damage, not things like scratches or surface discoloration from weather. This is natural and all leather that's used gets beat up. It's made for it.
All of our bags are handmade to order. That's the only way to make them for this price at this scale. We do try to keep some in stock but usually there is a week or two waitlist for a given model. If you are interested in placing an order please be patient. If you have a deadline for gifting etc. please send us a mail before you place an order.
No returns. These again are handmade to order, please be understanding and do not order one if you are not sure you want it. If you receive a bag and there is a problem with it we will of course offer an exchange or do what we need to to make sure you are happy. This rarely happens as each one is made one at a time.
If you have special concerns please let us know. I know of a woman with exceptionally small delicate fingers who bought a bag and couldn't even do the buckles, and I know a guy who bought one to fill with rocks and would go running every day as endurance training. If I had known either of these things beforehand I would have used slightly thicker or thinner leather on certain parts.


Last year, John took the plunge and left his local government Planning Officer role of more than a decade to pursue a split career between massage and private planning consultancy, and he got a personal best time in the London Marathon. Obviously there were many many more aspects to the 12 months of 2016 for John, but these three stood out and have established the foundations for his 2017 plans.
John's been doing such a great job with his private planning work that he's been offered an amazing opportunity and was offered first refusal on a part time permanent job with the consultancy firm he's been freelancing for. Unfortunately for us, the offer did involve a slight increase in his planning hours and this means that he would only have one day per week available for massage, which needed to fit around the school run. "With a slightly heavy heart I've taken it … really enjoyed my time at BMT and shall miss the place. It has been a brilliant experience and it's a shame it can't continue."
John's a great chap who has brought an incredible amount of enthusiasm and expertise to the team, particularly when it comes to all things running, and we will be sad to see him go. However, his exceptional talent in trainers will mean that we will still see him around … even if only as a flash as he passes us in his push towards the finish line.
His last day with us will be Friday 20th January, so if you would like to make the most of this chaps knowledge, do book in.


Click Here for the City Calendar of Dark Fridays and Holidays.
Located at 910 Calle Negocio, San Clemente CA, 92673. Offices are open Monday through Thursday from 7:30 a.m. to 5:30 p.m., and every other Friday from 8:00 a.m. to 5:00 p.m. City Hall offices are closed on the Alternate Fridays and holidays.
"The Permit Counter at the Community Development Department is closed for lunch from 12:30pm to 1:30pm and open by appointment only from 1:30pm to 2:30pm."
Located at 100 North Calle Seville, San Clemente, CA, 92672. Offices are open Monday through Thursday from 8:00 a.m. to 5:30 p.m., and every other Friday from 8:00 a.m. to 5:00 p.m. Community Center offices are closed on the Alternate Fridays and holidays.
Located at 380 Avenida Pico, San Clemente, CA, 92672. Offices are open Monday through Thursday from 7:00 a.m. to 4:30 p.m., and Fridays from 7:00 a.m. to 3:30 p.m.
Located at 390 Avenida Pico, San Clemente, CA, 92672. Offices are open Monday through Thursday from 7:00 a.m. to 5:00 p.m., and every other Friday from 7:00 a.m. to 4:00 p.m. Maintenance & Corporate Yard offices are closed on the Alternate Fridays and holidays.


text:
<?php defined('BLUDIT') or die('Bludit CMS.');

// ============================================================================
// Variables
// ============================================================================

// ============================================================================
// Functions
// ============================================================================

function buildThemes()
{
	global $site;

	$themes = array();
	$themesPaths = Filesystem::listDirectories(PATH_THEMES);

	foreach($themesPaths as $themePath)
	{
		// Check if the theme is translated.
		$languageFilename = $themePath.DS.'languages'.DS.$site->language().'.json';
		if( !Sanitize::pathFile($languageFilename) ) {
			$languageFilename = $themePath.DS.'languages'.DS.DEFAULT_LANGUAGE_FILE;
		}

		if( Sanitize::pathFile($languageFilename) )
		{
			$database = file_get_contents($languageFilename);
			$database = json_decode($database, true);
			if(empty($database)) {
				Log::set('99.themes.php'.LOG_SEP.'Language file error on theme '.$themePath);
				break;
			}

			$database = $database['theme-data'];

			$database['dirname'] = basename($themePath);

			// --- Metadata ---
			$filenameMetadata = $themePath.DS.'metadata.json';

			if( Sanitize::pathFile($filenameMetadata) )
			{
				$metadataString = file_get_contents($filenameMetadata);
				$metadata = json_decode($metadataString, true);

				$database['compatible'] = false;
				if( !empty($metadata['compatible']) ) {
					$bluditRoot = explode('.', BLUDIT_VERSION);
					$compatible = explode(',', $metadata['compatible']);
					foreach( $compatible as $version ) {
						$root = explode('.', $version);
						if( $root[0]==$bluditRoot[0] && $root[1]==$bluditRoot[1] ) {
							$database['compatible'] = true;
						}
					}
				}

				$database = $database + $metadata;
				array_push($themes, $database);
			}
		}
	}

	return $themes;
}

// ============================================================================
// Main
// ============================================================================

// Load the language file
$languageFilename = THEME_DIR.'languages'.DS.$site->language().'.json';
if( !Sanitize::pathFile($languageFilename) ) {
	$languageFilename = THEME_DIR.'languages'.DS.DEFAULT_LANGUAGE_FILE;
}

if( Sanitize::pathFile($languageFilename) )
{
	$database = file_get_contents($languageFilename);
	$database = json_decode($database, true);

	// Remote the name and description.
	unset($database['theme-data']);

	// Load words from the theme language
	if(!empty($database)) {
		$L->add($database);
	}
}


Moneytree is a lender that operates in California, Colorado, Idaho, Washington, Nevada, and Canada. That said, you'll only be able to access Moneytree business loans in California, Idaho, Nevada, and Washington.
If you do business in Idaho, Nevada, or Washington, Moneytree business loans will be $1,000 of capital that would carry $175 of fees and interest if repaid in 30 days.
If you do business in California, Moneytree business loans will be $2,500 of capital that would carry $487.50 of fees and interest if repaid in 30 days.
Growing up, you probably heard the saying "Money doesn't grow on trees." Now, as you start off your search for business funding, you might feel like money does grow on trees—with so many easy-to-access business capital options out there, it's easy to forget that old adage. Generally speaking, though, the easier business financing is to score, the harder it will be to pay back.
One such source of business capital—fittingly named Moneytree—offers short-term loans with no minimum business credentials. But are their quick and expensive repayment terms worth the easy access to capital they boast?
Are Moneytree Business Loans an Option for You?
Be sure to note from the get-go: Money tree business loans are only available to businesses in California, Idaho, Nevada, and Washington. So, if you're running a business that's not based in any of those four states, you'll need to skip ahead to our three picks for the best alternatives to Moneytree business loans.
Even within those four states, too, Moneytree business loans will vary in their amounts and terms. As such, though Moneytree business loans might seem pretty uniform, be sure that you're looking at the Moneytree business loan details that apply to your specific state.
Now that we've clarified Moneytree business loans' limited reach, let's begin to dive into the details on what Moneytree business loans would look like for the business owners in California, Idaho, Nevada, and Washington. Though Moneytree doesn't vary business loan terms based on creditworthiness, their business loans will work differently from California businesses than they will for Idaho, Nevada, and Washington.
For business owners in Idaho, Nevada, and Washington, Moneytree business loans will follow a format of $1,000 in principal loan amount with $175 worth of fees and interest if you repay your Moneytree business loan in 30 days. The total cost of capital for these Moneytree business loans will be $175, which means the short-term loan will carry a 1.175 factor rate.
Using a short-term loan calculator, you'll be able to see that the cost of these states' Moneytree business loans, calculated as an interest rate, will be 17.50%. Not too bad, right?
Well, because these terms are expressed with the repayment term of just 30 days, then the total cost of your loan will likely be more than $175 if you take longer than a month to pay your business loan back.
And even if you do manage to pay your loan back in 30 days, that will mean your debt would carry an APR of 382.51% due to the quick repayment.
Alternatively, if you're running a business in California, then Moneytree business loans will carry different terms for you than they would for Idaho-, Nevada-, and Washington-based business owners. California businesses will be able to access slightly larger Moneytree business loans of $2,500. These loans will come with fees and interest of $487.50 if you're able to pay back your debt in 30 days.
Calculated as an interest rate, the cost of these loans will be 19.50% interest. However, calculated as an APR, the cost of California Moneytree business loans—repaid in 30 days—will be a whopping 424.06% because of the quick turnaround. As a reminder, Moneytree business loans don't necessarily have to be repaid in 30 days, but they will accumulate more interest than $487.50 if you take longer to repay.
If you're eligible for Moneytree business loans, and you like what you see after reading the details on your state's loan terms, then it's time to consider the steps you'll need to take to apply.
Even if you are eligible for and interested in Moneytree business loans, we strongly recommend you look into other business loan options. Looking into Moneytree business loan alternatives will help you gather valuable context on your funding options—and might even allow you to find a more affordable option.
First and foremost, you'll need to look for a Moneytree business loan alternative if you're not based in one of the four states where they're available. The limited scope of Moneytree business loans means that the vast majority of business owners won't even be able to apply for this business capital, and that's a serious downside to this product. However, there are many alternatives to Moneytree business loans that work nationally—and offer much more affordable terms. We highlight three of our favorites below.
The lightning-fast repayment terms on Moneytree business loans has tons of ramifications that are less than ideal. Most simply, repaying a loan a mere 30 days after getting it just doesn't make sense for most businesses—it's too difficult to see returns from investing in your business within a month.
Additionally, such short repayment terms mean that you'll be expected to make daily payments toward your debt. And because APR is such a time-based measurement of cost, know that Moneytree business loans have sky-high APRs.
All in all, the quick repayment that Moneytree loans require will entail frequent payments and high APRs that will make it very hard to pay your debt back according to schedule.
Finally, one last thing to look out for with Moneytree business loans is the lack of public information available on them. Though Moneytree provides examples of their business loans on their site, they don't provide exact rate minimums or maximums or fees that they might charge you during the funding process.
Additionally, there aren't many customer reviews on Moneytree business loans available. This lack of information, along with the less-than-savory reputation other payday loan institutions have, should make you tread carefully if you decide to move forward with Moneytree.
Many business owners who don't live in the four states that Moneytree business loans serve are likely wondering where to take their search for business funding. And, as we've just gone over, Moneytree business loans aren't necessarily the most affordable options on the market.
First up in our four top alternatives to Moneytree business loans is Quarterspot, an online alternative lender that provides short-term loans nationally—and with much more ideal terms than Moneytree. Because Quarterspot offers terms of nine to 18 months, borrowers will have much more time to repay with this lender than they would with Moneytree.
Plus, Quarterspot offers much larger amounts—$5,000 to $200,000—and if you're able to pay back your loan ahead of schedule, then you'll be able to save on avoided interest.
If you're looking for less-frequent payments than the daily payments that Moneytree business loans will likely require of you, then Kabbage should be your go-to alternative. Kabbage provide short-term lines of credit of up to $250,000 from which borrowers will be able to withdraw as needed up to their limit. And once you withdraw from your Kabbage line, you'll repay your debt on a monthly basis for a repayment term of six months to a year.
If you're looking for easy-to-access financing that's available nationwide, then Fundbox invoice financing is a top alternative to Moneytree business loans. If you're a B2B business that invoices its customers—and you've got at least six months in business—then you'll be eligible to access an accounts receivable line of credit from Fundbox.
Fundbox offers funding of up to $100,000 and can fund you in a matter of hours thanks to their highly automated processes. Plus, once you access funding from Fundbox based on your business's outstanding invoices, you'll have three to six months to repay your debt.
Now that you've made it through our review of Moneytree business loans, you've likely gathered what our verdict on this lender is—with a limited scope, quick repayment terms, and little public information, Moneytree business loans are hard to endorse. That said, if you're based in California, Idaho, Nevada, or Washington, and you're looking for funding along the lines of what Moneytree offers, then they're an option you can consider. Nonetheless, we encourage you to look into alternatives to Moneytree business loans that could very likely offer you more affordable and transparent funding.


text:
Digital Workplace for Law FirmsWith over 15 years of experience in the legal sector, we know how to design, build and optimise digital workplace solutions to meet the demands of a modern law firm.
Digital Workplace for Accountants For more than a decade, we've helped accountancy firms develop secure, flexible and high-performing digital workplace solutions with user experience at the core.
Managed Desktop and Device
Azure Migration
WAN & SD-WAN
Consultancy & Change
Teams Telephony
Accountancy Application Hosting
Legal Application Hosting
Blog Insights from leading experts in legal and accounting IT
Webinars Our upcoming and on-demand legal and accounting guest webinars
Guides A a selection of in-depth guides on legal and accounting IT
Our Clients Case studies and press releases showcasing our work for legal and accounting firms across the UK
Our latest video podcast: Legal tech strategy in 2022
Cloud Desktop, legal IT, Managed IT, Infrastructure | 20 November, 2017
How law firms can use the cloud to manage legacy software
Like so many industries, the legal sector has become increasingly reliant on its own specific technology stack - a collection of software and applications delivered via a mix of on-premise and cloud-based solutions.
The performance of this IT environment has become fundamental to the performance of the law firm - yet as the technology stack grows bigger and bigger, it can become a major headache to ensure it is supported effectively.
The evolving collection of applications not only means dealing with multiple vendors, but also presents a challenge in ensuring your underlying IT platform is resilient enough to provide access to your technologies with minimum (ideally zero) downtime.
In this article, we explore the key issues Legal IT managers face in managing the software stack, and look at how these challenges can be overcome.
The limitations of on-premise software
Unlike other industries that are well-served by Software-as-a-Service (SaaS) applications, many technologies supporting the legal sector are still deployed as on-premise solutions. On-premise software has some well-documented drawbacks, but the problems can really add up if your firm operates across multiple sites. Maintenance of these applications can be a real problem for IT managers, especially if they are ageing, legacy applications.
Some firms choose a site from which to host the software centrally, then enable a wide area network (WAN) to connect all users into the application. However, this requires significant investment in bandwidth, and the challenge multiplies with every user and every application run in this way.
Mobility is the other major question mark with on-premise solutions. Law firm fee earners need to work on the move to stay productive, and while today's applications are designed to allow flexible working, the right IT infrastructure is required to support mobile teams properly. If your solutions are built around on-premise working, mobility is something of an after-thought - and mobile or remote workers will often be let down by the performance of the technology.
Why upgrades aren't always the answer
To escape the limitations of on-premise legal technology, many law firms have tried to upgrade their software, believing the only way to better mobility and performance is to move to a SaaS model. Yet you don't have to upgrade to a SaaS solution or invest in more on-premise infrastructure to get the most out of your existing applications.
A cloud desktop can enable the users of a firm to access all legacy on-premise software over the Internet in a single cloud environment. It can be extremely cost effective because it enables you to get more from your existing software assets - effectively moving to a SaaS model without having to upgrade.
Using VDI (virtual desktop infrastructure) as a way of delivering cloud desktop can also provide a good user experience with older software working on newer devices. So, you can access that legacy piece of software on a on a state-of-the-art tablet and the user experience will still be smooth and intuitive.
Solving the support issue
Another concern for legal firms is both the availability and quality of the technical support provided across the software landscape. As your collection of applications proliferates, you are more likely to encounter issues - often getting caught between vendors and IT providers, with nobody taking responsibility for solving the problem at hand. With the two parties often blaming one another, issues can take too long to resolve - potentially leaving you without access to your case management system or another vitally important application for hours - sometimes even days.
Often, when a firm wishes to retain a vendor's software, the practice feels obliged to retain the managed IT services offered by the software company, too. However, as these vendors are software companies first and managed services providers second, the service side is not specialised and typically limited to remote support.
This support does not cover the physical network or infrastructure, meaning the provider doesn't have full line of sight of the issues - and therefore isn't best placed to resolve them. Indeed, when problems arise, these support providers are usually unable to go on-site to fix them.
Due to the resilience of the cloud, however, a VDI solution can significantly reduce the number of support issues you have to resolve when dealing with software that sits on-premise.
A growing technology stack and a burgeoning list of vendors brings as many challenges as it does opportunities. For law firms experiencing problems now, struggling on without action is simply unsustainable - as things will only become more complex and troublesome every time you bring a new application on board.
A cloud desktop solution is an effective way to solve the puzzle. Essentially a way to move towards a SaaS model without the expense of upgrading your existing software, it enables you to harness the mobility and productivity features of applications you already know and love, while simultaneously cutting down on the support issues that can harm your business performance.
Posted by Wayne Barber
Cloud Desktop, legal IT
How law firms can benefit from Office 365
In the past, there has been some resistance within law firms to using cloud IT solutions. But that is now eroding as more and more firms realise the
Is the future of the legal cloud desktop Citrix free?
One of the most frequent conversations we've been having with legal sector IT Managers recently is how will the desktop evolve over the coming years?
Cloud Desktops: Not all solutions are created equal
A cloud desktop is a virtual desktop hosted in a secure data centre, accessed by individuals via a secure username and password. The desktop is
Prepare your firm for the future of work. Register for a demo today.
PRIVACY PAGES
Registrar Information
Digital Workplace for Law Firms
Digital Workplace for Accountants
Cloud Desktop as a Service
The latest news, articles and resources, sent to your inbox weekly
© 2022 Oosha. All Rights Reserved

redpajama_set_name: RedPajamaCommonCrawl


Posted April 11, 2017 to Samantha Pearl #newearthkitty by: Leslie Sue Photo.
Posted April 11, 2017	to Samantha Pearl #newearthkitty	by: Leslie Sue Photo.
Posted March 21, 2017 to Pet Adoption by: Leslie Sue Photo.
Posted March 21, 2017	to Pet Adoption	by: Leslie Sue Photo.
Posted March 16, 2017 to Visionary Art by: Leslie Sue Photo.
Posted March 16, 2017	to Visionary Art	by: Leslie Sue Photo.
Posted March 13, 2017 to Samantha Pearl #newearthkitty by: Leslie Sue Photo.
Posted March 13, 2017	to Samantha Pearl #newearthkitty	by: Leslie Sue Photo.
Posted March 11, 2017 to Visionary Art by: Leslie Sue Photo.
Posted March 11, 2017	to Visionary Art	by: Leslie Sue Photo.
Posted March 10, 2017 to Visionary Art by: Leslie Sue Photo.
Posted March 10, 2017	to Visionary Art	by: Leslie Sue Photo.
Posted March 9, 2017 to Samantha Pearl #newearthkitty by: Leslie Sue Photo.
Posted March 9, 2017	to Samantha Pearl #newearthkitty	by: Leslie Sue Photo.


At the beginning of this month, Carole Boston Weatherford challenged us to write an abecedarian poem.
But leave it to you all to put your muses to work and come up with some terrific results!
a communal quilt of abecedarian poems!
And that, my friends, is something to be proud of.
Thank you to everyone who contributed a poem, commented, or followed along, and most especially to Carole Boston Weatherford for the inspiration.
or for best viewing, CLICK HERE.
Inspired to write your own abecedarian poem?
Add it to our September 2017 padlet by TOMORROW, September 30, 2017, and I will move your poem to the wrap-up presentation.
Participants in this month's challenge will automatically be entered to win a copy of SCHOMBURG: The Man Who Built a Library by Carole Boston Weatherford, illustrated by Eric Velasquez (Candlewick Press, 2017).
Alternatively, you may enter the giveaway by commenting below. Comments must be received by Tuesday, October 3rd. If you contribute a poem and comment below you will receive two entries in total.
The winner will be determined by Random.org and announced next Friday, October 6th, when we reveal next month's spotlight interview and ditty challenge.
"Look for the Helpers" and 34 more poems from The Poetry Friday Anthology for Celebrations (Pomelo Books, 2015) are now available at SoundCloud. Click HERE to listen or upload for free! Featuring readers David Bowles, Pura Belpré Honor Book winner for The Smoking Mirror, and a dozen of his students from the University of Texas, Rio Grande Valley (UTRGV), the bilingual sampler was recorded in an effort to introduce teachers, students, and especially English language learners, to the music of these wonderful poems!
For those who might be uncomfortable playing audio from an online source, CDs are available for $9.00 (at cost) on Amazon.com. If you want to follow along while listening, you can find the Teacher/Librarian Edition and Children's Edition of The Poetry Friday Anthology for Celebrations available for purchase, as well.
Laura Purdie Salas hosts the Poetry Friday roundup at Writing the World for Kids. Along with this week's offerings, she shares a peek at Amy Ludwig VanDerwater's terrific new poetry collection from WordSong: Read! Read! Read!
© 2017 Buffy Silverman. All rights reserved.
Good grief, the end of the month already?
Join us for our wrap-up celebration of abecedarian poems tomorrow!
Post your poem on our September 2017 padlet. While some contributions will be featured as daily ditties this month, all contributions will be included in a wrap-up celebration tomorrow, Friday, September 29th. One lucky participant will win a copy of Schomburg: The Man Who Built a Library by Carole Boston Weatherford, illustrated by Eric Velasquez (Candlewick Press, 2017).
© 2017 Jesse Anna Bornemann. All rights reserved.
Post your poem on our September 2017 padlet. While some contributions will be featured as daily ditties this month, all contributions will be included in a wrap-up celebration this Friday, September 29th. One lucky participant will win a copy of Schomburg: The Man Who Built a Library by Carole Boston Weatherford, illustrated by Eric Velasquez (Candlewick Press, 2017).
© 2001 Heidi Mordhorst. All rights reserved.
Diane Mayr is in the building!
Following up on her last post in the Ask a Librarian series, today Diane encourages us to maintain a poetry practice routine with some useful resources to loosen the imagination.
"Hey, Mister, how do I get to Carnegie Hall?"
Fortunately, the answer to many questions can be answered with, "practice, practice, practice." How do you walk the length of the Appalachian Trail? You start with practice trips carrying a backpack. How do you publish a book of poetry? You start by reading and writing poems. Lots of poems. Perhaps write one a day or several a week. You must practice, practice, practice writing poetry!
So here's the rub: what do you write about? Where do you get your ideas? I addressed this question in my February post at Today's Little Ditty, "Be Curious." In it I recommended several online newsletters packed with writing ideas to pursue. But, if you're going to write several poems each week for practice, you don't need to dive headfirst into a topic.
What you need is a prompt. Michelle provides monthly prompts here at TLD; this month it is to write an abecedarian. Laura Salas provides a photo for a 15 Words or Less poetry challenge each Thursday. Laura Shovan, during the month of February over several years, used postcards, colors, sound files, and more to provide readers with prompts. Other bloggers provide additional starters.
Here you'll find the artworks of thousands of artists across the ages. Pick a random work of art, or pick an art movement.
There are many ways to classify the history of art by time period, stylistic features, or geography. Currently The Athenaeum calls all such groupings "art movements."
I have no idea of what the "Veduta" movement is, so I might click on that, then on an artist, then on a work. Here's the point, don't think about whether or not you like the work you land on, just use it. Let it set your imagination loose. Imagine what the artist was thinking when she created it. What would the subject of that work think about you looking at him? Can you come up with a story to fit the picture? Can you do it in 15 words, or three stanzas, or in rhyme? What about the colors? What do their use reveal? How does it make YOU feel?
"The Distribution of Milk at Saint Lazare Prison" by Hubert Robert.
This site is loosely art related. It makes me laugh, which, as far as I'm concerned, is a major plus! Again, pick a picture and go!
For a long time I've used flickr. In the drop-down menu titled "Any license" I click on "No known copyright restrictions." Then, I put in a random term such as "weathervane" or "goat" or "permanent." You never know what is going to come up—art, photos, vintage ads.
J. Robert Lennon Random Poem Idea Generator.
Robert Lee Brewer's Wednesday Poetry Prompts.
There are plenty more places to go for writing nudges. Perhaps you can share your favorite in the comments section? There is no excuse for not writing a poem a day when the prompts are so abundant. Start today and you'll be on the road to Carnegie Hall!
Thank you for sharing these fantastic resources with us!
Diane Mayr (a.k.a. Kurious Kitty) is a long-time public librarian and a freelance writer. She is the author of a storyhour favorite picture book, Run, Turkey, Run! (Walker & Co., 2007). Since 2007, she has concentrated on haiku and other short form poems, and works to improve her graphic skills by illustrating them. Find out more about Diane at her website.
I'm delighted with the turnout for Carole Boston Weatherford's abecedarian challenge. (This is not an easy poetry form!) This week's featured daily ditties included poems by Suzy Levinson, Juanita Havill, Rosi Hollinbeck, and my own, written for yesterday's International Day of Peace. Although abecedarian poems will be accepted through the end of September, next Friday will be our wrap-up celebration. To be included, post your contribution on our September 2017 padlet.
This week's Poetry Friday roundup is being hosted by Amy Ludwig VanDerwater at The Poem Farm.
While the world and current events can feel vast and uncontrollable, on a much smaller scale, here is an offering to my teenagers toward a more peaceful future.
Help when you are able.
Visit the International Day of Peace padlet for a collection of peaceful books, poems, images, activities for the classroom, and websites.
© 2017 Rosi Hollinbeck. All rights reserved.
quibbling theories, until . . .
undulating across the desert sand.
Autumn brings change and death.
© 2017 Maria Marshall. All rights reserved.
Each time Sylvia Vardell and Janet Wong come out with a new Poetry Friday Power Book, I jump at the opportunity to feature it.
That's because I believe so strongly in what they are accomplishing with these fun DIY poetry journals—slipping poetry into children's lives in a way that not only entertains, but helps young people explore their surroundings, think about themselves in relation to others, and express themselves through the power of words. The superpower of words, really.
YOU JUST WAIT, the first book in the series, explores questions that tweens and teens think about, like identity, belonging, and dreams for the future.
HERE WE GO is the next book in the series. Targeted at a slightly younger crowd, this book also grapples with questions of belonging, but within the context of community and social responsibility/activism.
The newest book in the series, PET CRAZY, is geared toward our youngest writers-in-training (grades K-3). The cover (illustrated by Franzi Paetzold) is friendly and inviting, the larger size is great for little hands and big handwriting, but most importantly, anyone who's ever had kids, worked with kids, or has been a kid knows the magnetic draw of pets at that age. Ask any scout leader. When it comes to community service, animal rescue comes up again and again. That's because kids are crazy about their furry, scaly, and feathered friends. And who can complain about that? Pets provide a training ground for empathy, unconditional love, and responsibility, and ultimately teach children how to be compassionate and trustworthy grown-ups.
Like the previous books, PET CRAZY boasts the contributions of twelve outstanding children's poets. They provide the "anchor poems" from which Janet Wong weaves a story-in-poems, intertwining the lives of three pet-loving characters: Kristy, Ben, and Daniel. Add to that, Sylvia Vardell's game-like writing activities, creative prompts, and a wide array of interesting resources for readers, writers, and pet lovers (pet poetry books, anyone?), and you've got the award-winning formula that has made all of the Poetry Friday Power Books so doggone successful.
allowing children the choice of what they read, think, write, and respond, and giving them a "behind the scenes" look at how poems work and how poets write and think. Wouldn't you know, PET CRAZY even comes with a bonus section about hidden language skills that readers can search for throughout the book! Of course you don't have to tell them it's educational, just let them have fun.
And speaking of having fun . . .
Since Carole Boston Weatherford was in the TLD spotlight last week, I thought I would showcase PowerPack 3 of PET CRAZY which includes her poem "Loose Tooth, Whose Tooth?"
Each PowerPack opens with a PowerPlay activity—a simple, yet engaging pre-writing activity to get readers thinking. For PowerPack 3, readers are given a list of words and asked to circle their favorites and/or cross out ones they don't like.
Carole's anchor poem comes next in the PowerPack, followed by a response poem (by Janet Wong) in the voice of Daniel.
After that, a mentor poem (also by Janet Wong) in the voice of Ben, and then a Power2You writing prompt. In this case, readers are encouraged to write a poem that uses repetition.
I decided to focus my poem on two words from my list: "puppy" and "wiggle."
There's a wiggle in my belly.
There's a wiggle in my toes.
and a drumbeat in my tail.
I think I'm gonna wail!
that we're going out to play!!!
You might be when I tell you that I have five copies of PET CRAZY to give away!
Leave a comment below, or email me at TodaysLittleDitty (at) gmail (dot) com no later than Tuesday, September 12, 2017 to be entered into the drawing. Winners will be chosen randomly and announced next Friday, September 15th. Yips of appreciation to Janet and Sylvia for providing me with these giveaway copies!
See you here next week for the Poetry Friday Roundup!
Carole Boston Weatherford's abecedarian challenge is already resulting in some terrific poems! To add yours, post it on our September 2017 padlet. Featured daily ditties this week included poems by Damon Dean, Rebekah Hoeft, and Brenda Davis Harsham.
Matt Forrest Esenwine is hosting this week's Poetry Friday roundup at Radio, Rhythm & Rhyme.


Developing and communicating purposeful ideas on the theme of waka journeys.
Using a range of oral and written features to create meaning and effect and to sustain interest.
Explore and use art-making conventions, applying knowledge of elements and selected principles.
Understanding and constructing simple commands using knowledge of Te Reo Maori.


I am going to start this post by apologizing to everyone… i fell down on the job and didn't get any pictures of Sam today… so this post will be picture and video free. I will try not to fall down on the job again!
So, they say there are good days and there are bad days… today was a really good day. Sam is responding really well to the Indicin. His kidney function continues to improve. More importantly, the chest xray they took today was the best Sam has had. His lungs looked really clear and healthy- an indication that his heart function is already improving with the Indicin. And, just to pile on the happy news, Sam is back in the 23% oxygen range after being in the high 20's low 30s the past few days. Basically, this was a great day! I even had a lovely hour plus cuddle with Sam with Stephanie Ross by my side.
On another front, last night after I wrote the post, Irene started to melt down. I sat down with her, and after a good 5 minutes of crying she finally told me that she doesn't want to go back to see Sam because it scares her. While this broke my heart, I was so proud of my five year old for trying to put on a brave face for all of us. She held it in for so long, and really showed no fear. Hopefully now, with her fear in the open, she will be honest with us and herself about how she is feeling. We want her to be present with Sam, but not if it scares her. This is just such a big thing for a five year old to take in and deal with. I am just proud to be her mom.
Fingers crossed that tonight brings more of the same for Sam… cause mama loves the positive side of the roller coaster!
Congratulations on the birth of your son. Though the situation and timing are much different than what you had imagined, what a blessing a new little life is. Sam is a beautiful baby.
I am glad you have encountered so many supportive Drs, specialists, highly trained nurses (save that one), etc. My first little babe spent a short time in the NICU and what a difference it makes to have people who are really supporting you and advocating for your child versus just punching in, in this especially stressful situation.
Also, congrats to Irene on being a big sister! The NICU is a pretty intimidating/overwhelming place for an adult, what with all the monitors, sounds, etc., present – it's hard to even imagine what it would be like through a child's eyes. She will be a great big sister, no doubt, even if it's from afar for a little while.
Your family will be in our prayers. We will continue to check back for updates on Sam.


text:
What happens to the Holden Colorado dual-cab ute now?
General Motors' decision to pull out of its remaining right-hand-drive markets means it has now sold the Thai manufacturing facility, which produces the Holden Colorado ute and Trailblazer SUV, to Chinese brand Great Wall Motors.
Holden will cease Australian and New Zealand operations by the end of 2020, while Chevrolet is being pulled from Thailand in the same timeframe.
GM president – and former Holden managing director – Mark Reuss said the decision to cease right-hand-drive operations was due to an unfavourable business case, despite desire to keep the Holden brand going.
"At the highest levels of our company we have the deepest respect for Holden's heritage and contribution to our company and to the countries of Australia and New Zealand," he said.
"After considering many possible options – and putting aside our personal desires to accommodate the people and the market – we came to the conclusion that we could not prioritise further investment over all other considerations we have in a rapidly changing global industry."
The Rayong manufacturing facility in Thailand, where the local Colorado ute and Trailblazer are sourced, was identified as "unsustainable" due to "low plant utilisation and forecast volumes", according to GM.
As a result, ownership will pass onto Great Wall Motors – who currently produce the Steed pick-up, and has plans for a new dual-cab ute to take on the Toyota HiLux and Ford Ranger – and Chevrolet will be killed in Thailand as "without domestic manufacturing, Chevrolet is unable to compete in Thailand's new-vehicle market", said GM in a release.
GM CEO Mary Barra said: "We are restructuring our international operations, focusing on markets where we have the right strategies to drive robust returns, and prioritising global investments that will drive growth in the future of mobility, especially in the areas of EVs and AVs.
"While these actions support our global strategy, we understand that they impact people who have contributed so much to our company. We will support our people, our customers and our partners, to ensure an orderly and respectful transition in the impacted markets," she said.
Meanwhile, GM International operations senior vice-president Julian Blissett said the brand will now focus on sustainable parts of the business.
"In markets where we don't have significant scale, such as Japan, Russia and Europe, we are pursuing a niche presence by selling profitable, high-end imported vehicles – supported by a lean GM structure," he said.
This gives hope that the new-gen Chevrolet Corvette could still make it to markets like Australia, but CarsGuide has contacted Holden for comment.
Last year, Holden sold 17,472 units of the Colorado, making it the 15th most popular model in Australia and the brand's best seller.
Comparatively, the Colorado finished behind the Toyota HiLux (47,759), Ford Ranger (40,960) and Mitsubishi Triton (25,819) in the ute segment.
The Colorado was Holden's best shot at gaining ground in Australia's struggling new car market, but like the rest of the brand's range, is now resigned to the history books.
February 17, 2020 9:06 am Published by benzina


text:
package agents.people;

import agents.EconomicAgent;
import financial.utilities.Quote;
import goods.Good;
import model.MacroII;

/**
 * Simplest default strategy: do nothing. Always.
 * Created by carrknight on 5/20/14.
 */
public class NotTradingStrategy implements PersonalTradingStrategy {

    private static NotTradingStrategy instance = null;

    public static NotTradingStrategy getInstance(){
        if(instance == null)
            instance=new NotTradingStrategy();
        return instance;
    }

    @Override
    public void beginTradingDay(Person p, MacroII model) {
        //nothing!
    }

    @Override
    public void endTradingDay(Person p, MacroII model) {
        //nothing!
    }

    @Override
    public void reactToFilledAskedQuote(Quote quoteFilled, Good g, int price, Person seller, EconomicAgent buyer) {
        throw  new RuntimeException("Never meant to be here! This strategy makes no sale offer!");
    }

    @Override
    public void reactToFilledBidQuote(Quote quoteFilled, Good g, int price, Person buyer, EconomicAgent seller) {
        throw  new RuntimeException("Never meant to be here! This strategy makes no buy offer!");

    }

    @Override
    public void turnOff() {

    }
}


Descriptions: cylinder number assignments chevy malibu forum within chevy steering column diagram.
Descriptions: fisher snowplow control kits xls xtremev ezv fishstik hand within chevy steering column diagram.
Descriptions: smuxi led string night light usb powered wire desk table wood within chevy steering column diagram.
Descriptions: cabin air filter caf replacement how to guide the accord within chevy steering column diagram.
Descriptions: alpha fab industries inc afi le ecotec swap bo hp within chevy steering column diagram.
Descriptions: hobart handler mig technical parts manual lgy through within chevy steering column diagram.
Descriptions: wonderful of rascal wiring diagram scooter pride within chevy steering column diagram.
Descriptions: cub cadet box wiring diagram schematics within chevy steering column diagram.
Descriptions: phase air pressor pressure switch wiring diagram arb twin within chevy steering column diagram.
Chevy Steering Column Diagram (Apr 05, 2019) ― Hi precious visitor. Trying to find fresh ideas is among the most interesting events but it can as well be bored when we might not discover the wanted concept. Like you now, You are searching for fresh ideas concerning chevy steering column diagram right?
Actually, we have been remarked that chevy steering column diagram is being one of the most popular subject right now. So we tried to locate some great chevy steering column diagram image to suit your needs. Here it is. we found it coming from reliable on ―line source and that we like it. We expect it deliver something new for chevy steering column diagram niche. So, how about you? Can you like it too? Do you ever agree that this picture will be one of good reference for chevy steering column diagram? Please leave a feedback for us, we hope were able to bring further helpful info for next posts.
This excellent chevy steering column diagram photo has submitted in Apr 05, 2019 by Maria Nieto. We thank you for your visit to our website. Make sure you get the information you are looking for. Do not forget to share and love our reference to help further develop our website.
gm tilt steering column fix. chevy truck steering column. 92 s10 steering column diagram. gm steering column parts breakdown. 57 chevy steering column diagram. chevy steering columns assembly. 1988 chevy steering column diagram. chevy steering column wiring. chevy truck steering column disassembly. cadillac steering column diagram. chevy steering column parts. chevy cobalt steering column diagram. 70 chevy steering column diagram. chevy truck steering column diagram. 88 chevy steering column diagram. chevy steering column repair. 1986 chevy steering column diagram. chevy tilt steering column diagram. chevy steering column exploded-view. chevrolet diagrams steering column. gm tilt steering column diagram. chevy s10 steering column diagram. 1957 chevy steering column diagram. 1990 chevy steering column diagram. gm steering column diagram.


E-BOOK - ISBN: 9788873041955Kyoko finds herself in the middle of an ageless war between the powerful..
E-BOOK - ISBN: 9788873041931To Kyoko, mythical creatures are something you rent and watch on a Satur..
E-BOOK - ISBN: 9788873043478Algunas leyendas lo describen como un dios, mientras que otros dicen que..
ATTENZIONE! CONTENUTO SOLO PER ADULTI.WARNING! ADULT ONLY CONTENTS.E-BOOK - ISBN: 9788893983372Algum..
E-BOOK - ISBN: 9788873040392Faites attention à ce que vous souhaitez. Pour tous les sauver, un vœu a..
E-BOOK - ISBN: 9788873042051Some legends describe him as a god, while others say he is a devil that ..
E-BOOK - ISBN: 9788873041450With the blood spell broken, Kane clawed his way out of the ground and s..
E-BOOK - ISBN: 9788873040354Damien is the charismatic owner of an electronic cigarette store in Flor..
ATTENZIONE! CONTENUTO SOLO PER ADULTI.WARNING! ADULT ONLY CONTENTS.E-BOOK - ISBN: 9788893983778Os Gu..
E-BOOK - ISBN: 9788873042037The guardian brothers are very possessive immortals when it comes to pro..
E-BOOK - ISBN: 9788873041917A young girl, born over a thousand years into the future, accidentally s..
E-BOOK - ISBN: 9788893980258Eine verfluchte Schreibmaschine. Ein Mann, der auf dem Geländer eines Ba..
E-BOOK - ISBN: 9788873042228Cuídate de lo que deseas. Para salvarlos a todos se pidió un deseo, tan ..
E-BOOK - ISBN: 9788885356757En el año 1530, Paolo Grillandi, juez pontificio presidente del tribunal..
E-BOOK - ISBN: 9788873048664El encuentro con Sabrina, una hermosa muchacha conocida por casualidad e..


Very Inspiring Blogger Award | Wie sagt man...?
A big thanks (again!) to Kristin at Expatially Mexico for nominating me for the Very Inspiring Blogger Award. It's nice to have a German on my side when I talk about crazy German things. Plus, she's living in Mexico, so she gets the whole expat thing. Go check her blog out!
1. I knit, and I just finished a sweater for myself that may be my first "wearable, like out in public wearable" sweater. (Knitters know what I mean).
2. I actually enjoy watching German television, including television dubbed into German. Even Germans think this is nuts, and yes — it is. However, it's not like if I'm dying to watch a particular episode of Scrubs and I have the option of either watching it in English or watching it in German, I'll opt for German. I just think it's a mildly amusing way to spend half an hour once you've flipped on the T.V. And have I mentioned how much fun it is to eat breakfast while watching the future Mr. Walter White running around and screaming in German?
3. My official job nowadays is "freelance writer." The next question is always, "and what do you write?" Well: textbook questions about management, finance and human resources. And fascinating articles like "How to Become a Podiatrist" and "Schooling Needed to Become an Assistant Head Receptionist at a Day Care Center that May or May Not Be Licensed." It's a glamorous life.
4. I've cooked my own Thanksgiving turkey only twice. Both times it was primarily for Germans, so expectations were thankfully (see what I did there?) quite low.
5. I speak Spanish. This has helped me in Germany exactly zero times.
6. I met John Stamos once and took a picture with him, after seeing him in Cabaret. I was 14 — I look much different now. I imagine that he actually does not.
7. I really, really, really can't stand it when the credits at the beginning of movies are just credits. Like, black screen with words, and that's it. Let's get some storytelling done, people!
Those Dam Americans – no longer "Dam," as of recently, but still a great read!
Expat Alien – an American who has lived…pretty much everywhere!
Oh, thank you! I still have an award from September(!!!) that I need to post about, but I promise to get round to yours soon.
No worries. I find writing these posts about myself to be very time-consuming!