text:
/*
 ******************************************************************************
 *
 *   Copyright (C) 2009-2014, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ******************************************************************************
 */

package jdk.internal.icu.impl;

import java.util.ArrayList;

import jdk.internal.icu.text.UTF16;
import jdk.internal.icu.text.UnicodeSet;
import jdk.internal.icu.text.UnicodeSet.SpanCondition;
import jdk.internal.icu.util.OutputInt;

/*
 * Implement span() etc. for a set with strings.
 * Avoid recursion because of its exponential complexity.
 * Instead, try multiple paths at once and track them with an IndexList.
 */
public class UnicodeSetStringSpan {

    /*
     * Which span() variant will be used? The object is either built for one variant and used once,
     * or built for all and may be used many times.
     */
    public static final int WITH_COUNT    = 0x40;  // spanAndCount() may be called
    public static final int FWD           = 0x20;
    public static final int BACK          = 0x10;
    // public static final int UTF16      = 8;
    public static final int CONTAINED     = 2;
    public static final int NOT_CONTAINED = 1;

    public static final int ALL = 0x7f;

    public static final int FWD_UTF16_CONTAINED      = FWD  | /* UTF16 | */    CONTAINED;
    public static final int FWD_UTF16_NOT_CONTAINED  = FWD  | /* UTF16 | */NOT_CONTAINED;
    public static final int BACK_UTF16_CONTAINED     = BACK | /* UTF16 | */    CONTAINED;
    public static final int BACK_UTF16_NOT_CONTAINED = BACK | /* UTF16 | */NOT_CONTAINED;

    /**
     * Special spanLength short values. (since Java has not unsigned byte type)
     * All code points in the string are contained in the parent set.
     */
    static final short ALL_CP_CONTAINED = 0xff;

    /** The spanLength is >=0xfe. */
    static final short LONG_SPAN = ALL_CP_CONTAINED - 1;

    /** Set for span(). Same as parent but without strings. */
    private UnicodeSet spanSet;

    /**
     * Set for span(not contained).
     * Same as spanSet, plus characters that start or end strings.
     */
    private UnicodeSet spanNotSet;

    /** The strings of the parent set. */
    private ArrayList<String> strings;

    /** The lengths of span(), spanBack() etc. for each string. */
    private short[] spanLengths;

    /** Maximum lengths of relevant strings. */
    private int maxLength16;

    /** Are there strings that are not fully contained in the code point set? */
    private boolean someRelevant;

    /** Set up for all variants of span()? */
    private boolean all;

    /** Span helper */
    private OffsetList offsets;

    /**
     * Constructs for all variants of span(), or only for any one variant.
     * Initializes as little as possible, for single use.
     */
    public UnicodeSetStringSpan(final UnicodeSet set, final ArrayList<String> setStrings, int which) {
        spanSet = new UnicodeSet(0, 0x10ffff);
        // TODO: With Java 6, just take the parent set's strings as is,
        // as a NavigableSet<String>, rather than as an ArrayList copy of the set of strings.
        // Then iterate via the first() and higher() methods.
        // (We do not want to create multiple Iterator objects in each span().)
        // See ICU ticket #7454.
        strings = setStrings;
        all = (which == ALL);
        spanSet.retainAll(set);
        if (0 != (which & NOT_CONTAINED)) {
            // Default to the same sets.
            // addToSpanNotSet() will create a separate set if necessary.
            spanNotSet = spanSet;
        }
        offsets = new OffsetList();

        // Determine if the strings even need to be taken into account at all for span() etc.
        // If any string is relevant, then all strings need to be used for
        // span(longest match) but only the relevant ones for span(while contained).
        // TODO: Possible optimization: Distinguish CONTAINED vs. LONGEST_MATCH
        // and do not store UTF-8 strings if !thisRelevant and CONTAINED.
        // (Only store irrelevant UTF-8 strings for LONGEST_MATCH where they are relevant after all.)
        // Also count the lengths of the UTF-8 versions of the strings for memory allocation.
        int stringsLength = strings.size();

        int i, spanLength;
        someRelevant = false;
        for (i = 0; i < stringsLength; ++i) {
            String string = strings.get(i);
            int length16 = string.length();
            spanLength = spanSet.span(string, SpanCondition.CONTAINED);
            if (spanLength < length16) { // Relevant string.
                someRelevant = true;
            }
            if (/* (0 != (which & UTF16)) && */ length16 > maxLength16) {
                maxLength16 = length16;
            }
        }
        if (!someRelevant && (which & WITH_COUNT) == 0) {
            return;
        }

        // Freeze after checking for the need to use strings at all because freezing
        // a set takes some time and memory which are wasted if there are no relevant strings.
        if (all) {
            spanSet.freeze();
        }

        int spanBackLengthsOffset;

        // Allocate a block of meta data.
        int allocSize;
        if (all) {
            // 2 sets of span lengths
            allocSize = stringsLength * (2);
        } else {
            allocSize = stringsLength; // One set of span lengths.
        }
        spanLengths = new short[allocSize];

        if (all) {
            // Store span lengths for all span() variants.
            spanBackLengthsOffset = stringsLength;
        } else {
            // Store span lengths for only one span() variant.
            spanBackLengthsOffset = 0;
        }

        // Set the meta data and spanNotSet and write the UTF-8 strings.

        for (i = 0; i < stringsLength; ++i) {
            String string = strings.get(i);
            int length16 = string.length();
            spanLength = spanSet.span(string, SpanCondition.CONTAINED);
            if (spanLength < length16) { // Relevant string.
                if (true /* 0 != (which & UTF16) */) {
                    if (0 != (which & CONTAINED)) {
                        if (0 != (which & FWD)) {
                            spanLengths[i] = makeSpanLengthByte(spanLength);
                        }
                        if (0 != (which & BACK)) {
                            spanLength = length16
                                    - spanSet.spanBack(string, length16, SpanCondition.CONTAINED);
                            spanLengths[spanBackLengthsOffset + i] = makeSpanLengthByte(spanLength);
                        }
                    } else /* not CONTAINED, not all, but NOT_CONTAINED */{
                        spanLengths[i] = spanLengths[spanBackLengthsOffset + i] = 0; // Only store a relevant/irrelevant
                                                                                // flag.
                    }
                }
                if (0 != (which & NOT_CONTAINED)) {
                    // Add string start and end code points to the spanNotSet so that
                    // a span(while not contained) stops before any string.
                    int c;
                    if (0 != (which & FWD)) {
                        c = string.codePointAt(0);
                        addToSpanNotSet(c);
                    }
                    if (0 != (which & BACK)) {
                        c = string.codePointBefore(length16);
                        addToSpanNotSet(c);
                    }
                }
            } else { // Irrelevant string.
                if (all) {
                    spanLengths[i] = spanLengths[spanBackLengthsOffset + i] = ALL_CP_CONTAINED;
                } else {
                    // All spanXYZLengths pointers contain the same address.
                    spanLengths[i] = ALL_CP_CONTAINED;
                }
            }
        }

        // Finish.
        if (all) {
            spanNotSet.freeze();
        }
    }

    /**
     * Do the strings need to be checked in span() etc.?
     *
     * @return true if strings need to be checked (call span() here),
     *         false if not (use a BMPSet for best performance).
     */
    public boolean needsStringSpanUTF16() {
        return someRelevant;
    }

    /** For fast UnicodeSet::contains(c). */
    public boolean contains(int c) {
        return spanSet.contains(c);
    }

    /**
     * Adds a starting or ending string character to the spanNotSet
     * so that a character span ends before any string.
     */
    private void addToSpanNotSet(int c) {
        if (spanNotSet == null || spanNotSet == spanSet) {
            if (spanSet.contains(c)) {
                return; // Nothing to do.
            }
            spanNotSet = spanSet.cloneAsThawed();
        }
        spanNotSet.add(c);
    }

    /*
     * Note: In span() when spanLength==0
     * (after a string match, or at the beginning after an empty code point span)
     * and in spanNot() and spanNotUTF8(),
     * string matching could use a binary search because all string matches are done
     * from the same start index.
     *
     * For UTF-8, this would require a comparison function that returns UTF-16 order.
     *
     * This optimization should not be necessary for normal UnicodeSets because most sets have no strings, and most sets
     * with strings have very few very short strings. For cases with many strings, it might be better to use a different
     * API and implementation with a DFA (state machine).
     */

    /*
     * Algorithm for span(SpanCondition.CONTAINED)
     *
     * Theoretical algorithm:
     * - Iterate through the string, and at each code point boundary:
     *   + If the code point there is in the set, then remember to continue after it.
     *   + If a set string matches at the current position, then remember to continue after it.
     *   + Either recursively span for each code point or string match, or recursively span
     *     for all but the shortest one and iteratively continue the span with the shortest local match.
     *   + Remember the longest recursive span (the farthest end point).
     *   + If there is no match at the current position,
     *     neither for the code point there nor for any set string,
     *     then stop and return the longest recursive span length.
     *
     * Optimized implementation:
     *
     * (We assume that most sets will have very few very short strings.
     * A span using a string-less set is extremely fast.)
     *
     * Create and cache a spanSet which contains all of the single code points of the original set
     * but none of its strings.
     *
     * - Start with spanLength=spanSet.span(SpanCondition.CONTAINED).
     * - Loop:
     *   + Try to match each set string at the end of the spanLength.
     *     ~ Set strings that start with set-contained code points
     *       must be matched with a partial overlap
     *       because the recursive algorithm would have tried to match them at every position.
     *     ~ Set strings that entirely consist of set-contained code points
     *       are irrelevant for span(SpanCondition.CONTAINED)
     *       because the recursive algorithm would continue after them anyway and
     *       find the longest recursive match from their end.
     *     ~ Rather than recursing, note each end point of a set string match.
     *   + If no set string matched after spanSet.span(),
     *     then return with where the spanSet.span() ended.
     *   + If at least one set string matched after spanSet.span(),
     *     then pop the shortest string match end point and continue the loop,
     *     trying to match all set strings from there.
     *   + If at least one more set string matched after a previous string match, then test if the
     *     code point after the previous string match is also contained in the set.
     *     Continue the loop with the shortest end point of
     *     either this code point or a matching set string.
     *   + If no more set string matched after a previous string match,
     *     then try another spanLength=spanSet.span(SpanCondition.CONTAINED).
     *     Stop if spanLength==0, otherwise continue the loop.
     *
     * By noting each end point of a set string match, the function visits each string position at most once and
     * finishes in linear time.
     *
     * The recursive algorithm may visit the same string position many times
     * if multiple paths lead to it and finishes in exponential time.
     */

    /*
     * Algorithm for span(SIMPLE)
     *
     * Theoretical algorithm:
     * - Iterate through the string, and at each code point boundary:
     *   + If the code point there is in the set, then remember to continue after it.
     *   + If a set string matches at the current position, then remember to continue after it.
     *   + Continue from the farthest match position and ignore all others.
     *   + If there is no match at the current position, then stop and return the current position.
     *
     * Optimized implementation:
     *
     * (Same assumption and spanSet as above.)
     *
     * - Start with spanLength=spanSet.span(SpanCondition.CONTAINED).
     * - Loop:
     *   + Try to match each set string at the end of the spanLength.
     *     ~ Set strings that start with set-contained code points
     *       must be matched with a partial overlap
     *       because the standard algorithm would have tried to match them earlier.
     *     ~ Set strings that entirely consist of set-contained code points
     *       must be matched with a full overlap because the longest-match algorithm
     *       would hide set string matches that end earlier.
     *       Such set strings need not be matched earlier inside the code point span
     *       because the standard algorithm would then have
     *       continued after the set string match anyway.
     *     ~ Remember the longest set string match (farthest end point)
     *       from the earliest starting point.
     *   + If no set string matched after spanSet.span(),
     *     then return with where the spanSet.span() ended.
     *   + If at least one set string matched,
     *     then continue the loop after the longest match from the earliest position.
     *   + If no more set string matched after a previous string match,
     *     then try another spanLength=spanSet.span(SpanCondition.CONTAINED).
     *     Stop if spanLength==0, otherwise continue the loop.
     */
    /**
     * Spans a string.
     *
     * @param s The string to be spanned
     * @param start The start index that the span begins
     * @param spanCondition The span condition
     * @return the limit (exclusive end) of the span
     */
    public int span(CharSequence s, int start, SpanCondition spanCondition) {
        if (spanCondition == SpanCondition.NOT_CONTAINED) {
            return spanNot(s, start, null);
        }
        int spanLimit = spanSet.span(s, start, SpanCondition.CONTAINED);
        if (spanLimit == s.length()) {
            return spanLimit;
        }
        return spanWithStrings(s, start, spanLimit, spanCondition);
    }

    /**
     * Synchronized method for complicated spans using the offsets.
     * Avoids synchronization for simple cases.
     *
     * @param spanLimit = spanSet.span(s, start, CONTAINED)
     */
    private synchronized int spanWithStrings(CharSequence s, int start, int spanLimit,
            SpanCondition spanCondition) {
        // Consider strings; they may overlap with the span.
        int initSize = 0;
        if (spanCondition == SpanCondition.CONTAINED) {
            // Use offset list to try all possibilities.
            initSize = maxLength16;
        }
        offsets.setMaxLength(initSize);
        int length = s.length();
        int pos = spanLimit, rest = length - spanLimit;
        int spanLength = spanLimit - start;
        int i, stringsLength = strings.size();
        for (;;) {
            if (spanCondition == SpanCondition.CONTAINED) {
                for (i = 0; i < stringsLength; ++i) {
                    int overlap = spanLengths[i];
                    if (overlap == ALL_CP_CONTAINED) {
                        continue; // Irrelevant string.
                    }
                    String string = strings.get(i);

                    int length16 = string.length();

                    // Try to match this string at pos-overlap..pos.
                    if (overlap >= LONG_SPAN) {
                        overlap = length16;
                        // While contained: No point matching fully inside the code point span.
                        overlap = string.offsetByCodePoints(overlap, -1); // Length of the string minus the last code
                                                                          // point.
                    }
                    if (overlap > spanLength) {
                        overlap = spanLength;
                    }
                    int inc = length16 - overlap; // Keep overlap+inc==length16.
                    for (;;) {
                        if (inc > rest) {
                            break;
                        }
                        // Try to match if the increment is not listed already.
                        if (!offsets.containsOffset(inc) && matches16CPB(s, pos - overlap, length, string, length16)) {
                            if (inc == rest) {
                                return length; // Reached the end of the string.
                            }
                            offsets.addOffset(inc);
                        }
                        if (overlap == 0) {
                            break;
                        }
                        --overlap;
                        ++inc;
                    }
                }
            } else /* SIMPLE */{
                int maxInc = 0, maxOverlap = 0;
                for (i = 0; i < stringsLength; ++i) {
                    int overlap = spanLengths[i];
                    // For longest match, we do need to try to match even an all-contained string
                    // to find the match from the earliest start.

                    String string = strings.get(i);

                    int length16 = string.length();

                    // Try to match this string at pos-overlap..pos.
                    if (overlap >= LONG_SPAN) {
                        overlap = length16;
                        // Longest match: Need to match fully inside the code point span
                        // to find the match from the earliest start.
                    }
                    if (overlap > spanLength) {
                        overlap = spanLength;
                    }
                    int inc = length16 - overlap; // Keep overlap+inc==length16.
                    for (;;) {
                        if (inc > rest || overlap < maxOverlap) {
                            break;
                        }
                        // Try to match if the string is longer or starts earlier.
                        if ((overlap > maxOverlap || /* redundant overlap==maxOverlap && */inc > maxInc)
                                && matches16CPB(s, pos - overlap, length, string, length16)) {
                            maxInc = inc; // Longest match from earliest start.
                            maxOverlap = overlap;
                            break;
                        }
                        --overlap;
                        ++inc;
                    }
                }

                if (maxInc != 0 || maxOverlap != 0) {
                    // Longest-match algorithm, and there was a string match.
                    // Simply continue after it.
                    pos += maxInc;
                    rest -= maxInc;
                    if (rest == 0) {
                        return length; // Reached the end of the string.
                    }
                    spanLength = 0; // Match strings from after a string match.
                    continue;
                }
            }
            // Finished trying to match all strings at pos.

            if (spanLength != 0 || pos == 0) {
                // The position is after an unlimited code point span (spanLength!=0),
                // not after a string match.
                // The only position where spanLength==0 after a span is pos==0.
                // Otherwise, an unlimited code point span is only tried again when no
                // strings match, and if such a non-initial span fails we stop.
                if (offsets.isEmpty()) {
                    return pos; // No strings matched after a span.
                }
                // Match strings from after the next string match.
            } else {
                // The position is after a string match (or a single code point).
                if (offsets.isEmpty()) {
                    // No more strings matched after a previous string match.
                    // Try another code point span from after the last string match.
                    spanLimit = spanSet.span(s, pos, SpanCondition.CONTAINED);
                    spanLength = spanLimit - pos;
                    if (spanLength == rest || // Reached the end of the string, or
                            spanLength == 0 // neither strings nor span progressed.
                    ) {
                        return spanLimit;
                    }
                    pos += spanLength;
                    rest -= spanLength;
                    continue; // spanLength>0: Match strings from after a span.
                } else {
                    // Try to match only one code point from after a string match if some
                    // string matched beyond it, so that we try all possible positions
                    // and don't overshoot.
                    spanLength = spanOne(spanSet, s, pos, rest);
                    if (spanLength > 0) {
                        if (spanLength == rest) {
                            return length; // Reached the end of the string.
                        }
                        // Match strings after this code point.
                        // There cannot be any increments below it because UnicodeSet strings
                        // contain multiple code points.
                        pos += spanLength;
                        rest -= spanLength;
                        offsets.shift(spanLength);
                        spanLength = 0;
                        continue; // Match strings from after a single code point.
                    }
                    // Match strings from after the next string match.
                }
            }
            int minOffset = offsets.popMinimum(null);
            pos += minOffset;
            rest -= minOffset;
            spanLength = 0; // Match strings from after a string match.
        }
    }

    /**
     * Spans a string and counts the smallest number of set elements on any path across the span.
     *
     * <p>For proper counting, we cannot ignore strings that are fully contained in code point spans.
     *
     * <p>If the set does not have any fully-contained strings, then we could optimize this
     * like span(), but such sets are likely rare, and this is at least still linear.
     *
     * @param s The string to be spanned
     * @param start The start index that the span begins
     * @param spanCondition The span condition
     * @param outCount The count
     * @return the limit (exclusive end) of the span
     */
    public int spanAndCount(CharSequence s, int start, SpanCondition spanCondition,
            OutputInt outCount) {
        if (spanCondition == SpanCondition.NOT_CONTAINED) {
            return spanNot(s, start, outCount);
        }
        // Consider strings; they may overlap with the span,
        // and they may result in a smaller count that with just code points.
        if (spanCondition == SpanCondition.CONTAINED) {
            return spanContainedAndCount(s, start, outCount);
        }
        // SIMPLE (not synchronized, does not use offsets)
        int stringsLength = strings.size();
        int length = s.length();
        int pos = start;
        int rest = length - start;
        int count = 0;
        while (rest != 0) {
            // Try to match the next code point.
            int cpLength = spanOne(spanSet, s, pos, rest);
            int maxInc = (cpLength > 0) ? cpLength : 0;
            // Try to match all of the strings.
            for (int i = 0; i < stringsLength; ++i) {
                String string = strings.get(i);
                int length16 = string.length();
                if (maxInc < length16 && length16 <= rest &&
                        matches16CPB(s, pos, length, string, length16)) {
                    maxInc = length16;
                }
            }
            // We are done if there is no match beyond pos.
            if (maxInc == 0) {
                outCount.value = count;
                return pos;
            }
            // Continue from the longest match.
            ++count;
            pos += maxInc;
            rest -= maxInc;
        }
        outCount.value = count;
        return pos;
    }

    private synchronized int spanContainedAndCount(CharSequence s, int start, OutputInt outCount) {
        // Use offset list to try all possibilities.
        offsets.setMaxLength(maxLength16);
        int stringsLength = strings.size();
        int length = s.length();
        int pos = start;
        int rest = length - start;
        int count = 0;
        while (rest != 0) {
            // Try to match the next code point.
            int cpLength = spanOne(spanSet, s, pos, rest);
            if (cpLength > 0) {
                offsets.addOffsetAndCount(cpLength, count + 1);
            }
            // Try to match all of the strings.
            for (int i = 0; i < stringsLength; ++i) {
                String string = strings.get(i);
                int length16 = string.length();
                // Note: If the strings were sorted by length, then we could also
                // avoid trying to match if there is already a match of the same length.
                if (length16 <= rest && !offsets.hasCountAtOffset(length16, count + 1) &&
                        matches16CPB(s, pos, length, string, length16)) {
                    offsets.addOffsetAndCount(length16, count + 1);
                }
            }
            // We are done if there is no match beyond pos.
            if (offsets.isEmpty()) {
                outCount.value = count;
                return pos;
            }
            // Continue from the nearest match.
            int minOffset = offsets.popMinimum(outCount);
            count = outCount.value;
            pos += minOffset;
            rest -= minOffset;
        }
        outCount.value = count;
        return pos;
    }

    /**
     * Span a string backwards.
     *
     * @param s The string to be spanned
     * @param spanCondition The span condition
     * @return The string index which starts the span (i.e. inclusive).
     */
    public synchronized int spanBack(CharSequence s, int length, SpanCondition spanCondition) {
        if (spanCondition == SpanCondition.NOT_CONTAINED) {
            return spanNotBack(s, length);
        }
        int pos = spanSet.spanBack(s, length, SpanCondition.CONTAINED);
        if (pos == 0) {
            return 0;
        }
        int spanLength = length - pos;

        // Consider strings; they may overlap with the span.
        int initSize = 0;
        if (spanCondition == SpanCondition.CONTAINED) {
            // Use offset list to try all possibilities.
            initSize = maxLength16;
        }
        offsets.setMaxLength(initSize);
        int i, stringsLength = strings.size();
        int spanBackLengthsOffset = 0;
        if (all) {
            spanBackLengthsOffset = stringsLength;
        }
        for (;;) {
            if (spanCondition == SpanCondition.CONTAINED) {
                for (i = 0; i < stringsLength; ++i) {
                    int overlap = spanLengths[spanBackLengthsOffset + i];
                    if (overlap == ALL_CP_CONTAINED) {
                        continue; // Irrelevant string.
                    }
                    String string = strings.get(i);

                    int length16 = string.length();

                    // Try to match this string at pos-(length16-overlap)..pos-length16.
                    if (overlap >= LONG_SPAN) {
                        overlap = length16;
                        // While contained: No point matching fully inside the code point span.
                        int len1 = 0;
                        len1 = string.offsetByCodePoints(0, 1);
                        overlap -= len1; // Length of the string minus the first code point.
                    }
                    if (overlap > spanLength) {
                        overlap = spanLength;
                    }
                    int dec = length16 - overlap; // Keep dec+overlap==length16.
                    for (;;) {
                        if (dec > pos) {
                            break;
                        }
                        // Try to match if the decrement is not listed already.
                        if (!offsets.containsOffset(dec) && matches16CPB(s, pos - dec, length, string, length16)) {
                            if (dec == pos) {
                                return 0; // Reached the start of the string.
                            }
                            offsets.addOffset(dec);
                        }
                        if (overlap == 0) {
                            break;
                        }
                        --overlap;
                        ++dec;
                    }
                }
            } else /* SIMPLE */{
                int maxDec = 0, maxOverlap = 0;
                for (i = 0; i < stringsLength; ++i) {
                    int overlap = spanLengths[spanBackLengthsOffset + i];
                    // For longest match, we do need to try to match even an all-contained string
                    // to find the match from the latest end.

                    String string = strings.get(i);

                    int length16 = string.length();

                    // Try to match this string at pos-(length16-overlap)..pos-length16.
                    if (overlap >= LONG_SPAN) {
                        overlap = length16;
                        // Longest match: Need to match fully inside the code point span
                        // to find the match from the latest end.
                    }
                    if (overlap > spanLength) {
                      overlap = spanLength;
                    }
                    int dec = length16 - overlap; // Keep dec+overlap==length16.
                    for (;;) {
                        if (dec > pos || overlap < maxOverlap) {
                            break;
                        }
                        // Try to match if the string is longer or ends later.
                        if ((overlap > maxOverlap || /* redundant overlap==maxOverlap && */dec > maxDec)
                                && matches16CPB(s, pos - dec, length, string, length16)) {
                            maxDec = dec; // Longest match from latest end.
                            maxOverlap = overlap;
                            break;
                        }
                        --overlap;
                        ++dec;
                    }
                }

                if (maxDec != 0 || maxOverlap != 0) {
                    // Longest-match algorithm, and there was a string match.
                    // Simply continue before it.
                    pos -= maxDec;
                    if (pos == 0) {
                        return 0; // Reached the start of the string.
                    }
                    spanLength = 0; // Match strings from before a string match.
                    continue;
                }
            }
            // Finished trying to match all strings at pos.

            if (spanLength != 0 || pos == length) {
                // The position is before an unlimited code point span (spanLength!=0),
                // not before a string match.
                // The only position where spanLength==0 before a span is pos==length.
                // Otherwise, an unlimited code point span is only tried again when no
                // strings match, and if such a non-initial span fails we stop.
                if (offsets.isEmpty()) {
                    return pos; // No strings matched before a span.
                }
                // Match strings from before the next string match.
            } else {
                // The position is before a string match (or a single code point).
                if (offsets.isEmpty()) {
                    // No more strings matched before a previous string match.
                    // Try another code point span from before the last string match.
                    int oldPos = pos;
                    pos = spanSet.spanBack(s, oldPos, SpanCondition.CONTAINED);
                    spanLength = oldPos - pos;
                    if (pos == 0 || // Reached the start of the string, or
                            spanLength == 0 // neither strings nor span progressed.
                    ) {
                        return pos;
                    }
                    continue; // spanLength>0: Match strings from before a span.
                } else {
                    // Try to match only one code point from before a string match if some
                    // string matched beyond it, so that we try all possible positions
                    // and don't overshoot.
                    spanLength = spanOneBack(spanSet, s, pos);
                    if (spanLength > 0) {
                        if (spanLength == pos) {
                            return 0; // Reached the start of the string.
                        }
                        // Match strings before this code point.
                        // There cannot be any decrements below it because UnicodeSet strings
                        // contain multiple code points.
                        pos -= spanLength;
                        offsets.shift(spanLength);
                        spanLength = 0;
                        continue; // Match strings from before a single code point.
                    }
                    // Match strings from before the next string match.
                }
            }
            pos -= offsets.popMinimum(null);
            spanLength = 0; // Match strings from before a string match.
        }
    }

    /**
     * Algorithm for spanNot()==span(SpanCondition.NOT_CONTAINED)
     *
     * Theoretical algorithm:
     * - Iterate through the string, and at each code point boundary:
     *   + If the code point there is in the set, then return with the current position.
     *   + If a set string matches at the current position, then return with the current position.
     *
     * Optimized implementation:
     *
     * (Same assumption as for span() above.)
     *
     * Create and cache a spanNotSet which contains
     * all of the single code points of the original set but none of its strings.
     * For each set string add its initial code point to the spanNotSet.
     * (Also add its final code point for spanNotBack().)
     *
     * - Loop:
     *   + Do spanLength=spanNotSet.span(SpanCondition.NOT_CONTAINED).
     *   + If the current code point is in the original set, then return the current position.
     *   + If any set string matches at the current position, then return the current position.
     *   + If there is no match at the current position, neither for the code point
     *     there nor for any set string, then skip this code point and continue the loop.
     *     This happens for set-string-initial code points that were added to spanNotSet
     *     when there is not actually a match for such a set string.
     *
     * @param s The string to be spanned
     * @param start The start index that the span begins
     * @param outCount If not null: Receives the number of code points across the span.
     * @return the limit (exclusive end) of the span
     */
    private int spanNot(CharSequence s, int start, OutputInt outCount) {
        int length = s.length();
        int pos = start, rest = length - start;
        int stringsLength = strings.size();
        int count = 0;
        do {
            // Span until we find a code point from the set,
            // or a code point that starts or ends some string.
            int spanLimit;
            if (outCount == null) {
                spanLimit = spanNotSet.span(s, pos, SpanCondition.NOT_CONTAINED);
            } else {
                spanLimit = spanNotSet.spanAndCount(s, pos, SpanCondition.NOT_CONTAINED, outCount);
                outCount.value = count = count + outCount.value;
            }
            if (spanLimit == length) {
                return length; // Reached the end of the string.
            }
            pos = spanLimit;
            rest = length - spanLimit;

            // Check whether the current code point is in the original set,
            // without the string starts and ends.
            int cpLength = spanOne(spanSet, s, pos, rest);
            if (cpLength > 0) {
                return pos; // There is a set element at pos.
            }

            // Try to match the strings at pos.
            for (int i = 0; i < stringsLength; ++i) {
                if (spanLengths[i] == ALL_CP_CONTAINED) {
                    continue; // Irrelevant string.
                }
                String string = strings.get(i);

                int length16 = string.length();
                if (length16 <= rest && matches16CPB(s, pos, length, string, length16)) {
                    return pos; // There is a set element at pos.
                }
            }

            // The span(while not contained) ended on a string start/end which is
            // not in the original set. Skip this code point and continue.
            // cpLength<0
            pos -= cpLength;
            rest += cpLength;
            ++count;
        } while (rest != 0);
        if (outCount != null) {
            outCount.value = count;
        }
        return length; // Reached the end of the string.
    }

    private int spanNotBack(CharSequence s, int length) {
        int pos = length;
        int i, stringsLength = strings.size();
        do {
            // Span until we find a code point from the set,
            // or a code point that starts or ends some string.
            pos = spanNotSet.spanBack(s, pos, SpanCondition.NOT_CONTAINED);
            if (pos == 0) {
                return 0; // Reached the start of the string.
            }

            // Check whether the current code point is in the original set,
            // without the string starts and ends.
            int cpLength = spanOneBack(spanSet, s, pos);
            if (cpLength > 0) {
                return pos; // There is a set element at pos.
            }

            // Try to match the strings at pos.
            for (i = 0; i < stringsLength; ++i) {
                // Use spanLengths rather than a spanLengths pointer because
                // it is easier and we only need to know whether the string is irrelevant
                // which is the same in either array.
                if (spanLengths[i] == ALL_CP_CONTAINED) {
                    continue; // Irrelevant string.
                }
                String string = strings.get(i);

                int length16 = string.length();
                if (length16 <= pos && matches16CPB(s, pos - length16, length, string, length16)) {
                    return pos; // There is a set element at pos.
                }
            }

            // The span(while not contained) ended on a string start/end which is
            // not in the original set. Skip this code point and continue.
            // cpLength<0
            pos += cpLength;
        } while (pos != 0);
        return 0; // Reached the start of the string.
    }

    static short makeSpanLengthByte(int spanLength) {
        // 0xfe==UnicodeSetStringSpan::LONG_SPAN
        return spanLength < LONG_SPAN ? (short) spanLength : LONG_SPAN;
    }

    // Compare strings without any argument checks. Requires length>0.
    private static boolean matches16(CharSequence s, int start, final String t, int length) {
        int end = start + length;
        while (length-- > 0) {
            if (s.charAt(--end) != t.charAt(length)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Compare 16-bit Unicode strings (which may be malformed UTF-16)
     * at code point boundaries.
     * That is, each edge of a match must not be in the middle of a surrogate pair.
     * @param s       The string to match in.
     * @param start   The start index of s.
     * @param limit   The limit of the subsequence of s being spanned.
     * @param t       The substring to be matched in s.
     * @param tlength The length of t.
     */
    static boolean matches16CPB(CharSequence s, int start, int limit, final String t, int tlength) {
        return matches16(s, start, t, tlength)
                && !(0 < start && Character.isHighSurrogate(s.charAt(start - 1)) &&
                        Character.isLowSurrogate(s.charAt(start)))
                && !((start + tlength) < limit && Character.isHighSurrogate(s.charAt(start + tlength - 1)) &&
                        Character.isLowSurrogate(s.charAt(start + tlength)));
    }

    /**
     * Does the set contain the next code point?
     * If so, return its length; otherwise return its negative length.
     */
    static int spanOne(final UnicodeSet set, CharSequence s, int start, int length) {
        char c = s.charAt(start);
        if (c >= 0xd800 && c <= 0xdbff && length >= 2) {
            char c2 = s.charAt(start + 1);
            if (UTF16.isTrailSurrogate(c2)) {
                int supplementary = UCharacterProperty.getRawSupplementary(c, c2);
                return set.contains(supplementary) ? 2 : -2;
            }
        }
        return set.contains(c) ? 1 : -1;
    }

    static int spanOneBack(final UnicodeSet set, CharSequence s, int length) {
        char c = s.charAt(length - 1);
        if (c >= 0xdc00 && c <= 0xdfff && length >= 2) {
            char c2 = s.charAt(length - 2);
            if (UTF16.isLeadSurrogate(c2)) {
                int supplementary = UCharacterProperty.getRawSupplementary(c2, c);
                return set.contains(supplementary) ? 2 : -2;
            }
        }
        return set.contains(c) ? 1 : -1;
    }

    /**
     * Helper class for UnicodeSetStringSpan.
     *
     * <p>List of offsets from the current position from where to try matching
     * a code point or a string.
     * Stores offsets rather than indexes to simplify the code and use the same list
     * for both increments (in span()) and decrements (in spanBack()).
     *
     * <p>Assumption: The maximum offset is limited, and the offsets that are stored at any one time
     * are relatively dense, that is,
     * there are normally no gaps of hundreds or thousands of offset values.
     *
     * <p>This class optionally also tracks the minimum non-negative count for each position,
     * intended to count the smallest number of elements of any path leading to that position.
     *
     * <p>The implementation uses a circular buffer of count integers,
     * each indicating whether the corresponding offset is in the list,
     * and its path element count.
     * This avoids inserting into a sorted list of offsets (or absolute indexes)
     * and physically moving part of the list.
     *
     * <p>Note: In principle, the caller should setMaxLength() to
     * the maximum of the max string length and U16_LENGTH/U8_LENGTH
     * to account for "long" single code points.
     *
     * <p>Note: An earlier version did not track counts and stored only byte flags.
     * With boolean flags, if maxLength were guaranteed to be no more than 32 or 64,
     * the list could be stored as bit flags in a single integer.
     * Rather than handling a circular buffer with a start list index,
     * the integer would simply be shifted when lower offsets are removed.
     * UnicodeSet does not have a limit on the lengths of strings.
     */
    private static final class OffsetList {
        private int[] list;
        private int length;
        private int start;

        public OffsetList() {
            list = new int[16];  // default size
        }

        public void setMaxLength(int maxLength) {
            if (maxLength > list.length) {
                list = new int[maxLength];
            }
            clear();
        }

        public void clear() {
            for (int i = list.length; i-- > 0;) {
                list[i] = 0;
            }
            start = length = 0;
        }

        public boolean isEmpty() {
            return (length == 0);
        }

        /**
         * Reduces all stored offsets by delta, used when the current position moves by delta.
         * There must not be any offsets lower than delta.
         * If there is an offset equal to delta, it is removed.
         *
         * @param delta [1..maxLength]
         */
        public void shift(int delta) {
            int i = start + delta;
            if (i >= list.length) {
                i -= list.length;
            }
            if (list[i] != 0) {
                list[i] = 0;
                --length;
            }
            start = i;
        }

        /**
         * Adds an offset. The list must not contain it yet.
         * @param offset [1..maxLength]
         */
        public void addOffset(int offset) {
            int i = start + offset;
            if (i >= list.length) {
                i -= list.length;
            }
            assert list[i] == 0;
            list[i] = 1;
            ++length;
        }

        /**
         * Adds an offset and updates its count.
         * The list may already contain the offset.
         * @param offset [1..maxLength]
         */
        public void addOffsetAndCount(int offset, int count) {
            assert count > 0;
            int i = start + offset;
            if (i >= list.length) {
                i -= list.length;
            }
            if (list[i] == 0) {
                list[i] = count;
                ++length;
            } else if (count < list[i]) {
                list[i] = count;
            }
        }

        /**
         * @param offset [1..maxLength]
         */
        public boolean containsOffset(int offset) {
            int i = start + offset;
            if (i >= list.length) {
                i -= list.length;
            }
            return list[i] != 0;
        }

        /**
         * @param offset [1..maxLength]
         */
        public boolean hasCountAtOffset(int offset, int count) {
            int i = start + offset;
            if (i >= list.length) {
                i -= list.length;
            }
            int oldCount = list[i];
            return oldCount != 0 && oldCount <= count;
        }

        /**
         * Finds the lowest stored offset from a non-empty list, removes it,
         * and reduces all other offsets by this minimum.
         * @return min=[1..maxLength]
         */
        public int popMinimum(OutputInt outCount) {
            // Look for the next offset in list[start+1..list.length-1].
            int i = start, result;
            while (++i < list.length) {
                int count = list[i];
                if (count != 0) {
                    list[i] = 0;
                    --length;
                    result = i - start;
                    start = i;
                    if (outCount != null) { outCount.value = count; }
                    return result;
                }
            }
            // i==list.length

            // Wrap around and look for the next offset in list[0..start].
            // Since the list is not empty, there will be one.
            result = list.length - start;
            i = 0;
            int count;
            while ((count = list[i]) == 0) {
                ++i;
            }
            list[i] = 0;
            --length;
            start = i;
            if (outCount != null) { outCount.value = count; }
            return result + i;
        }
    }
}


Cheap countertops are identical with the material kinds that are used to build the countertops. Related to cheap materials for the countertops, there are some options you can choose. First option is laminate countertops. Laminate is very common one chosen by most homeowners for creating the sense of modern for the countertops.
Moreover, laminate countertops are the easiest one to be appropriated with the main kitchen decoration theme. There are three benefits of installing laminate countertops. The benefits are easy-maintenance, good durability, strong, and high aesthetic value.
Next cheap and fabulous material for countertop is tempered glass. It is a newest one and many people like it. It is thick and tough material. Tempered glass countertops are easy to clean. It is available in many verities of beautiful colors.
Ceramic is next cheap countertops which becomes the second favorite choice over laminate countertops. Ceramic countertops are anti-scratch, cool, and easy to maintain and to clean. Ceramic countertops will look so attractive if they are re-designed in dark grey as the final finish and we combine them with wood surround.
Nanotech material probably sounds so strange if it is used as the kitchen countertop. Yet, the material is able to give special accent for the countertop. Besides, it also offers many benefits such as anti-fingerprints, reflective resistance, soft appearance, and amazingly it has the capability of self-healing. Wood, stainless steel, and tiles are most recommended materials which are called as cheap countertops.


text:
Fintechs lending to high-risk segments even as banks, lenders clamp down on unsecured loans
A study by Equifax and Small Industries Development Bank of India (Sidbi) put the ratio of bad loans in the personal segment at 6.15% for fintechs, in December 2019, way above the 0.71% for the industry.
The fintech industry in general, and the lending sector in particular, is looking to build new products on a scalable architecture that is being created with initiatives such as account aggregation.
Armed with capital a clutch of fintechs is moving in to finance the self-employed and freelancers at a time when banks and other lenders are clamping down on unsecured loans. The risks are high given how even before the pandemic the share of loans in the 90 days-past-due (dpd) category was elevated.
However, lenders like Abhishek Agarwal, co-founder and CEO, CreditVidya, believe there is an opportunity. "There is a segment of the population which is not as bad, but has just been hit very badly by the pandemic," Agarwal said.
The lender, which operates in the alternative data underwriting space, has now launched a lending vertical called Prefr, which offers pay-later loans, cash advances and term loans to the self-employed.
It found that traditional NBFCs' unsecured loan disbursements had dropped by 70% after the Covid-19 outbreak and also that private banks were lending primarily to their customers. Also, they they raised income cut-offs for borrowers to be able to access loans. Another player in this segment is ePayLater, which has tied up with Metro Cash & Carry, Walmart's Best Price and Reliance Market to lend to their customers.
In order to better the chances of recovering their loans, fintech lenders are asking specifically for the end use of funds. In some cases, this could take the shape of small-scale supply chain financing, where the funds are disbursed to a distributor in the retail supply chain and the repayment is made by the merchant. In others, merchants are loaning money to sustain operations running until the online sales result in payments. Others are funding cash-starved freelancers and gig-economy workers. Delinquencies remain elevated in this segment. Many of the loanees were untraceable post the lockdown despite Aadhaar eKYC having been done. Unlike banks and large NBFCs, digital-only lenders do not have field agents to make recoveries for them and are, therefore, far worse off at collections.
Industry executives like Tarun Kumar Kalra, global head of sales, CredoLab said fintechs are mushrooming, with freelancers as the main customer segment because they know these people need help and their existing lenders are turning them down. " They are using all sorts of alternative data and behaviour to assess this segment because that's where the biggest consumption will happen, but where the biggest risk also lies," Kalra said.
The full impact of the pandemic on the economy in terms of employment levels and small and medium enterprises (SME) profitability will play out over a much longer period of time. These risks are likely to manifest themselves thereafter, Kalra said.
The sole explanation behind the increased lending to riskier segments amid an economic crisis is the venture money invested into fintechs. This money allows them to lend and, in the process, obtain the digital footprint of lakhs of people. "So if one year after launch, the fintech can claim it has 100,000 freelance customers, its valuation will be more, as compared to how many of those customers have actually paid back," Kalra said.
Fintechs lending to high-risk segments even as banks lenders clamp down on unsecured&nbsploans

redpajama_set_name: RedPajamaCommonCrawl


text:
Early antibiotics for sepsis supported in new study
Concerns about overuse of antibiotics in hospitalized patients addressed in multi-hospital analysis that included Kaiser Permanente
A large multi-hospital analysis found that early antibiotics in sepsis patients resulted in improved health outcomes for them without posing unintended consequences for others, such as expanding overall antibiotic use or worsening antibiotic resistance.
Vincent Liu, MD, MSc.
The study, published June 27 in JAMA Internal Medicine, is good news for hospital physicians who want to act fast to respond to sepsis — the body's overreaction to an infection — which can turn deadly within hours, said senior study author Vincent Liu, MD, MSc, intensivist physician and research scientist with the Kaiser Permanente Division of Research.
"There has been an intense focus on treating sepsis patients with antibiotics as early as possible because it is the cornerstone of performance improvement for this devastating condition," Liu said. "However, what has been poorly understood is what impact those efforts have had on other patients who may be receiving antibiotics out of concern for infection."
Liu and research collaborator Hallie C. Prescott, MD, MSc, critical care physician and associate professor at the University of Michigan, launched the study with funding from the Agency for Healthcare Research and Quality.
Their analysis examined care in 152 Kaiser Permanente and Veterans Affairs hospitals from 2013 to 2018, involving more than 1.5 million patients. They studied patients admitted to the hospital through the emergency department who had 2 or more symptoms of systemic inflammatory response syndrome (SIRS), such as increased heart rate and abnormal body temperature. Patients with SIRS symptoms would be at risk for sepsis, but many might not end up having it or needing antibiotics.
The researchers then compared the 17% of the patients who were admitted with a diagnosis of sepsis with the entire group, to learn the impact of earlier antibiotic use for sepsis on each group.
The study found that for sepsis patients, the time to initial antibiotic use decreased by 37 minutes over the 6-year study period (4.7 hours to 3.9), indicating hospitals were implementing the earlier treatment advice.
Hallie Prescott, MD, MSc.
At the same time the hospitals were improving care for sepsis patients, they were not indiscriminately expanding antibiotic use with others, the analysis found. In fact, it identified the opposite: overall antibiotic use declined, as did the average number of days of antibiotic treatment and use of broad-spectrum antibiotics. Both groups of patients saw reductions in 30-day mortality, length of hospitalization, and positive culture for a resistant bacteria.
"The pushback has been [time-to-treatment for sepsis] should not be a performance measure because it's going to cause more harm than good, and I think our data shows it probably does more good than harm," Prescott said. "We have shown that 152 hospitals have been able to make improvements in stewardship and sepsis treatment at the same time, contrary to popular belief."
The study's authors said their findings suggest antibiotics are being targeted to the patients who would most benefit.
"This study adds to our national conversation about how to combat sepsis most effectively," Liu said. "It also confirms that we now need to look for new opportunities to mitigate sepsis by finding patients at high risk before they arrive at the hospital, identifying hospitalized patients most likely to benefit from specific treatments, and enhancing their recovery after they survive sepsis."
Read the University of Michigan news release


TAKE NOTICE that in accordance with the provisions of Sec. 40-8-1 through Sec. 40-8-3 NMSA 1978, the Petitioner LaVerne Janis Mary Visarraga will apply to the Honorable Clay Campbell, District Judge of the 2ND Judicial District at Albuquerque, New Mexico at 10:00 a.m. on the 15th day of Noveber, 2013 for an ORDER FOR CHANGE OF NAME from LAVERNE JANIS MARY VISARRAGA to AMOR JANIS MARIE.


text:
NGC 2740 é uma galáxia espiral (Sab) localizada na direcção da constelação de Ursa Major. Possui uma declinação de +51° 44' 08" e uma ascensão recta de 9 horas, 06 minutos e 05,0 segundos.

A galáxia NGC 2740 foi descoberta em 17 de Fevereiro de 1831 por John Herschel.

Ver também
Astronomia extragaláctica
Lista de galáxias
Lista de objectos NGC
New General Catalogue

Ligações externas

NGC 2740
Constelação de Ursa Major
Galáxias espirais

redpajama_set_name: RedPajamaWikipedia


text:
<!DOCTYPE html>

  <meta charset="utf-8" />
  <title>Flatkit - HTML Version | Bootstrap 4 Web App Kit with AngularJS</title>
  <meta name="description" content="Admin, Dashboard, Bootstrap, Bootstrap 4, Angular, AngularJS" />
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimal-ui" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">

  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-barstyle" content="black-translucent">
  <link rel="apple-touch-icon" href="../assets/images/logo.png">
  <meta name="apple-mobile-web-app-title" content="Flatkit">

  <meta name="mobile-web-app-capable" content="yes">
  <link rel="shortcut icon" sizes="196x196" href="../assets/images/logo.png">

  <link rel="stylesheet" href="../assets/animate.css/animate.min.css" type="text/css" />
  <link rel="stylesheet" href="../assets/font-awesome/css/font-awesome.min.css" type="text/css" />
  <link rel="stylesheet" href="../assets/material-design-icons/material-design-icons.css" type="text/css" />

  <link rel="stylesheet" href="../assets/bootstrap/dist/css/bootstrap.min.css" type="text/css" />

  <link rel="stylesheet" href="../assets/styles/app.css" type="text/css" />

  <link rel="stylesheet" href="../assets/styles/font.css" type="text/css" />

Basic

          <div class='input-group date' ui-jp="datetimepicker" ui-options="{
                icons: {
                  time: 'fa fa-clock-o',
                  date: 'fa fa-calendar',
                  up: 'fa fa-chevron-up',
                  down: 'fa fa-chevron-down',
                  previous: 'fa fa-chevron-left',
                  next: 'fa fa-chevron-right',
                  today: 'fa fa-screenshot',
                  clear: 'fa fa-trash',
                  close: 'fa fa-remove'
                }
              }">
              <input type='text' class="form-control" >

No icon

          <input type='text' class="form-control" ui-jp="datetimepicker" ui-options="{
            icons: {
              time: 'fa fa-clock-o',
              date: 'fa fa-calendar',
              up: 'fa fa-chevron-up',
              down: 'fa fa-chevron-down',
              previous: 'fa fa-chevron-left',
              next: 'fa fa-chevron-right',
              today: 'fa fa-screenshot',
              clear: 'fa fa-trash',
              close: 'fa fa-remove'
            }
          }">

Custom formats

          <div class='input-group date' ui-jp="datetimepicker" ui-options="{
                format: 'LT',
                icons: {
                  time: 'fa fa-clock-o',
                  date: 'fa fa-calendar',
                  up: 'fa fa-chevron-up',
                  down: 'fa fa-chevron-down',
                  previous: 'fa fa-chevron-left',
                  next: 'fa fa-chevron-right',
                  today: 'fa fa-screenshot',
                  clear: 'fa fa-trash',
                  close: 'fa fa-remove'
                }
              }">
              <input type='text' class="form-control" />

          <div class='input-group date' ui-jp="datetimepicker" ui-options="{
                format: 'DD/MM/YYYY',
                icons: {
                  time: 'fa fa-clock-o',
                  date: 'fa fa-calendar',
                  up: 'fa fa-chevron-up',
                  down: 'fa fa-chevron-down',
                  previous: 'fa fa-chevron-left',
                  next: 'fa fa-chevron-right',
                  today: 'fa fa-screenshot',
                  clear: 'fa fa-trash',
                  close: 'fa fa-remove'
                }
              }">
              <input type='text' class="form-control" />

Enabled/Disabled dates

          <div class='input-group date' ui-jp="datetimepicker" ui-options="{
                defaultDate: '11/1/2015',
                disabledDates: [
                    '11/2/2015 00:53'
                ],
                icons: {
                  time: 'fa fa-clock-o',
                  date: 'fa fa-calendar',
                  up: 'fa fa-chevron-up',
                  down: 'fa fa-chevron-down',
                  previous: 'fa fa-chevron-left',
                  next: 'fa fa-chevron-right',
                  today: 'fa fa-screenshot',
                  clear: 'fa fa-trash',
                  close: 'fa fa-remove'
                }
              }">
              <input type='text' class="form-control" />

Disabled days of the week

          <div class='input-group date' ui-jp="datetimepicker" ui-options="{
                daysOfWeekDisabled: [0, 6],
                icons: {
                  time: 'fa fa-clock-o',
                  date: 'fa fa-calendar',
                  up: 'fa fa-chevron-up',
                  down: 'fa fa-chevron-down',
                  previous: 'fa fa-chevron-left',
                  next: 'fa fa-chevron-right',
                  today: 'fa fa-screenshot',
                  clear: 'fa fa-trash',
                  close: 'fa fa-remove'
                }
              }">
              <input type='text' class="form-control" />

View mode

          <div class='input-group date' ui-jp="datetimepicker" ui-options="{
                viewMode: 'years',
                icons: {
                  time: 'fa fa-clock-o',
                  date: 'fa fa-calendar',
                  up: 'fa fa-chevron-up',
                  down: 'fa fa-chevron-down',
                  previous: 'fa fa-chevron-left',
                  next: 'fa fa-chevron-right',
                  today: 'fa fa-screenshot',
                  clear: 'fa fa-trash',
                  close: 'fa fa-remove'
                }
              }">
              <input type='text' class="form-control" />

          <div class='input-group date' ui-jp="datetimepicker" ui-options="{
                viewMode: 'years',
                format: 'MM/YYYY',
                icons: {
                  time: 'fa fa-clock-o',
                  date: 'fa fa-calendar',
                  up: 'fa fa-chevron-up',
                  down: 'fa fa-chevron-down',
                  previous: 'fa fa-chevron-left',
                  next: 'fa fa-chevron-right',
                  today: 'fa fa-screenshot',
                  clear: 'fa fa-trash',
                  close: 'fa fa-remove'
                }
              }">
              <input type='text' class="form-control" />

Inline

redpajama_set_name: RedPajamaGithub


Why wait? We can offer multiple options for financing your perfect purchase including interest free credit and new or pre-owned watch finance options. If you would like to understand which option would suit you best, we have given you a little bit more information to digest below.
Up to 60 months 0% APR representative interest free finance. Spread the cost with our interest free finance available online and in store.
Our simple finance options allow you to spread the cost of your purchase. Depending on the product you wish to finance we can offer options over 6, 9, 10, 12, 18, 24, 36, 48, 60 months, depending on the value of your order.
Unfortunately we are unable to offer finance on sale items.
When you buy online from Burrells Watches you have the choice of applying for instant finance by adding your purchase to the shopping basket, selecting the option to PaybyFinance, and completing a finance application form. The whole process only takes a few minutes and is simple and secure. Once your finance application is approved, you will receive an e-mail advising you of how to download the finance agreement. Please read this carefully checking that all the details are correct, then either e-sign the agreement, if offered, or print and sign the finance agreement twice. Post the document to the address shown on the finance agreement. Following receipt of your finance agreement and a few additional checks, your goods will be dispatched.
Within minutes of your application being approved, you will be presented with the option to sign your credit agreement. If you are offered the ability to e-sign your credit agreement and choose to do so, a PDF of your credit agreement will be displayed on screen. You should read the credit agreement carefully before clicking all the relevant sections agreeing to its terms. Once you have agreed to the terms of the credit agreement Burrells Watches will be notified and you need do nothing more. If you are presented with the ability to print and return your credit agreement you should print the PDF agreement, read it carefully and then sign the document following the instructions on the covering letter. This signed document should then be posted to the address shown on the covering letter of the credit agreement. Note that products will not be allocated to your order until your completed and signed agreement is returned and received by Hitachi Capital. Shipment of your goods will follow soon after your agreement has been returned to our finance company.
Credit subject to status and affordability. Terms & Conditions Apply. Burrells Watches are a credit broker and are Authorised and Regulated by the Financial Conduct Authority.Credit is provided by Hitachi Personal Finance, a division of Hitachi Capital (UK) PLC Authorised and Regulated by the Financial Conduct Authority.


text:
Home › Destinations › Vanuatu – volcanoes, mermaids and wrecks
Vanuatu – volcanoes, mermaids and wrecks
By Strike on January 14, 2014 • ( 0 )
A 700-kilometre chain of 80-plus islands ringed with coral fringing reefs, the South Pacific island nation of Vanuatu boasts active volcanoes, lush rain forests and a fascinating array of marine life that includes dugongs, the legendary 'mermaids' of folklore.
Espiritu Santo (meaning home to the spirits of the Saints) is the largest and, in many ways, the most stunning of all of the islands in the magnificent Vanuatu island chain.
During WWII James A Michener, then a lieutenant in the US army, was posted here and was so overwhelmed by the island's beauty that he wrote the legendary Tales of the South Pacific. Although there is, today, little sign of the 100,000 allied troops that were stationed on Espiritu Santo during the war, the island hosts a permanent reminder of that conflict in the shape of what is claimed to be the world's largest accessible shipwreck, the SS President Coolidge, an artificial reef of gothic proportions.
The 'SS President Coolidge'
A former ocean-going passenger liner turned troopship, that fell victim to an 'own goal' in 1942, during the Second World War, the 22,000 ton, 'SS President Coolidge' was launched in 1931 and began life as a luxury passenger cruise liner sailing the Pacific between San Francisco and the Far East. Commandeered into the service of her country as a troopship in early 1942, (like many other ocean going passenger liners of the time), the 'Coolidge' was stripped of her comfortable appointments and fittings and used to transport men and materials to the South Pacific ahead of the advancing Japanese forces.
Relying on a speed of 20 knots to outrun enemy submarines and land his precious cargo safely on Espiritu Santo, the largest of the islands of Vanuatu, Captain Henry Nelson was, on October 26th, 1942, negotiating the 'Coolidge' through the heavily mined second channel when the ship hit two American mines.
In an attempt to save his ship and passengers, the Captain steered the stricken vessel towards – and up onto – the steeply sloping beach. Within an hour most of the cargo had been dumped overboard and 5,500 troops and crew gained the safety of the shore before the 'SS President Coolidge', labouring beneath the weight of inrushing water and gravity, slowly disappeared beneath the surface.
Only two lives were lost, those of a ship's fireman killed in one of the initial explosions and an army officer who had been instrumental in saving many lives and who had returned to search the sinking vessel in the mistaken belief that men were still trapped below decks.
Only 100-metres or so from the shore, the 200-metre long, 'President Coolidge' has, over the years, slipped down the steep incline on which she came to rest. Lying on her port side, the bow rests in about 20-metres while the stern drops away into 60-plus metres of water.
Regardless of certification level the 'SS President Coolidge' offers divers of every experience something unique and, because of its sheer size, there's always something new to discover.
Like any penetration wreck dive silt-outs are always a possibility and, as a complex structure whose maze of passageways and compartments can defeat the navigational skills of even the most experienced divers, the presence of a dive guide is a mandatory requirement in fully appreciating all that the 'Coolidge' has to offer.
Most of the diving takes place between the bow and the bridge area at a usual depth of no more than 40 metres, although the more atmospheric sections of the wreck are, despite their depth, extremely easy to reach.
And there is plenty to see and marvel at. The Promenade deck is still littered with the refuse of war. Rifles, bayonets, helmets and gas masks, together with uniform clothing rest where they fell more than half-a-century ago. In the spacious holds trucks, jeeps, anti-aircraft guns and shells lie forgotten.
Apart from depth restrictions almost all parts of the wreck are accessible to divers. At the shallower levels the bridge wings still support their two cannons, while deeper into the wreck there's an abundance of plates, utensils and artefacts.
Points of interest are the large turbines, the swimming pool, the barbers chair, the Captains bathroom, the medical supply room and rows of toilet bowls where many a neoprene clad diver has paused to rest and have their picture taken.
The highlight of a dive on the 'SS President Coolidge' is the swim through to the former First-Class Smoking Room of this once luxurious ship. At a depth of just over 40-metres a framed relief figure of a lady wearing costume of the Elizabethan period and posed in front of a unicorn still hangs above the fireplace: A startling treasure that comes to life in the beams of underwater lights.
With quick and easy access from either boat or shore – and more than a dozen different dives in, over and around the 'Coolidge' – it's possible to overlook the marine life in favour of the wreck's inspirational size. But for divers' carrying out their safety stops in the shallows near the wreck (in a coral garden built by legendary diving figure. Allan Power, who has spent more than thirty years exploring the wreck and researching the history of the 'SS President Coolidge'), there are plenty of amusing, colourful and exotic fish life that call the 'Coolidge' home.
Featured on the itinerary of most of the island nation's dive operators, the wreck of the 'SS President Coolidge' was, in 1983, declared a Vanuatu Marine National Park.
The above, edited, article was first published in the on-line Nekton Magazine in 2007.
‹ Fish and ships … and divers
Gideon Liew – G.U.E. Instructor ›
Categories: Destinations
Tags: deep wreck diving, dive plan, Diving Destinations, mixed gas diving, OZTeK, PADI, recreational diving, scuba, shore diving, SSI, TDI, technical diving, Vanuatu, wreck diving
General Select Category Book Reviews Counter-Strike Crisis Manual Destinations General History Profiles Techniques


Please call 866.403.8046 and mention code: JEA20S.
The best way to cozy up this winter is to join us at The Venetian and The Palazzo. With the cooler temperatures there's no better time to indulge and experience all the excitement we have to offer. Savor award-winning global cuisine, enjoy hand-crafted cocktails—whatever you desire. Book with us directly and take advantage of these rates before they disappear.
Please note this offer's Terms & Conditions.


A Sogdian Mortuary Couch, Bas Relief, Northern Qi dynasty, A.D. 550-577.
At least nine stone slabs were once part of an elaborate stone couch (shichuang), a rare type of burial furniture used for the repose of the deceased, carved with an unusual combination of Buddhist and secular themes.
Last edited by druzhina; 07-24-2017 at 07:33.


text:
Healthcare Through A Different Lens
Posted on April 7, 2022 January 31, 2023
Valerie Ryan speaks to leaders of columbia university's innovative programme on the developing concept of 'narrative medicine' and how it can enhance patient interactions
The influence of 'narrative medicine' as a concept in clinical practice has grown over the past two decades. It has regularly emerged as a topic at clinical meetings or as a methodology in the teaching of medicine. More recently, narrative medicine has been proposed as a potential response to the pressures on healthcare professionals (HCPs) in the pandemic.
The surge of interest in the discipline also comes with uncertainty around what narrative medicine encompasses. How narrative medicine is generally seen or referred to in clinical practice varies widely. Some describe the field as narrative, underlining the value of sharing HCPs' and patients' stories; others stress how literature and storytelling may act as a support for wellbeing to mitigate burnout.
A benchmark programme in New York City's Columbia University is looking more broadly to building individual narrative skills to support better healthcare. Tracing the field back to the founding days of the programme, the phrase 'narrative medicine' was first coined in 2000 by Dr Rita Charon, the leading founder of the discipline, to refer to clinical practice fortified by narrative competence, or as she is so often quoted saying, the ability to acknowledge, absorb, interpret, and act on the stories and plights of others.
Trained at Harvard Medical School, Dr Charon is the founding Chair and Professor of Medical Humanities and Ethics and Pro- fessor of Medicine at Columbia University Irving Medical Centre. She went on to launch the first Master of Science (MS) in Narrative Medicine at Columbia University in 2009. A required narrative medicine curriculum now runs across all four years of Columbia's medical school.
Last autumn, the Keck School of Medicine of University of Southern California (USC) introduced the country's second MS in Narrative Medicine; Dr Charon and the core faculty from Columbia University are part of the advisory board. A specialist in internal medicine and Executive Director of the Division of Narrative Medicine at Columbia, she has proved to be a sought-after speaker, reiterating her thinking to doctors and other healthcare sectors on the development of narrative training as a tool for enhancing their practice.
The model for teaching narrative skills for Columbia's Masters' programme has been used beyond the university over the years and formed the basis of international workshops and courses. Co-leaders of the international programme, noted American writers Ms Nellie Hermann and Ms Catherine Rogers,
discussed the principles and practice of the Columbia University model. While a universal definition may be elusive, both Ms Hermann and Ms Rogers were clear the objective of the Master's programme in narrative medicine was not specifically to either teach doctors and others creative writing nor to target improved self-reflection, deliver arts therapy, or directly analyse the impact of patients' experiences.
Instead, Ms Hermann, co-author of The Principles and Practice of Narrative Medicine (2017) and Creative Director of the Programme in Narrative Medicine at Columbia, offered the definition of narrative medicine "as a field that uses the tools of creativity and storytelling in order to enhance healthcare". "What does it mean to tell a story, to listen to a story? Of course, we also define 'story' very broadly, and we use the creative arts as a way to open up those conversations and begin to think about what does that mean," she said.
The Division of Narrative Medicine suggests the field helps those in healthcare to deepen their self-awareness, clinical attunement, collaborative skills, and creative capacities through rigorous narrative training and practices. They contend that "narrative medicine is based on the idea that human beings understand themselves primarily in terms of the stories they tell to others and themselves.
According to this idea, joy or suffering, and the meanings we attribute to these, do not arise from events alone.
" Ms Rogers, who is Associate Director and Lecturer in the Programme in Narrative Medicine, explained the origins of the programme. She outlined how Dr Charon went to medical school and studied pharmacology, anatomy, physiology and chemistry but later on, as patients came to her, she began to feel there was something missing. While stories were what her patients were coming with, nobody had told her how to dissect these stories. It was at that point Dr Charon made the decision to go to the English department and sought to learn about stories. Undertaking a PhD, which she completed in 1999, she specialised in the works of Henry James and became convinced that the skills that she developed were necessary to good patient care. "You do have to have anatomy and physiology; you do have to know what medication is going to work. But you also need to know what you're being told and how you're being told. And there are scientific ways of understanding this," said Ms Rogers.
DEEP SCIENCE
Dr Charon's argument was that storytelling was a deep science that could be learned and must be learned in order for there to be optimal healthcare. One very strong aspect of the practice of narrative medicine was having a signature method. Narrative medicine training stresses 'close reading' of literary texts to gain greater skills in paying attention to patients and their stories. It also highlights 'close listening', or radical unframed listening, to boost self-knowledge and deepen professional relationships with healthcare colleagues. Close reading in narrative medicine is paired with 'prompted writing', which "does not aim to foster future novelists", but to develop a deeper appreciation of patients' stories, and a more informed personal response to those stories. Ms Hermann and Ms Rogers gave a brief sense of how they work with a group of HCPs sitting around a table, where they would bring in a poem or artwork. They would then ask participants to look at closely at the text, or piece of art, and respond to it. Ms Rogers said: "This is 'close reading', but only if facilitated by narrative medicine specialists. We have a Masters programme to train people to do that, both medical and [other] healthcare people, artists and scholars.
After looking at this artwork, it could be a visual artwork or music, we give them a writing prompt. Then they write for four minutes and read to each other what they have written and we respond to what they have written." Reflection was part of the work, but Ms Hermann said they were focused more on creative work. A common misconception was that participants would be asked for a writing prompt to reflect on a recent patient encounter and what they might have done differently if they could do it again.
"That's not what we're doing at all. For us, a prompt might be, usually, quotes from the text that we're reading. It's connected to what just happened in the room," said Ms Hermann, who is also Lecturer in the Department of Medical Humanities and Ethics at Columbia University's Irving Medical Centre. She underlined that it was very open-ended, with participants deliberately asked to write whatever came to them.
"They may write about a recent patient encounter if that's what comes to them, but they also might write about their childhood or their father — a very important part of what happens — because then people connect to one another in a much deeper way, and are able to see each other as human beings." Ms Rodgers and Ms Hermann believe the best way to understand the method more clearly was by trying it out or practising it.
A framework of three skills of narrative medicine in practice have been discussed extensively by Dr Charon in her lectures, books and journals and they build learning to better attend, represent and affiliate. In The Principles and Practice of Narrative Medicine, Dr Charon and co-authors stated their goals were "to increase the capacity of our learners to notice things, to be curious about words, to enter alien narrative worlds without fear or indifference, to gain insight into their own characterological moves in interpreting stories, and to be open to the beauty of what they receive."
SHAME IN THE GAME
The Rise Of Extremism


text:
Q: How to load user's file in Flash? I would like to load a user's file right after the app is inicialized. I have this code:
fll = new FileReference();
fll.browse([new FileFilter("Text *.txt", "*.txt")]);

It works fine when some button is pressed, but when i just put it inside the frame's code, it doesnt work. How can i do it?

A: This function works only on user interaction (mouse click, key press etc) for security reasons, so it won't work when you paste it in regular frame script.

A:    Try this code, hopefully this will work for you:

   import flash.text.*;
   import flash.net.FileReference;

   var tf:TextField = new TextField();
   tf.width = 350
   tf.height = 350
   tf.multiline=true;
   tf.border = true
   addChild(tf);

   var fileReference:FileReference = new FileReference();
   var fileFilter:FileFilter=new FileFilter("Images","*.txt");
   fileReference.addEventListener(Event.SELECT, onSelectFile);
   fileReference.addEventListener(Event.COMPLETE,onFileComplete);
   bBrowse.addEventListener(MouseEvent.MOUSE_DOWN, browseFile);

   function onFileComplete(event:Event):void
   {
      tf.htmlText = "opening: "+fileReference.name+"<br>"
      var bytes:ByteArray=fileReference.data;
      var newtext:String=fileReference.data.readMultiByte(fileReference.data.length,"gb2312");
      //var newtext:String = fileReference.data.readUTFBytes(fileReference.data.length)
      tf.appendText(newtext);
    }

    function browseFile(e:MouseEvent)
    {
        fileReference.browse([fileFilter]);
    }

    function onSelectFile(event:Event):void
    {
         fileReference.load();
    }

redpajama_set_name: RedPajamaStackExchange


The Train & Travel is one of the most popular training events the IKMF offers. The popularity of this course is two-fold: it combines amazing training AND an opportunity to sightsee through Israel. This course is open to ALL levels of Krav Maga, including no experience at all, and families are encouraged to attend. During your time in Israel, you will have the opportunity to train with several members of the Global Instructor Team, the IKMF's highest ranked instructors.
IF YOU WISH TO COMBINE THE BEST KRAV MAGA TRAINING AVAILABLE WITH TOURING ISRAEL, THIS IS THE PROGRAM FOR YOU!
The winter program takes place in Israel. Its total cost is 1400 Euro, Including: 3 star Hotel (B&B, double occupancy); Touring Israel (including entry fees to all locations); Private transportation to all locations; Krav Maga and related training.
Law Enforcement training methods, developed by Israeli law enforcements units. Also, Participants experience Israeli firing techniques at a shooting range with certified tactical instructors.
VIP Protection intensive training following Israeli governmental executive protection units methods, emphasizing on first circle defense system.
Military: Learning to function under intense strain while implementing Israeli commando self defense techniques, and much more!
Civilian: Training sessions with Avi Moyal, following techniques developed by Imi Lichtenfeld himself!
Customized Krav Maga: A taste of additional training methods adapted for unique working environments; i.e.: CQB, Air marshals, close quarter battle situations.
Operational driving & car rage (by request): Learning how to operate a vehicle against car jacking or attacks inside the vehicle based on techniques developed by Master Avi Moyal for confidential factors of the Israeli government.
Three days will be dedicated to touring Israel, spiced by on the tour trainning. (Locations may vary !!!).
The Dead-Sea: The lowest point on earth renowned for its medicinal qualities.
Jerusalem: Yad Vashem, the old city and the Western Wall, and the Church of the Holy Sepulchre.
Tel Aviv: Party in TLV, experience the city that never sleeps with its active night life, clubs, pubs and beautiful beach strip!
North Israel - The Galili ridge and sea.
Training Clothes: Bring enough clothes to last you for three training sessions (wash & hang in your room if you don't want to pack to much).
Training Gear: Groin protection is highly recommended. Also optional: mouthpiece, shin guard, hand wraps.
Training Shoes: when training in the gym wrestling shoes or barefoot. On outdoors training regular sneakers are fine. Bring an extra pair for water training.
Shooting range gear: If you prefer your own eye and ear protection when shooting, bring it; otherwise, it will be provided.
Israel is a small country with only one international airport, named "Ben Gurion". Remember your passport, wallet, international driver's license, health insurance card, credit card, ATM card.
Check to see that your ATM code works in Israel (verify with your bank); credit cards are accepted in most places.
Make copies of your important documents, and keep them separate from the originals.
Be sure to attach luggage tags to your suitcase.
Be sure to pack; sun glasses, sunscreen, bathing suit, travel towel, personal hygiene objects.
If there is a chance of visiting holy sites that day, wear short sleeved shirt, long pants closed toe shoes, and bring a hat.
Food is very good, relatively inexpensive and safe. For quick, filling meals, try "Falafel" (vegetarian), "Schwarma" (like Greek gyros, only better) and the many fruit smoothies. Israel is the country of milk & hony.
The beach at Tel Aviv is lively and safe late into the night.
This is the Middle East; don't expect American service, or manners, But you will feel the warmth and love of middle eastern hospitality.
MAH NISHMA - How's it going?


Love it or hate it, you have to admit that the Shard, currently the tallest building in all of Europe at 306 metres high, and the newest addition to the London city skyline, makes for quite an impression on the eye, not least because its construction in the London Bridge area rather than the more developed City, means that the skyscraper is something of a lone ranger in amongst a terrain of far shorter historical constructions. While I had my reservations at first, particularly when I saw the building on completion and realised that the jaggard edges at its summit (said to resemble shards of glass – hence the name) were not going to come together into a satisfying point, I have to admire the way that this vast building stretches into the sky for as far as the eye can see, bursting out of the Bermondsey skyline as an indisputable symbol of man's quest to build higher and higher into the realms where only nature has previously reined free.
But seeing the mighty Shard from a distance is one thing – how about dining at its foot, on the roof top of a nearby restaurant with the more recognisable skyline of riverside London reflected in the Shard's huge glass facades? Well that was exactly the dining experience I enjoyed at the end of last week when, with my dear friend Celia, master baker and author of the indefatigably brilliant Lady-Aga blog, we spent the late-summer's evening at the Rooftop Café of the Exchange building, a laid-back antipodean affair, where aussie chefs and suitably chilled-out waiters serve a menu loaded with tantalising light summer treats, to be savoured while enjoying the view which, thanks to the reflective surfaces of skyrise buildings all around, could be seen wherever the eye did venture.
So while you must excuse the fact that, for all those fine views, my memory of the food is less precise (luckily my fellow diner was more astute in that respect, and I will let her review on Lady-Aga fill you in on all the gastronomic details), as The Daily Norm's favourite photo(s) of the week will testify, the view of London was simply too breathtaking to let food take centre stage. I could, in fact, fill this post with photos of the views which I took on my handy iphone that evening, as the sky over London went from a fair-weather cloud scattered lemony yellow, to a rich raspberry pink. However in an attempt to pare down my selection to a mere few, I have selected what was undoubtedly my favourite view of all – the double whammy which was provided in seeing the recognisable London skyline (London Eye and Parliament included) reflected in the sparkling new surfaces of the glazed and angular shard.
Quite unable to choose between these three views, each taken slightly later during the evening, I simply opted for all three. One series – a view in transition – taken in three successive shots.
All photos and written content are strictly the copyright of Nicholas de Lacy-Brown © 2013 and The Daily Norm.
Good shot, very good, and fine way to approach a building this tall, having a reflective view of it..
Thank you! Yes otherwise tall buildings can be a bit boring up close. I was genuinely impressed with the shard's ability, with its slightly angled panes, to reflect the skyline so magnificently!


Sports Reporter Chip Brierre is now working at WJLA-TV in a temporary position. He's open to any news OR sports job. He's an engaging, energetic professional with a charismatic and confident on-air demeanor. A top-notch storyteller, Chip is also an experienced play-by-play announcer. If you need a person of substance who viewers find comfortable and credible, look no further! Please take a look!
See all of Chip's clips.
2016 AP Outstanding Sports Operations, large market.
2015 AP Best Sports Anchor, large market.
2015 VA Assoc. of Broadcasters Award for outstanding sports coverage.
WJLA-TV, Washington: Sports Reporter, Temp (April 2019 - present).
WRIC-TV, Richmond: Sports Anchor/Reporter (June 2014 - July 2018).
Broke story on VCU head coach Shaka Smart leaving to take Texas head coaching job.Award-winning coverage of 2015 & 2016 NCAA Tournament runs for the Virginia Cavaliers.
Exclusive coverage of VCU Baseball's historic NCAA Super Regional in Miami. Anchor/produced top-rated weekly local high school football and basketball shows. Assisted in procuring lucrative sponsorships such as Papa John's, Ford Automotive, Haley Auto Group. Voted area's best local sports anchor by Richmond Magazine (2015, 2016, 2017).
UMTV, Miami: Anchor/Reporter (Fall 2010 – April 2014).
Anchored and produced weekly, live, award-winning, 30-minute collegiate sports broadcast.
Anchor, reporter, analyst, staff writer and segment producer. Covered breaking news, shot games, practices and stories. Led coverage of Nevin Shapiro scandal. Insider access to Miami Hurricanes athletics through developed relationship leading to exclusive content.
WVUM, University of Miami Radio: PBP and Host (Sept. 2010 – 2014).
Play-by-Play and Color Commentary for five different sports. Host "Ibis Sports Weekly" and "Hurricane Sports Weekend", hour-long, all-sports, call-in shows.
WFOR-TV, Miami: Sports Department Intern (Jan. 2012 - July 2012).
University of Miami, Coral Gables: Bachelor of Science in Journalism.
Sony HD and XDCAM cameras, Panasonic HMC cameras, Final Cut Pro, Avid, Edius, NewsCutter, ENPS, iNEWS, CoolEdit Pro, Adobe Edit, Microsoft Office and Excel. Control room audio board, digital playback and graphics production.
Mike Vrabel (former supervisor), Asst. News Director, WRIC-TV, Richmond, 804-330-8838.
Catherine Shelor (former supervisor), EP, WRIC-TV, Richmond, 804-330-8811.
Juan Conde (colleague), Anchor, WRIC-TV, Richmond, 804-330-8822.


Secretary of Defense Chuck Hagel gave a preview Monday of his budget recommendations for the next fiscal year.
Hagel said the budget will preserve all three legs of the nuclear triad, which includes the intercontinental ballistic missiles located at Malmstrom Air Force Base.
Those investments were not detailed, nor was the force structure and manning levels of the preserved nuclear triad.
Last week, Pentagon officials told the Great Falls Tribune that Hagel's office directed the Air Force to initiate an environmental assessment to collect information from all three missile bases on the effect of eliminating no more than 50 ICBM silos in determining options for New START treaty reductions, required by February 2018.
Hagel's proposed budget calls for significant personnel reductions, retiring aircraft and reducing other weapons system purchases.
The National Guard and Reserves will also shrink, under Hagel's proposal, from 355,000 in the Army National Guard and 205,000 Reserve soldiers to 335,000 in the Guard and 195,000 Reserves by 2017. If sequestration returns in 2016, those numbers would continue to decline, Hagel said.
"With the wars in Iraq and Afghanistan coming to a close, it makes sense to take a hard look at military contracting and waste at the Defense Department. I will continue to fight for responsible investments in our troops, their families and our nation's veterans, while standing up against attempts to cut the salaries or benefits earned by our military men and women," Sen. Jon Tester, D-Mont., said in a statement.
Personnel pay increases and benefits would also see slower growth in the coming years. Since 2001, pay and benefits have increased about 40 percent more than growth in the private sector, Hagel said.
But with the first defense budget in 13 years that isn't built around major combat operations, Hagel is proposing to slow the growth of tax free housing allowances, simplify the military health care insurance program and reduce the direct subsidy to military commissaries annually.
The entire defense budget is expected to roll out next week.
In his budget preview, Hagel did not mention C-130s, the plane coming to the Montana Air National Guard starting next week.