What are clients saying about working with Tracy?
"I never imagined I could experience so many powerful results."
"I've learned practical, easy to implement strategies to stay on track."
"Before Tracy and I worked together, my challenge was finding within me the key to allowing myself to be more visible in the entrepreneurial world. I knew there was something holding me back that connected my numerous manifestations of this particular version of self-sabotage, but despite my best efforts I couldn't get to the bottom of the issue. I felt trapped in a vicious circle of questioning and guessing that only Tracy's expert guidance was able to break through and help me get clarity around the deeper truth about myself that I was seeking without success for so long. Discovering this missing piece of the puzzle has brought me home to what my mind, body, and soul truly require to thrive, and has allowed me to release several old patterns, beliefs, and emotions that were dragging me down and keeping me small. I've learned practical, easy to implement tools and strategies to stay on track and continue upgrading my energetic frequency. Not only did I get the answer to my biggest self-discovery question, I also experienced a significant identity shift. I see myself in a much more empowered way today, and feel unstoppable! And, now I know what to do and how to do it to avoid the pitfalls I was so fast to fall into in the past. Priceless!
"My business tripled, almost immediately."


text:
» Business Opportunities
» Representatives
1 - 12 of 1200 listings
THI$ I$ TOO $$$Imple!
Representatives - Micaville (North Carolina) - May 29, 2021 Free
{$1000 Cash Daily in Mailbox!?|MONEY FOR NOTHNG? PRACTICALLY!|THI$ I$ TOO $$$Imple!|BECOME A MONEY MAGNET TODAY!|CHECKS KEEP POURING IN!} Legal, ethical, exciting and fun! No MLM, pyramids, or nonsense! Website reveals all. www.thegoodlifewithjohn.co...
SIMPLE COPY AND PASTE SYSTEM EARNING 100% COMMISSIONS
Representatives - Bennington (Nebraska) - August 3, 2021 Free
100% Commissions ALL Day..$300 $150 $50 Hey there! This ad is going to be short & sweet.. My team is making 100% Commissions left & right up to $300 over and over again! This is probably the most important ad you will read today! Why? Because it's ca...
Make Daily Money With No Monthly Fees
Representatives - Surf City (North Carolina) - July 4, 2021 Free
Don't Join Another Biz Opp Until You Watch This. Get Tons Of Free Bonuses just for opting in and learn how EVERYONE Gets Paid Daily & gets a total of 86 bonuses & resources. Get All the proof you need today and begin earning daily by tomorrow. ======...
Receiving lots of CA$H is Easy
Representatives - Verdi (Nevada) - July 31, 2021 Free
Learn how to make automated income online! It's Legal, ethical, exciting & fun! No MLM, chains, pyramids, or nonsense! Website Reveals All! Www.Make11ktoday.com ====================== Click here for More details.... ======================
Representatives - Trent (South Dakota) - May 29, 2021 Free
Top Secret Website allows Ordinary Folks to make alot of cash weekly
Representatives - South Strafford (Vermont) - August 10, 2021 Free
Lets Create Success at Home Check out these Social Proof Videos about real people making real cash weekly and how you can too. Do what most people won't, so you can live like most people can't. ====================== Click here for More details.... =...
Complete Turnkey Makes Thousands on Autopilot!
Representatives - Harrington (Delaware) - December 24, 2021 Free
Make Multiple Income Streams, Never have to speak to anyone, Your Own Personal Travel Agency, Market and Manage All Your Affiliates Offers, Complete AutoResponder Set up for you with letters, and that just a fraction of what you get. Only pay once fo...
$1000 Cash Daily in Mailbox!?
Representatives - Newington (Connecticut) - May 29, 2021 Free
Representatives - Ellsworth (Wisconsin) - May 29, 2021 Free
Retire with coach Clifford
Representatives - - January 20, 2022 Free
Retire with coach Clifford We market and license Digital Informational and Educational product packages through our membership system along with marketing our business opportunity itself. Don't miss out on this amazing opportunity to changes your lif...
Make $100 Again and Again
Make $100 Again and Again New technology by Textbot text sms marketing lead generation system, sales funnel creator for smart mobile phone. It holds real time, human-like text message conversations with everyone I connect her up with. It actually ans...
Your FREE Lead System
If you "really" want more leads for your business and I mean REALLY, then you owe it to yourself to check this system out. Please visit here for more details...
Save this ad... Frame it when you're rich!
Representatives - Willow Lake (South Dakota) - January 19, 2022 Free
Save this ad... Frame it when you're rich! Learn how to make 2K, 5K, 10K per month from home. You decide how much you want to make. Fully automated system does all the work for you. You never have to talk to anyone. Click on the link below. Plea...
Push-button autopilot traffic!
Save money & get more traffic too! The Most Powerful Income & Lead Generation System Here's what you get with this system: ==> 100 drip-fed "Business Opportunity" email subscribers into your contact list EVERY 24-Hours... ==> Done-for-you emailing pl...
Why are you still broke? Come get your cash! Learn how to make 2K, 5K, 10K per month from home. You decide how much you want to make. Fully automated system does all the work for you. You never have to talk to anyone. Click on the link below. Pl...
Representatives - South Amboy (New Jersey) - January 19, 2022 Free
The New Tech Millionaires
You can make thousands, and ten of thousands of dollars on a regular basis with this system without having to worry about the technical aspect of creating your online business. Click here for More details....
Join a Multi-Billionaire and His Winning Team
Representatives - Megargel (Texas) - January 19, 2022 Free
U.S. Multi-Billionaire Seeks Serious Partners Build Your Business With A U.S. Multi-Billionaire! While other companies PROMISE ... this one DELIVERS PROOF! --> GET DETAILS! http://gethappycapture.com/dr2/ To Our Mutual Success, Dale Rust PS. Check Yo...
Make Money While You Sleep
Come join this simple 3 step opportunity you can't go wrong with this system! Half of Million is paid in the company in 2 months! I can't make this up check out the video! ====================== Click here for More details.... ======================
FREE entry! Proven $12 system 100% payouts
Representatives - Clayton (New Mexico) - January 19, 2022 Free
FREE entry! Proven $12 system 100% payouts $500-$5000 monthly on autopilot 100% commissions! Proven #1 business since 2016. Started 2009. FREE $12 funnel system for 7 days. Team bonuses. Take the tour: www.path4wealth.com ====================== Click...
Want Passive Income? I'll Show You How To Get It!
Representatives - Cumberland (Rhode Island) - January 19, 2022 Free
RECOMMENDED BY TODAY'S TOP MARKETERS! Why would today's top marketers all recommend 1 website? Because it works! Will it work for you too? There is only one way to find out and it starts by visiting our website today! ====================== Click her...
Representatives Alabama
Representatives Alaska
Representatives Arizona
Representatives Arkansas
Representatives California
Representatives Colorado
Representatives Connecticut
Representatives Delaware
Representatives District of Columbia
Representatives Florida
Representatives Georgia
Representatives Hawaii
Representatives Idaho
Representatives Illinois
Representatives Indiana
Representatives Iowa
Representatives Kansas
Representatives Kentucky
Representatives Louisiana
Representatives Maine
Representatives Maryland
Representatives Massachusetts
Representatives Michigan
Representatives Minnesota
Representatives Mississippi
Representatives Missouri
Representatives Montana
Representatives Nebraska
Representatives Nevada
Representatives New Hampshire
Representatives New Jersey
Representatives New Mexico
Representatives New York
Representatives North Carolina
Representatives North Dakota
Representatives Ohio
Representatives Oklahoma
Representatives Oregon
Representatives Pennsylvania
Representatives Rhode Island
Representatives South Carolina
Representatives South Dakota
Representatives Tennessee
Representatives Texas
Representatives Utah
Representatives Vermont
Representatives Virginia
Representatives Washington
Representatives West Virginia
Representatives Wisconsin
Representatives Wyoming

redpajama_set_name: RedPajamaCommonCrawl


Magnetic resonance imaging (MRI) is an indispensable method for diagnosing diseases and monitoring the course of treatment. It creates sectional images of the human body without the use of any harmful radiation. Typically, the water molecules in the tissue are exposed to a strong magnetic field. However, MRI is very insensitive and needs a high concentration of molecules in order to absorb a usable signal. Contrast media are often used to improve diagnostics in order to detect specific changes such as tumors more clearly.
However, even with these contrast media, the sensitivity of MRI cannot be significantly increased, and many markers that are known from cell biology cannot be detected during imaging. Besides this, the safety of certain contrast media containing the element gadolinium is currently the subject of increasing discussion. "We need new, improved methods in which as little contrast medium as possible influences as much of the signal-transmitting substance as possible, which is typically water," said FMP researcher Dr Leif Schroeder. He and his team have now achieved an important breakthrough.
The researchers have been working for some time in developing contrast media based on xenon, a harmless noble gas. The group employs a process with powerful lasers in which the xenon is artificially magnetised and then – even in small quantities – generates measurable signals. To detect specific cellular disease markers, the xenon has to be bound to them for a short time. In a cooperation with scientists from the California Institute of Technology (Caltech) funded by the Human Frontiers Science Program (HFSP), Dr Leif Schroeder and his team have now looked into a new class of contrast media that binds the xenon reversibly. These are hollow protein structures produced by certain bacteria in order to regulate the depth at which they float in water, similar to a miniaturised swim bladder in fish but on a nanometer scale. The research group led by cooperation partner Mikhail Shapiro at Caltech introduced these so-called "gas vesicles" some time ago as MR contrast media. However, it was not yet known how well they could be "charged" with xenon.
In the study both groups described how these vesicles form an ideal contrast medium: They can "elastically" adjust their influence on the measured xenon. "The protein structures have a porous wall structure through which the xenon can flow in and out. Unlike conventional contrast media, the gas vesicles always absorb a fixed portion of the xenon that is provided by the environment, in other words also larger amounts if more Xe is provided," Dr Leif Schröder reported.
This characteristic can be employed in MRI diagnostics, because more xenon must be used in order to obtain better images. The concentration of a conventional contrast medium would also need to be adjusted in order to achieve a change in signal for all the xenon atoms. The gas vesicles, on the other hand, automatically fill up with more xenon when this is offered by the environment.
"They act like a kind of balloon, to which an external pump is attached. If the balloon is 'inflated' by xenon atoms flowing into the gas vesicle, its size does not change, but the pressure does increase – similar to a bicycle tire tube," explained Dr Leif Schroeder.
Because much more xenon passes into the vesicles than with conventional contrast media, the xenon atoms can then be read out much better after they have left the vesicle again and show a changed signal.
This way, the image contrast is many times higher than the background noise while the quality of the image is significantly improved. These contrast media can thus also be used to identify disease markers that occur in relatively low concentrations.
During the further course of the cooperation, the two groups intend to test these contrast media in initial animal studies. The newly discovered behavior will be a decisive advantage in order to use these very sensitive contrast media in living tissue as well. Dr Leif Schroeder and his team were able to make the first MRI images with particle concentrations one million times lower than those of the contrast media currently employed.
The study has been published in the journal ACS Nano.


Hoover Penrod PLC assists individuals and businesses throughout the Shenandoah Valley with a wide range of real estate needs. Because we do our own title examinations and document preparation, we can assure you of thorough legal representation. We also have decades of experience negotiating contracts and litigating real estate disputes.
Purchasing a property is a major financial decision. If you are about to close on a property, you will be asked to sign many legal documents that will commit you to specific legal obligations. Hoover Penrod PLC offers you the advantage of attorneys who can explain these documents and advise you when you have questions. If you have a problem or complication with real estate, we have the experience and skill to help you.
Our attorneys can assist you with every aspect of the lending and refinancing process, from real estate loans and refinancing to modification and short sales.
If you need assistance with a real estate issue, please contact Hoover Penrod PLC or call 540-433-2444 to schedule a consultation with one of our real estate attorneys. We serve clients throughout Harrisonburg, Staunton, Winchester, and the nearby areas in Virginia.


text:
Airbnb is canceling reservations in DC during inauguration week
Growing up.
Image: Reuters/Carlo Allegri
Michelle Cheng
Airbnb is canceling and blocking reservations in the Washington DC metro area during inauguration week. The drastic decision was informed by reports of "armed militias and known hate groups that are attempting to travel and disrupt the Inauguration" of US president-elect Joe Biden, the company said in a blog post. Airbnb also discussed the matter with local government and police officials and with members of Congress, a spokesperson for the company tells Quartz.
Washington DC mayor Muriel Bowser, Maryland governor Larry Hogan, and Virginia governor Ralph Northam all have discouraged visitors from traveling to the DC metro area next week. Airbnb says customers whose reservations are canceled will be refunded in full, and hosts will be reimbursed by the company.
Like other gig companies, Airbnb has had a tumultuous relationship with government officials. It has faced a slew of regulatory battles in cities around the world (and still does). But its dialogue with DC public officials suggests the company, which went public last month, has grown into its role as a corporate citizen. In addition to improving relations with regulators, Airbnb has in recent years made efforts to improve safety, for example booting off users associated with violent hate groups, in advance of specific events like the white supremacist march in Charlottesville, Virginia, in 2017. (After the deadly insurrection at the US Capitol, Airbnb said it had canceled DC reservations made for that week by alleged members of groups like the Proud Boys.)
Out of all the big gig companies, Airbnb has been the most outspoken about the recent attack. Last week, the company announced it will be "pausing" political donations to Congressional Republicans who objected to certifying the election results.
It is unclear whether other lodging companies will join Airbnb in suspending reservations in Washington. Hyatt Hotels said its DC properties will remain open, although the company is "strongly encouraging" essential travel only from Jan. 15 to Jan. 22, including stays by essential workers or people caring for others left vulnerable in the pandemic. A spokesperson from Hilton said the company has "no plans to cancel hotel reservations and look[s] forward to welcoming the many Inauguration-related suppliers, government officials, medical professionals, media representatives, military and law enforcement who are traveling to Washington DC."
This article has been updated with Hyatt Hotels' intention to keep its DC hotels open during the week of the inauguration.


text:
Q: grep is not finding a pattern of \n and hyphens together (but can find them separately) I have some apt files that have code in them like this:
---

some code

---

Sometimes there's a blank line following the opening ---, or before the closing ---. I want to compress these (get rid of the unwanted "inside" blank lines). I'm quite willing to do so manually, but I'd like to print out a list of where all those are. I'm actually looking for \n\n---\n\n, but in the following I'll just show my work on \n\n---.
I've tried many variations on the following with no success:
grep -E \n\n---\n\n file.apt

Escaped the backslashes, tried \r, single and double quotes, grep --, w/o -E, ^$, etc. The following works:
grep \n\n file.apt

It prints all the right lines. The following also works:
grep "\---" file.apt

It prints all of the lines that have 3 hyphens. However, the following prints nothing:
grep "\n\n\---" file.apt

If I try that pattern (\n\n---) in vi I find what I'm looking for. All the failed grep attempts print nothing. So how can I find "\n\n---"?
I'm on Mac OSX, terminal command line.

A: It is my understanding that grep only matches a single line at a time. If you want to get rid of blank lines try running
grep ^$ -v file.apt

^$ will match every blank line and then the -v will print only lines that don't match.

A: This is basically a duplicate of: How to find patterns across multiple lines using grep?
There are good answers there that should help you. I'd probably use the sed option for what you are doing.

redpajama_set_name: RedPajamaStackExchange


text:
Q: Refresh ASP.NET page periodically to display real time data from SQL Server I have a shopping cart based application in asp.net 2.0 which uses the concept of group buying.My requirement is that when user checks out a particular product,he should do it with the latest price of that item at that time.
Now there is a scenario.
I have a product with price 50.I did a checkout.50 is displayed in my cart.At the same time some other user is accessing the product and now based on some business logic,we calculate the price.the second user did some activity which reduced the price to 45. I have a trigger which updates all shopping cart items with this new price.
I want to show this updated price on the frontend of the first user without a postback. or i want to give him a message that this price has changed so do a page refresh.
I have the following options.
1) The repeater control which shows the cart should be put under an update panel and that update panel should be refreshed after some interval using a timer.
2) use SQL Server notification services and invalidate the cache as soon as the data changes in database.
I do not want to use notification services as I am not caching the data.Secondly problem with update panel and timer control in that it will be a overhead to refresh it and refresh time is hard to find.
Please tell me a way to accomplish this scenario.

A: This is usually done via ajax from the client (browser) side of things. Perhaps this approach will work for your requirements as well?
Using ExtJs core, you can make an ajax call as follows:
Ext.Ajax.request({
   url: 'ajax_demo/sample.aspx',
   params : {'requestType':'check-sql-prices'}
   success: function(response, opts) {
      var obj = Ext.decode(response.responseText);
      // process the response JSON object.
   },
   failure: function(response, opts) {
      // this writes the the firebug console.
      console.log('server-side failure with status code ' + response.status);
   }
});

Ext Core also handles "Timed Code Execution", so you could run the check, say, every 30 seconds. Round trip timing is usually less than 100 milliseconds, but that would definitely depend on your "SQL price checking" logic.

A: I would generate JavaScript that updates all Repeater items (html fields with prices), and has setTimeout() for periodical checking to web service (wcf, asmx or ashx) if price has changed. If it has, then i would retrieve all prices and update HTML fields! User don't need to prees anything, you can show him some notice that price has changed.
With jQuery and JSON for object serialisation this could be easily accomplished.


Fanaleds 2.4 is here and with some major changes! On big demand Fanaleds now supports the Logitech G29 and the game Automobilista. In this version there is also improved support for rFactor based games, the Fanatec CSP V3 pedals and the Leo Bodnar Fanatec Rim conversion PCB. There is now also support for the Precision Sim Engineering Formula Rim and Assetto Corsa Pro.
In the latest major release of Fanaleds we have focused on bringing a lot of new features and bug fixes. All problems with the Fanatec CSP v3 should now be fixed, including brake and throttle rumble. All owners of the Logitech G29 should be happy with this release as well, Fanaleds now supports this steering wheel. Automobilista players are now able to enjoy the broad features Fanaleds offers with this support. Please note that the Leo Bodnar Fanatec Rim conversion PCB needs a new firmware version to be fully compatible. This can be downloaded from the Leo Bodnar website. Owners of the Formula Rim by Precision Sim Engineering will also need to update their firmware in order to have Fanaleds support.


text:
/**
 * @class Ext.view.AbstractView
 * This is an abstract superclass and should not be used directly. Please see {@link Ext.view.View}.
 * @private
 */
Ext.define('Ext.view.AbstractView', {
    extend: 'Ext.Component',
    requires: [
        'Ext.LoadMask',
        'Ext.CompositeElementLite',
        'Ext.selection.DataViewModel',
        'Ext.view.NavigationModel'
    ],
    mixins: [
        'Ext.util.StoreHolder'
    ],

    inheritableStatics: {
        getRecord: function(node) {
            return this.getBoundView(node).getRecord(node);
        },

        getBoundView: function(node) {
            return Ext.getCmp(node.getAttribute('data-boundView'));
        }
    },

    defaultBindProperty: 'store',

    /**
     * @private
     * Used for buffered rendering.
     */
    renderBuffer: document.createElement('div'),

    statics: {

        /**
         * @cfg {Number} [updateDelay=200] Global config for use when using {@link #throttledUpdate throttled view updating} if the data in the backing {@link Ext.data.Store store}
         * is being changed rapidly, for example receiving changes from the server through a WebSocket connection.
         *
         * To avoid too-frequent view updates overloading the browser with style recalculation, layout and paint requests, updates can be {@link #throttledUpdate throttled} to
         * coalesced, and applied at the interval specified in milliseconds.
         */
        updateDelay: 200,

        queueRecordChange: function(view, store, record, operation, modifiedFieldNames) {
            var me = this,
                changeQueue = me.changeQueue || (me.changeQueue = {}),
                recId = record.internalId,
                recChange,
                updated,
                len, i, fieldName, value,
                checkForReversion;

            recChange = changeQueue[recId] || (changeQueue[recId] = {
                operation: operation,
                record: record,
                data: {},
                views: []
            });

            // Hash of original values
            updated = recChange.data;

            // Make sure this view is among those updated when record changes are flushed
            Ext.Array.include(recChange.views, view);

            // Note the following condition tests the result of an assignment statement.
            // If we have been informed that specific fields have changed.
            if (modifiedFieldNames && (len = modifiedFieldNames.length)) {
                for (i = 0; i < len; i++) {
                    fieldName = modifiedFieldNames[i];
                    value = record.data[fieldName];

                    // More than one update is being performed...
                    if (updated.hasOwnProperty(fieldName)) {

                        // If the update is back to the original value, this may have reverted the record to original state
                        if (record.isEqual(updated[fieldName], value)) {
                            delete updated[fieldName];
                            checkForReversion = true;
                        }
                    }

                    // On first update, cache the original value
                    else {
                        updated[fieldName] = value;
                    }
                }

                // If the record has been returned to its original state, delete the queue entry.
                // checkForReversion flag saves the expensive (on legacy browsers) call to Ext.Object.getKeys
                if (checkForReversion && !Ext.Object.getKeys(updated).length) {
                    delete changeQueue[recId];
                }
            }

            // Unpsecified fields have changed. We have to collect the whole data object.
            else {
                Ext.apply(updated, record.data);
            }

            // Create a task which will call on to the onFlushTick every updateDelay milliseconds.
            if (!me.flushQueueTask) {
                me.flushQueueTask = Ext.util.TaskManager.newTask({
                    // Queue the actual render flush on the next animation frame if available.
                    run: Ext.global.requestAnimationFrame ? Ext.Function.createAnimationFrame(me.onFlushTick, me) : Ext.Function.bind(me.onFlushTick, me),
                    interval: Ext.view.AbstractView.updateDelay,
                    repeat: 1
                });
            }
            me.flushQueueTask.start();
        },

        /**
         * @private
         * On every flush (determined by updateDelay setting), ask the animation system to schedule a call to
         * flushChangeQueue at the next animation frame.
         */
        onFlushTick: function() {
            Ext.AnimationQueue.start(this.flushChangeQueue, this);
        },

        /**
        * @private
        * Flushes all queued field updates to the UI.
        *
        * Called in the context of the AbstractView class.
        *
        * The queue is shared across all Views so that there is only one global flush operation.
        */
        flushChangeQueue: function() {
            // Maintainer: Note that "me" references AbstractView class
            var me = this,
                dirtyViews,
                len,
                changeQueue,
                recChange,
                recId,
                i, view;

            // If there is scrolling going on anywhere, requeue the flush operation.
            if (Ext.isScrolling) {
                me.flushQueueTask.start();
                return;
            }

            changeQueue = me.changeQueue;

            // Empty the view's changeQueue
            this.changeQueue = {};

            for (recId in changeQueue) {
                recChange = changeQueue[recId];
                dirtyViews = recChange.views;
                len = dirtyViews.length;

                // Loop through all the views which have outstanding changes.
                for (i = 0; i < len; i++) {
                    view = dirtyViews[i];

                    // View may have been destroyed during the buffered phase.
                    if (!view.destroyed) {
                        view.handleUpdate(view.dataSource, recChange.record, recChange.operation, Ext.Object.getKeys(recChange.data));
                    }
                }
            }
            Ext.AnimationQueue.stop(me.flushChangeQueue, me);
        }
    },

    config: {
        /**
         * @cfg {Ext.data.Model} selection
         * The selected model. Typically used with {@link #bind binding}.
         */
        selection: null,

        /*
         * @cfg {Ext.data.Store} store
         * The {@link Ext.data.Store} to bind this DataView to.
         * @since 2.3.0
         */
        store: 'ext-empty-store',

        // @cmd-auto-dependency { aliasPrefix: 'view.navigation.' }
        /**
         * @private
         * The {@link Ext.view.NavigationModel} [default] alias to use.
         * @since 5.0.1
         */
        navigationModel: {
            type: 'default'
        },

        // @cmd-auto-dependency { aliasPrefix: 'selection.' }
        /**
         * @cfg {Object/Ext.selection.DataViewModel} selectionModel
         * The {@link Ext.selection.Model selection model} [dataviewmodel] config or alias to use.
         * @since 5.1.0
         */
        selectionModel: {
            type: 'dataviewmodel'
        }
    },

    publishes: ['selection'],
    twoWayBindable: ['selection'],

    /**
     * @cfg {Boolean} [throttledUpdate=false]
     * Configure as `true` to have this view participate in the global throttled update queue which flushes store changes to the UI at a maximum rate
     * determined by the {@link #updateDelay} setting.
     */
    throttledUpdate: false,

    /**
     * @cfg {String/String[]/Ext.XTemplate} tpl (required)
     * The HTML fragment or an array of fragments that will make up the template used by this DataView.  This should
     * be specified in the same format expected by the constructor of {@link Ext.XTemplate}. When a `tpl` is specified,
     * this class assumes that records are rendered in the order they appear in the `{@link #store}`. If a custom `tpl`
     * does not conform to this assumption, index values will be incorrect which may cause the view to misbehave.
     * @since 2.3.0
     */

    /**
     * @cfg {Boolean} [deferInitialRefresh=false]
     * Configure as 'true` to defer the initial refresh of the view.
     *
     * This allows the View to execute its render and initial layout more quickly because the process will not be encumbered
     * by the update of the view structure.
     */
    deferInitialRefresh: false,

    /**
     * @cfg {String} itemSelector (required)
     * This is a required setting. A simple CSS selector (e.g. `div.some-class` or
     * `span:first-child`) that will be used to determine what nodes this DataView will be
     * working with. The itemSelector is used to map DOM nodes to records. As such, there should
     * only be one root level element that matches the selector for each record. The itemSelector
     * will be automatically configured if the {@link #itemTpl} config is used.
     *
     *     new Ext.view.View({
     *         renderTo: Ext.getBody(),
     *         store: {
     *             fields: ['name'],
     *             data: [
     *                 {name: 'Item 1'},
     *                 {name: 'Item 2'}
     *             ]
     *         },
     *         tpl: [
     *             '
',
     *             '<tpl for=".">',
     *                 '
{name}
',
     *             '</tpl>',
     *             '
'
     *         ],
     *         // Match the li, since each one maps to a record
     *         itemSelector: 'li'
     *     });
     *
     * @since 2.3.0
     */

    /**
     * @cfg {String} itemCls
     * Specifies the class to be assigned to each element in the view when used in conjunction with the
     * {@link #itemTpl} configuration.
     * @since 2.3.0
     */
    itemCls: Ext.baseCSSPrefix + 'dataview-item',

    /**
     * @cfg {String/String[]/Ext.XTemplate} itemTpl
     * The inner portion of the item template to be rendered. Follows an XTemplate
     * structure and will be placed inside of a tpl.
     */

    /**
     * @cfg {String} overItemCls
     * A CSS class to apply to each item in the view on mouseover.
     * Setting this will automatically set {@link #trackOver} to `true`.
     */

    //<locale>
    /**
     * @cfg {String} loadingText
     * A string to display during data load operations.  If specified, this text will be
     * displayed in a loading div and the view's contents will be cleared while loading, otherwise the view's
     * contents will continue to display normally until the new data is loaded and the contents are replaced.
     * @since 2.3.0
     */
    loadingText: 'Loading...',
    //</locale>

    /**
     * @cfg {Boolean/Object} loadMask
     * False to disable a load mask from displaying while the view is loading. This can also be a
     * {@link Ext.LoadMask} configuration object.
     */
    loadMask: true,

    /**
     * @cfg {String} loadingCls
     * The CSS class to apply to the loading message element. Defaults to Ext.LoadMask.prototype.msgCls "x-mask-loading".
     */

    /**
     * @cfg {Boolean} loadingUseMsg
     * Whether or not to use the loading message.
     * @private
     */
    loadingUseMsg: true,

    /**
     * @cfg {Number} loadingHeight
     * If specified, gives an explicit height for the data view when it is showing the {@link #loadingText},
     * if that is specified. This is useful to prevent the view's height from collapsing to zero when the
     * loading mask is applied and there are no other contents in the data view.
     */

    /**
     * @cfg {String} selectedItemCls
     * A CSS class to apply to each selected item in the view.
     */
    selectedItemCls: Ext.baseCSSPrefix + 'item-selected',

    //<locale>
    /**
     * @cfg {String} emptyText
     * The text to display in the view when there is no data to display.
     * Note that when using local data the emptyText will not be displayed unless you set
     * the {@link #deferEmptyText} option to false.
     * @since 2.3.0
     */
    emptyText: "",
    //</locale>

    /**
     * @cfg {Boolean} deferEmptyText
     * True to defer emptyText being applied until the store's first load.
     * @since 2.3.0
     */
    deferEmptyText: true,

    /**
     * @cfg {Boolean} trackOver
     * When `true` the {@link #overItemCls} will be applied to items when hovered over.
     * This in return will also cause {@link Ext.view.View#highlightitem highlightitem} and
     * {@link Ext.view.View#unhighlightitem unhighlightitem} events to be fired.
     *
     * Enabled automatically when the {@link #overItemCls} config is set.
     *
     * @since 2.3.0
     */
    trackOver: false,

    /**
     * @cfg {Boolean} blockRefresh
     * Set this to true to ignore refresh events on the bound store. This is useful if
     * you wish to provide custom transition animations via a plugin
     * @since 3.4.0
     */
    blockRefresh: false,

    /**
     * @cfg {Boolean} [disableSelection=false]
     * True to disable selection within the DataView. This configuration will lock the selection model
     * that the DataView uses.
     */

    /**
     * @cfg {Boolean} preserveScrollOnRefresh
     * True to preserve scroll position across refresh operations.
     */
    preserveScrollOnRefresh: false,

    /**
     * @cfg {Boolean} [preserveScrollOnReload=false]
     * True to preserve scroll position when the store is reloaded.
     *
     * You may want to configure this as `true` if you are using a {@link Ext.data.BufferedStore buffered store}
     * and you require refreshes of the client side data state not to disturb the state of the UI.
     *
     * @since 5.1.1
     */
    preserveScrollOnReload: false,

    ariaRole: 'listbox',
    itemAriaRole: 'option',

    /**
     * @private
     */
    last: false,
    focusable: true,
    tabIndex: 0,

    triggerEvent: 'itemclick',
    triggerCtEvent: 'containerclick',

    // Starts as true by default so that pn the leading edge of the first layout a refresh will be triggered.
    // A refresh opereration sets this flag to false.
    // When a refresh is requested using refreshView, the request may be deferred because of hidden or collapsed state.
    // This is done by setting the refreshNeeded flag to true, and the the next layout will trigger  refresh.
    refreshNeeded: true,

    updateSuspendCounter: 0,

    addCmpEvents: Ext.emptyFn,

    /**
     * @event beforerefresh
     * Fires before the view is refreshed
     * @param {Ext.view.View} this The DataView object
     */

    /**
     * @event refresh
     * Fires when the view is refreshed
     * @param {Ext.view.View} this The DataView object
     */

    /**
     * @event viewready
     * Fires when the View's item elements representing Store items has been rendered. No items will be available
     * for selection until this event fires.
     * @param {Ext.view.View} this
     */

    /**
     * @event itemupdate
     * Fires when the node associated with an individual record is updated
     * @param {Ext.data.Model} record The model instance
     * @param {Number} index The index of the record
     * @param {HTMLElement} node The node that has just been updated
     */

    /**
     * @event itemadd
     * Fires when the nodes associated with an recordset have been added to the underlying store
     * @param {Ext.data.Model[]} records The model instance
     * @param {Number} index The index at which the set of records was inserted
     * @param {HTMLElement[]} node The node that has just been updated
     */

    /**
     * @event itemremove
     * Fires when the node associated with an individual record is removed
     * @param {Ext.data.Model[]} records The model instances removed
     * @param {Number} index The index from which the records wer removed
     * @param {HTMLElement[]} item The view items removed
     * @param {Ext.view.View} view The view removing the item
     */

    constructor: function(config) {
        if (config && config.selModel) {
            config.selectionModel = config.selModel;
        }
        this.callParent([config]);
    },

    initComponent: function(){
        var me = this,
            isDef = Ext.isDefined,
            itemTpl = me.itemTpl,
            memberFn = {};

        if (itemTpl) {
            if (Ext.isArray(itemTpl)) {
                // string array
                itemTpl = itemTpl.join('');
            } else if (Ext.isObject(itemTpl)) {
                // tpl instance
                memberFn = Ext.apply(memberFn, itemTpl.initialConfig);
                itemTpl = itemTpl.html;
            }

            if (!me.itemSelector) {
                me.itemSelector = '.' + me.itemCls;
            }

            itemTpl = Ext.String.format('<tpl for=".">
{1}
</tpl>', me.itemCls, itemTpl, me.itemAriaRole);
            me.tpl = new Ext.XTemplate(itemTpl, memberFn);
        }

        //<debug>
        if (!isDef(me.tpl) || !isDef(me.itemSelector)) {
            Ext.raise({
                sourceClass: 'Ext.view.View',
                tpl: me.tpl,
                itemSelector: me.itemSelector,
                msg: "DataView requires both tpl and itemSelector configurations to be defined."
            });
        }
        //</debug>

        me.callParent();
        me.tpl = me.getTpl('tpl');

        //<debug>
        // backwards compat alias for overClass/selectedClass
        // TODO: Consider support for overCls generation Ext.Component config
        if (isDef(me.overCls) || isDef(me.overClass)) {
            if (Ext.isDefined(Ext.global.console)) {
                Ext.global.console.warn('Ext.view.View: Using the deprecated overCls or overClass configuration. Use overItemCls instead.');
            }
            me.overItemCls = me.overCls || me.overClass;
            delete me.overCls;
            delete me.overClass;
        }

        if (isDef(me.selectedCls) || isDef(me.selectedClass)) {
            if (Ext.isDefined(Ext.global.console)) {
                Ext.global.console.warn('Ext.view.View: Using the deprecated selectedCls or selectedClass configuration. Use selectedItemCls instead.');
            }
            me.selectedItemCls = me.selectedCls || me.selectedClass;
            delete me.selectedCls;
            delete me.selectedClass;
        }
        //</debug>

        if (me.overItemCls) {
            me.trackOver = true;
        }

        me.addCmpEvents();

        // Look up the configured Store. If none configured, use the fieldless, empty Store defined in Ext.data.Store.
        me.store = Ext.data.StoreManager.lookup(me.store || 'ext-empty-store');

        // Use the provided store as the data source unless a Feature or plugin has injected a special one
        if (!me.dataSource) {
            me.dataSource = me.store;
        }

        // Must exist before the selection model.
        // Selection model listens to this for navigation events.
        me.getNavigationModel().bindComponent(this);

        // Bind to the data source. Cache it by the property name "dataSource".
        // The store property is public and must reference the provided store.
        // The selection model is configured and bound to the store at the top of bindStore.
        me.bindStore(me.dataSource, true, 'dataSource');

        if (!me.all) {
            me.all = new Ext.CompositeElementLite();
        }

        // We track the scroll position
        me.scrollState = {
            top: 0,
            left: 0
        };

        me.savedTabIndexAttribute = 'data-savedtabindex-' + me.id;
    },

    getElConfig: function() {
        var result = this.mixins.renderable.getElConfig.call(this);

        // Subclasses may set focusable to false (BoundList is not focusable)
        if (this.focusable) {
            result.tabIndex = 0;
        }
        return result;
    },

    onRender: function() {
        var mask = this.loadMask;

        this.callParent(arguments);
        if (mask) {
            this.createMask(mask);
        }
    },

    beforeLayout: function() {
        var me = this;

        me.callParent(arguments);

        // If a refresh is needed, just before the layout is the time to apply it.
        // If there is a deferred refresh timer running, allow that to do the refresh.
        if (me.refreshNeeded && !me.pendingRefresh) {
            // If we have refreshed before, just call a refresh now.
            if (me.refreshCounter) {
                me.refresh();
            }
            else {
                me.doFirstRefresh(me.dataSource);
            }
        }
    },

    onMaskBeforeShow: function(){
        var me = this,
            loadingHeight = me.loadingHeight;

        if (loadingHeight && loadingHeight > me.getHeight()) {
            me.hasLoadingHeight = true;
            me.oldMinHeight = me.minHeight;
            me.minHeight = loadingHeight;
            me.updateLayout();
        }
    },

    onMaskHide: function(){
        var me = this;

        if (!me.destroying && me.hasLoadingHeight) {
            me.minHeight = me.oldMinHeight;
            me.updateLayout();
            delete me.hasLoadingHeight;
        }
    },

    beforeRender: function() {
        this.callParent(arguments);
        this.getSelectionModel().beforeViewRender(this);
    },

    afterRender: function() {
        this.callParent(arguments);

        // Subclasses may set focusable to false.
        // BoundList is not focusable.
        // BoundList processes key events from its boundField.
        if (this.focusable) {
            this.focusEl = this.el;
        }
    },

    getRefItems: function() {
        var mask = this.loadMask,
            result = [];

        if (mask && mask.isComponent) {
            result.push(mask);
        }
        return result;
    },

    getSelection: function() {
        return this.getSelectionModel().getSelection();
    },

    updateSelection: function(selection) {
        var me = this,
            sm;

        if (!me.ignoreNextSelection) {
            me.ignoreNextSelection = true;
            sm = me.getSelectionModel();
            if (selection) {
                sm.select(selection);
            } else {
                sm.deselectAll();
            }
            me.ignoreNextSelection = false;
        }
    },

    updateBindSelection: function(selModel, selection) {
        var me = this,
            selected = null;

        if (!me.ignoreNextSelection) {
            me.ignoreNextSelection = true;
            if (selection.length) {
                selected = selModel.getLastSelected();
                me.hasHadSelection = true;
            }
            if (me.hasHadSelection) {
                me.setSelection(selected);
            }
            me.ignoreNextSelection = false;
        }
    },

    applySelectionModel: function(selModel, oldSelModel) {
        var me = this,
            grid = me.grid,
            mode, ariaAttr, ariaDom;

        if (oldSelModel) {
            oldSelModel.un({
                scope: me,
                selectionchange: me.updateBindSelection,
                lastselectedchanged: me.updateBindSelection,
                select: me.ariaSelect,
                deselect: me.ariaDeselect
            });

            Ext.destroy(me.selModelRelayer);
            selModel = Ext.Factory.selection(selModel);
        }
        // If this is the initial configuration, pull overriding configs in from this view
        else {
            if (selModel && selModel.isSelectionModel) {
                selModel.locked = me.disableSelection;
            } else {
                if (me.simpleSelect) {
                    mode = 'SIMPLE';
                } else if (me.multiSelect) {
                    mode = 'MULTI';
                } else {
                    mode = 'SINGLE';
                }

                if (typeof selModel === 'string') {
                    selModel = {
                        type: selModel
                    };
                }
                selModel = Ext.Factory.selection(Ext.apply({
                    allowDeselect: me.allowDeselect || me.multiSelect,
                    mode: mode,
                    locked: me.disableSelection
                }, selModel));
            }
        }

        // Grids should have aria-multiselectable on their ariaEl instead
        if (selModel.mode !== 'SINGLE') {
            ariaDom = (grid || me).ariaEl.dom;

            if (ariaDom) {
                ariaDom.setAttribute('aria-multiselectable', true);
            }
            else if (!grid) {
                ariaAttr = me.ariaRenderAttributes || (me.ariaRenderAttributes = {});
                ariaAttr['aria-multiselectable'] = true;
            }
        }

        me.selModelRelayer = me.relayEvents(selModel, [
            'selectionchange', 'beforeselect', 'beforedeselect', 'select', 'deselect', 'focuschange'
        ]);

        selModel.on({
            scope: me,
            lastselectedchanged: me.updateBindSelection,
            selectionchange: me.updateBindSelection,
            select: me.ariaSelect,
            deselect: me.ariaDeselect
        });

        return selModel;
    },

    updateSelectionModel: function(selectionModel) {
        // Keep the legacy property correct
        this.selModel = selectionModel;
    },

    applyNavigationModel: function (navigationModel) {
        return Ext.Factory.viewNavigation(navigationModel);
    },

    onFocusEnter: function(e) {
        var me = this,
            navigationModel = me.getNavigationModel(),
            focusPosition;

        // Disable tabbability of elements within this view.
        me.toggleChildrenTabbability(false);

        if (!me.itemFocused && me.all.getCount()) {
            focusPosition = navigationModel.getLastFocused();
            navigationModel.setPosition(focusPosition || 0, e.event, null, !focusPosition);

            // We now contain focus is that was successful
            me.itemFocused = navigationModel.getPosition() != null;
        }

        // View's main el should be kept untabbable, otherwise pressing
        // Shift-Tab key in the view would move the focus to the main el
        // which will then bounce it back to the last focused item.
        // That would effectively make Shift-Tab unusable.
        if (me.itemFocused) {
            this.el.dom.setAttribute('tabIndex', '-1');
        }

        me.callParent([e]);
    },

    onFocusLeave: function(e) {
        var me = this;

        // Ignore this event if we do not actually contain focus,
        // or if the reason for focus exiting was that we are refreshing.
        if (me.itemFocused && !me.refreshing) {

            // Blur the focused cell
            me.getNavigationModel().setPosition(null, e.event, null, true);

            me.itemFocused = false;
            me.el.dom.setAttribute('tabIndex', 0);
        }

        me.callParent([e]);
    },

    ariaSelect: function(selModel, record) {
        var node = this.getNode(record);

        if (node) {
            node.setAttribute('aria-selected', true);
        }
    },

    ariaDeselect: function(selModel, record) {
        var node = this.getNode(record);

        if (node) {
            node.removeAttribute('aria-selected');
        }
    },

    onRemoved: function(isDestroying) {
        this.callParent([isDestroying]);

        // IE does not fire focusleave on removal from DOM
        if (!isDestroying) {
            this.onFocusLeave({});
        }
    },

    /**
     * Refreshes the view by reloading the data from the store and re-rendering the template.
     * @since 2.3.0
     */
    refresh: function() {
        var me = this,
            items = me.all,
            prevItemCount = items.getCount(),
            refreshCounter = me.refreshCounter,
            targetEl,
            dom,
            records,
            selModel = me.getSelectionModel(),
            navModel = me.getNavigationModel(),
            // If there are items in the view, then honour preserveScrollOnRefresh
            scroller = refreshCounter && items.getCount() && me.preserveScrollOnRefresh && me.getScrollable(),
            scrollPos;

        if (!me.rendered || me.destroyed || me.preventRefresh) {
            return;
        }

        if (!me.hasListeners.beforerefresh || me.fireEvent('beforerefresh', me) !== false) {

            // So that listeners to itemremove events know that its because of a refresh
            me.refreshing = true;

            // Allow the NavigationModel to cache the focus position.
            navModel.beforeViewRefresh(me);

            targetEl = me.getTargetEl();
            records = me.getViewRange();
            dom = targetEl.dom;

            if (scroller) {
                scrollPos = scroller.getPosition();
            }

            if (refreshCounter) {
                me.clearViewEl();
                me.refreshCounter++;
            } else {
                me.refreshCounter = 1;
            }

            // Usually, for an empty record set, this would be blank, but when the Template
            // Creates markup outside of the record loop, this must still be honoured even if there are no
            // records.
            me.tpl.append(targetEl, me.collectData(records, items.startIndex || 0));

            // The emptyText is now appended to the View's element
            // after nodes outside the tpl block.
            if (records.length < 1) {
                // Process empty text unless the store is being cleared.
                me.addEmptyText();
                items.clear();
            } else {
                me.collectNodes(targetEl.dom);
                me.updateIndexes(0);
            }

            // Allow the NavigationModel to restore lost focus into the view
            navModel.onViewRefresh();

            // Some subclasses do not need to do this. TableView does not need to do this - it renders selected class using its tenmplate.
            if (me.refreshSelmodelOnRefresh !== false) {
                selModel.refresh();
            }

            me.refreshNeeded = false;

            // Ensure layout system knows about new content size.
            // If number of items have changed, force a layout.
            me.refreshSize(items.getCount() !== prevItemCount);

            me.fireEvent('refresh', me, records);

            if (scroller) {
                scroller.scrollTo(scrollPos);
            }

            // Upon first refresh, fire the viewready event.
            // Reconfiguring the grid "renews" this event.
            if (!me.viewReady) {
                // Fire an event when deferred content becomes available.
                me.viewReady = true;
                me.fireEvent('viewready', me);
            }

            me.refreshing = false;
            me.refreshScroll();

            me.cleanupData();
        }
    },

    addEmptyText: function() {
        var me = this,
            store = me.getStore();

        if (me.emptyText && !store.isLoading() && (!me.deferEmptyText || me.refreshCounter > 1 || store.isLoaded())) {
            me.emptyEl = Ext.core.DomHelper.insertHtml('beforeEnd', me.getTargetEl().dom, me.emptyText);
        }
    },

    getViewRange: function() {
        return this.dataSource.getRange();
    },

    /**
     * @private
     * Called by the framework when the view is refreshed, or when rows are added or deleted.
     *
     * These operations may cause the view's dimensions to change, and if the owning container
     * is shrinkwrapping this view, then the layout must be updated to accommodate these new dimensions.
     */
    refreshSize: function(forceLayout) {
        var me = this,
            sizeModel = me.getSizeModel(),
            scroller = me.getScrollable();

        if (sizeModel.height.shrinkWrap || sizeModel.width.shrinkWrap || forceLayout) {
            me.updateLayout();
        }

        // We need to refresh the Scroller (BufferedRenderer has to do this if present).
        // But the first refresh takes place on the leading edge of the first layout
        // before the Scroller has been initialized, so do it as soon
        // as we reach boxready.
        else if (me.touchScroll && !me.bufferedRenderer) {
            if (scroller) {
                scroller.refresh();
            } else {
                me.on({
                    boxready: me.refreshScroll,
                    scope: me,
                    single: true
                });
            }
        }
    },

    onResize: function() {
        var me = this,
            scroller = me.getScrollable();

        if (scroller && !me._hasScrollListener) {
            scroller.on({
                scroll: me.onViewScroll,
                scrollend: me.onViewScrollEnd,
                scope: me,
                onFrame: !!Ext.global.requestAnimationFrame
            });
            me._hasScrollListener = true;
        }
        this.callParent(arguments);
    },

    clearViewEl: function() {
        var me = this,
            targetEl = me.getTargetEl(),
            nodeContainerIsTarget = me.getNodeContainer() === targetEl;

        me.clearEmptyEl();
        // If nodeContainer is the el, just clear the innerHTML. Otherwise, we need
        // to manually remove each node we know about.
        me.all.clear(!nodeContainerIsTarget);
        if (nodeContainerIsTarget) {
            targetEl.dom.innerHTML = '';
        }
    },

    clearEmptyEl: function() {
        var emptyEl = this.emptyEl;

        // emptyEl is likely to be a TextNode if emptyText is not HTML code.
        // Use native DOM to remove it.
        if (emptyEl) {
            Ext.removeNode(emptyEl);
        }
        this.emptyEl = null;
    },

    onViewScroll: function(scroller, x, y) {
        this.fireEvent('scroll', this, x, y);
    },

    onViewScrollEnd: function(scroller, x, y) {
        this.fireEvent('scrollend', this, x, y);
    },

    /**
     * Saves the scrollState in a private variable. Must be used in conjunction with restoreScrollState.
     * @private
     */
    saveScrollState: function() {
        var me = this,
            state = me.scrollState;

        if (me.rendered) {
            state.left = me.getScrollX();
            state.top = me.getScrollY();
        }
    },

    /**
     * Restores the scrollState.
     * Must be used in conjunction with saveScrollState
     * @private
     */
    restoreScrollState: function() {
        var me = this,
            state = me.scrollState;

        if (me.rendered) {
            me.setScrollX(state.left);
            me.setScrollY(state.top);
        }
    },

    /**
     * Function which can be overridden to provide custom formatting for each Record that is used by this
     * DataView's {@link #tpl template} to render each node.
     * @param {Object/Object[]} data The raw data object that was used to create the Record.
     * @param {Number} recordIndex the index number of the Record being prepared for rendering.
     * @param {Ext.data.Model} record The Record being prepared for rendering.
     * @return {Array/Object} The formatted data in a format expected by the internal {@link #tpl template}'s overwrite() method.
     * (either an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'}))
     * @since 2.3.0
     */
    prepareData: function(data, index, record) {
        var associatedData, attr, hasCopied;
        if (record) {
            associatedData = record.getAssociatedData();
            for (attr in associatedData) {
                if (associatedData.hasOwnProperty(attr)) {
                    // This would be better done in collectData, however
                    // we only need to copy the data object if we have any associations,
                    // so we optimize it by only copying if we must.
                    // We do this so we don't mutate the underlying record.data
                    if (!hasCopied) {
                        data = Ext.Object.chain(data);
                        hasCopied = true;
                    }
                    data[attr] = associatedData[attr];
                }
            }
        }
        return data;
    },

    /**
     * Function which can be overridden which returns the data object passed to this
     * DataView's {@link #cfg-tpl template} to render the whole DataView.
     *
     * This is usually an Array of data objects, each element of which is processed by an
     * {@link Ext.XTemplate XTemplate} which uses `'<tpl for=".">'` to iterate over its supplied
     * data object as an Array. However, named properties may be placed into the data object to
     * provide non-repeating data such as headings, totals etc.
     *
     * @param {Ext.data.Model[]} records An Array of {@link Ext.data.Model}s to be rendered into the DataView.
     * @param {Number} startIndex the index number of the Record being prepared for rendering.
     * @return {Object[]} An Array of data objects to be processed by a repeating XTemplate. May also
     * contain named properties.
     * @since 2.3.0
     */
    collectData: function(records, startIndex){
        var data = [],
            i = 0,
            len = records.length,
            record;

        for (; i < len; i++) {
            record = records[i];
            data[i] = this.prepareData(record.data, startIndex + i, record);
        }
        return data;
    },

    cleanupData: Ext.emptyFn,

    bufferRender: function(records, index) {
        var me = this,
            div = me.renderBuffer,
            result = document.createDocumentFragment(),
            nodes, len, i;

        me.tpl.overwrite(div, me.collectData(records, index));
        nodes = Ext.fly(div).query(me.getItemSelector());
        for (i = 0, len = nodes.length; i < len; i++) {
            result.appendChild(nodes[i]);
        }
        return {
            fragment: result,
            children: nodes
        };
    },

    // Element which contains rows
    nodeContainerSelector: null,

    getNodeContainer: function() {
        var target = this.getTargetEl(),
            selector = this.nodeContainerSelector;
        return selector ? target.down(selector, true) : target;
    },

    /**
     * Returns a CSS selector which selects the element which contains record nodes.
     */
    getNodeContainerSelector: function() {
        return this.nodeContainerSelector;
    },

    onUpdate: function(store, record, operation, modifiedFieldNames, details) {
        var me = this,
            isFiltered = details && details.filtered;

        // If, due to filtering or buffered rendering, or node collapse, the updated record is not
        // represented in the rendered structure, this is a no-op.
        // The correct, new values will be rendered the next time the record becomes visible and is rendered.
        if (!isFiltered && me.getNode(record)) {

            // If we are throttling UI updates (See the updateDelay global config), ensure there's a change entry
            // queued for the record in the global queue.
            if (me.throttledUpdate) {
                me.statics().queueRecordChange(me, store, record, operation, modifiedFieldNames);
            } else {
                me.handleUpdate.apply(me, arguments);
            }
        }
    },

    handleUpdate: function(store, record){
        var me = this,
            index,
            node,
            selModel = me.getSelectionModel();

        if (me.viewReady) {
            index = me.dataSource.indexOf(record);

            // If the record has been removed from the data source since the changes were made, do nothing
            if (index > -1) {
                // ensure the node actually exists in the DOM
                if (me.getNode(record)) {
                    node = me.bufferRender([record], index).children[0];
                    me.all.replaceElement(index, node, true);
                    me.updateIndexes(index, index);
                    // Maintain selection after update
                    selModel.onUpdate(record);
                    me.refreshSizePending = true;
                    if (selModel.isSelected(record)) {
                        me.onItemSelect(record);
                    }
                    if (me.hasListeners.itemupdate) {
                        me.fireEvent('itemupdate', record, index, node);
                    }
                    return node;
                }
            }
        }
    },

    /*
     * @private.
     * Respond to store replace event which is fired by GroupStore group expand/collapse operations.
     * This saves a layout because a remove and add operation are coalesced in this operation.
     */
    onReplace: function(store, startIndex, oldRecords, newRecords) {
        var me = this,
            all = me.all,
            selModel = me.getSelectionModel(),
            origStart = startIndex,
            result, item, fragment, children, oldItems, endIndex;

        if (me.rendered) {

            // Insert the new items before the remove block
            result = me.bufferRender(newRecords, startIndex, true);
            fragment = result.fragment;
            children = result.children;
            item = all.item(startIndex);
            if (item) {
                all.item(startIndex).insertSibling(fragment, 'before', true);
            } else {
                me.appendNodes(fragment);
            }
            all.insert(startIndex, children);

            startIndex += newRecords.length;
            endIndex = startIndex + oldRecords.length - 1;

            // Remove the items which correspond to old records
            oldItems = all.removeRange(startIndex, endIndex, true);

            // Some subclasses do not need to do this. TableView does not need to do this.
            if (me.refreshSelmodelOnRefresh !== false) {
                selModel.refresh();
            }

            // Update the row indices (TableView) doesn't do this.
            me.updateIndexes(startIndex);

            if (me.hasListeners.itemremove) {
                me.fireEvent('itemremove', oldRecords, origStart, oldItems, me);
            }

            if (me.hasListeners.itemadd) {
                me.fireEvent('itemadd', newRecords, origStart, children);
            }
            me.refreshSize();
        }
    },

    onAdd: function(store, records, index) {
        var me = this,
            nodes,
            selModel = me.getSelectionModel();

        if (me.rendered) {
            // If we are adding into an empty view, we must refresh in order that the *full tpl* is applied
            // which might create boilerplate content *around* the record nodes.
            if (me.all.getCount() === 0) {
                me.refresh();
                nodes = me.all.slice();
            } else {
                nodes = me.doAdd(records, index);
                // Some subclasses do not need to do this. TableView does not need to do this.
                if (me.refreshSelmodelOnRefresh !== false) {
                    selModel.refresh();
                }
                me.updateIndexes(index);

                // Ensure layout system knows about new content size
                me.refreshSizePending = true;
            }

            if (me.hasListeners.itemadd) {
                me.fireEvent('itemadd', records, index, nodes);
            }
        }

    },

    appendNodes: function(nodes) {
        var all = this.all,
            count = all.getCount();

        if (this.nodeContainerSelector) {
            this.getNodeContainer().appendChild(nodes);
        } else {
            // If we don't have a nodeContainerSelector, we may have our
            // itemSelector nodes wrapped in some other container, so we
            // can't just append them to the node container, it may be the wrong element
            all.item(count - 1).insertSibling(nodes, 'after');
        }
    },

    doAdd: function(records, index) {
        var me = this,
            result = me.bufferRender(records, index, true),
            fragment = result.fragment,
            children = result.children,
            all = me.all,
            count = all.getCount(),
            firstRowIndex = all.startIndex || 0,

            lastRowIndex = all.endIndex || count - 1;

        if (count === 0 || index > lastRowIndex) {
            me.appendNodes(fragment);
        } else if (index <= firstRowIndex) {
            all.item(firstRowIndex).insertSibling(fragment, 'before', true);
        } else {
            all.item(index).insertSibling(children, 'before', true);
        }

        all.insert(index, children);
        return children;
    },

    onRemove: function(ds, records, index) {
        var me = this,
            rows = me.all,
            fireItemRemove = me.hasListeners.itemremove,
            currIdx, i, record, nodes, node;

        if (rows.getCount()) {
            if (me.dataSource.getCount() === 0) {
                // Refresh so emptyText can be applied if necessary
                if (fireItemRemove) {
                    me.fireEvent('itemremove', records, index, me.getNodes(index, index + records.length - 1));
                }
                me.refresh();
            } else {
                // Just remove the elements which corresponds to the removed records
                // The tpl's full HTML will still be in place.
                if (fireItemRemove) {
                    nodes = [];
                }
                for (i = records.length - 1; i >= 0; --i) {
                    record = records[i];
                    currIdx = index + i;
                    if (nodes) {
                        node = rows.item(currIdx);
                        nodes[i] = node ? node.dom : undefined;
                    }

                    if (rows.item(currIdx)) {
                        me.doRemove(record, currIdx);
                    }
                }

                if (fireItemRemove) {
                    me.fireEvent('itemremove', records, index, nodes, me);
                }
                me.updateIndexes(index);
            }

            // Ensure layout system knows about new content size
            me.refreshSizePending = true;
        }
    },

    doRemove: function(record, index) {
        this.all.removeElement(index, true);
    },

    /**
     * Refreshes an individual node's data from the store.
     * @param {Ext.data.Model/Number} record The record or index of the record to update.
     * @since 2.3.0
     */
    refreshNode: function(record) {
        if (Ext.isNumber(record)) {
            record = this.store.getAt(record);
        }
        this.onUpdate(this.dataSource, record);
    },

    updateIndexes: function(startIndex, endIndex) {
        var nodes = this.all.elements,
            node,
            records = this.getViewRange(),
            i,
            myId = this.id;

        startIndex = startIndex || 0;
        endIndex = endIndex || ((endIndex === 0) ? 0 : (nodes.length - 1));
        for (i = startIndex; i <= endIndex; i++) {
            node = nodes[i];
            node.setAttribute('data-recordIndex', i);
            node.setAttribute('data-recordId', records[i].internalId);
            node.setAttribute('data-boundView', myId);
        }
    },

    /**
     * Changes the data store bound to this view and refreshes it.
     * @param {Ext.data.Store} store The store to bind to this view
     * @since 3.4.0
     */
    bindStore: function(store, initial, propName) {
        var me = this,
            selModel = me.getSelectionModel(),
            navModel = me.getNavigationModel();

        // We'll refresh the selModel below when we refresh
        selModel.preventRefresh = true;
        selModel.bindStore(store);
        selModel.bindComponent(store ? me : null);
        selModel.preventRefresh = false;

        // Navigation model must bind to new store
        navModel.setStore(store);

        me.mixins.storeholder.bindStore.apply(me, arguments);

        // If we have already achieved our first layout, refresh immediately.
        // If we bind to the Store before the first layout, then beforeLayout will
        // call doFirstRefresh
        if (store && me.componentLayoutCounter && !me.preventRefresh) {
            // If not the initial bind, we enforce noDefer
            me.doFirstRefresh(store, !initial);
        }
    },

    /**
     * @private
     * Perform the first refresh of the View from a newly bound store.
     *
     * This is called when this View has been sized for the first time.
     */
    doFirstRefresh: function(store, noDefer) {
        var me = this;

        // If we are configured to defer, and *NOT* called from the defer call below
        if (me.deferInitialRefresh && !noDefer) {
            Ext.defer(me.doFirstRefresh, 1, me, [store, true]);
        }

        else {
            // 4.1.0: If we have a store, and the Store is *NOT* already loading (a refresh is on the way), then
            // on first layout, refresh regardless of record count.
            // Template may contain boilerplate HTML outside of record iteration loop.
            // Also, emptyText is appended by the refresh method.
            if (store && !store.isLoading()) {
                me.refresh();
            }
        }
    },

    onUnbindStore: function(store, initial, propertyName) {
        if (propertyName === 'store') {
            this.setMaskBind(null);
            this.getSelectionModel().bindStore(null);
        }
    },

    onBindStore: function(store, initial, propName, oldStore) {
        var me = this;

        // A BufferedStore has to know to reload the most recent visible zone if its View is preserveScrollOnReload
        if (me.store.isBufferedStore) {
            me.store.preserveScrollOnReload = me.preserveScrollOnReload;
        }
        if (oldStore && oldStore.isBufferedStore) {
            delete oldStore.preserveScrollOnReload;
        }

        me.setMaskBind(store);
        // After the oldStore (.store) has been unbound/bound,
        // do the same for the old data source (.dataSource).
        if (!initial && propName === 'store') {
            // Block any refresh, since this means we're binding the store, which will kick off
            // a refresh.
            me.preventRefresh = true;
            // Ensure we have the this.store reference set correctly.
            me.store = store;
            me.bindStore(store, false, 'dataSource');
            me.preventRefresh = false;
        }
    },

    setMaskBind: function(store) {
        var mask = this.loadMask;

        if (this.rendered && mask && store && !mask.bindStore) {
            mask = this.createMask();
        }

        if (mask && mask.bindStore) {
            mask.bindStore(store);
        }
    },

    getStoreListeners: function() {
        var me = this;
        return {
            refresh: me.onDataRefresh,
            replace: me.onReplace,
            add: me.onAdd,
            remove: me.onRemove,
            update: me.onUpdate,
            clear: me.onDataRefresh,
            beginupdate: me.onBeginUpdate,
            endupdate: me.onEndUpdate
        };
    },

    onBeginUpdate: function() {
        ++this.updateSuspendCounter;
        Ext.suspendLayouts();
    },

    onEndUpdate: function() {
        var me = this;

        if (me.updateSuspendCounter) {
            --me.updateSuspendCounter;
        }

        Ext.resumeLayouts(true);
        if (me.refreshSizePending) {
            me.refreshSize(true);
            me.refreshSizePending = false;
        }
    },

    /**
     * @private
     * Calls this.refresh if this.blockRefresh is not true
     * @since 3.4.0
     */
    onDataRefresh: function(store) {
        var me = this,
            preserveScrollOnRefresh = me.preserveScrollOnRefresh;

        // If this refresh event is fire from a store load, then use the
        // preserveScrollOnReLoad setting to decide whether to preserve scroll position
        if (store.loadCount > me.lastRefreshLoadCount) {
            me.preserveScrollOnRefresh = me.preserveScrollOnReLoad;
        }
        me.refreshView();
        me.preserveScrollOnRefresh = preserveScrollOnRefresh;
        me.lastRefreshLoadCount = store.loadCount;
    },

    refreshView: function() {
        var me = this,
            // If we have an ancestor in a non-boxready state (collapsed or in-transition, or hidden), then block the
            // refresh because the next layout will trigger the refresh
            blocked = me.blockRefresh || !me.rendered || me.up('[collapsed],[isCollapsingOrExpanding],[hidden]');

        // If we are blocked in any way due to either a setting, or hidden or collapsed, or animating ancestor, then
        // the next refresh attempt at the upcoming layout must not defer.
        if (blocked) {
            me.refreshNeeded = true;
        } else {
            if (me.bufferedRenderer) {
                me.bufferedRenderer.refreshView();
            } else {
                me.refresh();
            }
        }
    },

    /**
     * Returns the template node the passed child belongs to, or null if it doesn't belong to one.
     * @param {HTMLElement} node
     * @return {HTMLElement} The template node
     */
    findItemByChild: function(node){
        return Ext.fly(node).findParent(this.getItemSelector(), this.getTargetEl());
    },

    /**
     * Returns the template node by the Ext.event.Event or null if it is not found.
     * @param {Ext.event.Event} e
     */
    findTargetByEvent: function(e) {
        return e.getTarget(this.getItemSelector(), this.getTargetEl());
    },

    /**
     * Gets the currently selected nodes.
     * @return {HTMLElement[]} An array of HTMLElements
     * @since 2.3.0
     */
    getSelectedNodes: function(){
        var nodes   = [],
            records = this.getSelectionModel().getSelection(),
            ln = records.length,
            i  = 0;

        for (; i < ln; i++) {
            nodes.push(this.getNode(records[i]));
        }

        return nodes;
    },

    /**
     * Gets an array of the records from an array of nodes
     * @param {HTMLElement[]} nodes The nodes to evaluate
     * @return {Ext.data.Model[]} records The {@link Ext.data.Model} objects
     * @since 2.3.0
     */
    getRecords: function(nodes) {
        var records = [],
            i = 0,
            len = nodes.length,
            data = this.dataSource.data;

        for (; i < len; i++) {
            records[records.length] = data.getByKey(nodes[i].getAttribute('data-recordId'));
        }

        return records;
    },

    /**
     * Gets a record from a node
     * @param {Ext.dom.Element/HTMLElement} node The node to evaluate
     *
     * @return {Ext.data.Model} record The {@link Ext.data.Model} object
     * @since 2.3.0
     */
    getRecord: function(node){
        return this.dataSource.getByInternalId(Ext.getDom(node).getAttribute('data-recordId'));
    },

    /**
     * Returns true if the passed node is selected, else false.
     * @param {HTMLElement/Number/Ext.data.Model} node The node, node index or record to check
     * @return {Boolean} True if selected, else false
     * @since 2.3.0
     */
    isSelected: function(node) {
        var r = this.getRecord(node);
        return this.getSelectionModel().isSelected(r);
    },

    /**
     * Selects a record instance by record instance or index.
     * @param {Ext.data.Model[]/Number} records An array of records or an index
     * @param {Boolean} keepExisting
     * @param {Boolean} suppressEvent Set to false to not fire a select event
     * @deprecated 4.0 Use {@link Ext.selection.Model#select} instead.
     * @since 2.3.0
     */
    select: function(records, keepExisting, suppressEvent) {
        this.getSelectionModel().select(records, keepExisting, suppressEvent);
    },

    /**
     * Deselects a record instance by record instance or index.
     * @param {Ext.data.Model[]/Number} records An array of records or an index
     * @param {Boolean} suppressEvent Set to false to not fire a deselect event
     * @since 2.3.0
     */
    deselect: function(records, suppressEvent) {
        this.getSelectionModel().deselect(records, suppressEvent);
    },

    /**
     * Gets a template node.
     * @param {HTMLElement/String/Number/Ext.data.Model} nodeInfo An HTMLElement template node, index of a template node,
     * the id of a template node or the record associated with the node.
     * @return {HTMLElement} The node or null if it wasn't found
     * @since 2.3.0
     */
    getNode: function(nodeInfo) {
        var me = this,
            out;

        if (me.rendered && (nodeInfo || nodeInfo === 0)) {
            if (Ext.isString(nodeInfo)) {
                // Id
                out = document.getElementById(nodeInfo);
            } else if (nodeInfo.isModel) {
                // Record
                out = me.getNodeByRecord(nodeInfo);
            } else if (Ext.isNumber(nodeInfo)) {
                // Index
                out = me.all.elements[nodeInfo];
            } else {
                if (nodeInfo.target && nodeInfo.target.nodeType) {
                    // An event. Check that target is a node:  must pass unchanged
                    nodeInfo = nodeInfo.target;
                }
                out = Ext.fly(nodeInfo).findParent(me.itemSelector, me.getTargetEl()); // already an HTMLElement
            }
        }
        return out || null;
    },

    /**
     * @private
     */
    getNodeByRecord: function(record) {
        var index = this.store.indexOf(record);
        return this.all.elements[index] || null;
    },

    /**
     * Gets a range nodes.
     * @param {Number} start (optional) The index of the first node in the range
     * @param {Number} end (optional) The index of the last node in the range
     * @return {HTMLElement[]} An array of nodes
     * @since 2.3.0
     */
    getNodes: function(start, end) {
        var all = this.all;

        if (end !== undefined) {
            end++;
        }
        return all.slice(start, end);
    },

    /**
     * Finds the index of the passed node.
     * @param {HTMLElement/String/Number/Ext.data.Model} nodeInfo An HTMLElement template node, index of a template node, the id of a template node
     * or a record associated with a node.
     * @return {Number} The index of the node or -1
     * @since 2.3.0
     */
    indexOf: function(node) {
        node = this.getNode(node);
        if (!node && node !== 0) {
            return -1;
        }
        if (node.getAttribute('data-recordIndex')) {
            return Number(node.getAttribute('data-recordIndex'));
        }
        return this.all.indexOf(node);
    },

    onDestroy: function() {
        var me = this,
            count = me.updateSuspendCounter;

        me.all.clear();
        me.emptyEl = null;

        me.callParent();
        me.bindStore(null);

        me.store = me.dataSource = me.storeListeners = null;

        if (me.selModelRelayer) {
            me.selModelRelayer.destroy();
            me.selModelRelayer = null;
        }

        Ext.destroy(me.navigationModel, me.selectionModel);
        me.navigationModel = me.selectionModel = me.selModel = null;

        me.loadMask = null;

        // We have been destroyed during a begin/end update, which means we're
        // suspending layouts, must forcibly do it here.
        while (count--) {
            Ext.resumeLayouts(true);
        }
    },

    // invoked by the selection model to maintain visual UI cues
    onItemSelect: function(record) {
        var node = this.getNode(record);

        if (node) {
            Ext.fly(node).addCls(this.selectedItemCls);
        }
    },

    // invoked by the selection model to maintain visual UI cues
    onItemDeselect: function(record) {
        var node = this.getNode(record);

        if (node) {
            Ext.fly(node).removeCls(this.selectedItemCls);
        }
    },

    getItemSelector: function() {
        return this.itemSelector;
    },

    /**
     * Adds a CSS Class to a specific item.
     * @param {HTMLElement/String/Number/Ext.data.Model} itemInfo An HTMLElement, index or instance of a model
     * representing this item
     * @param {String} cls
     */
    addItemCls: function(itemInfo, cls) {
        var item = this.getNode(itemInfo);
        if (item) {
            Ext.fly(item).addCls(cls);
        }
    },

    /**
     * Removes a CSS Class from a specific item.
     * @param {HTMLElement/String/Number/Ext.data.Model} itemInfo An HTMLElement, index or instance of a model
     * representing this item
     * @param {String} cls
     */
    removeItemCls: function(itemInfo, cls) {
        var item = this.getNode(itemInfo);
        if (item) {
            Ext.fly(item).removeCls(cls);
        }
    },

    updateStore: function(store) {
        if (!this.isConfiguring) {
            // bindStore has various checks to see if the current store is the same, so
            // delete the property from our instance, it will be assigned during bindStore
            delete this.store;
            this.bindStore(store);
        }
    },

    privates: {
        toggleChildrenTabbability: function(enableTabbing) {
            var focusEl = this.getTargetEl();

            if (enableTabbing) {
                focusEl.restoreTabbableState(/* skipSelf = */ true);
            }
            else {
                // Do NOT includeSaved
                // Once an item has had tabbability saved, do not increment its save level
                focusEl.saveTabbableState({
                    skipSelf: true,
                    includeSaved: false
                });
            }
        },

        /*
         * @private
         * Called by refresh to collect the view item nodes.
         */
        collectNodes: function(targetEl) {
            var all = this.all,
                options = {
                    role: this.itemAriaRole
                };

            all.fill(Ext.fly(targetEl).query(this.getItemSelector()), all.startIndex || 0);

            // Subclasses may set focusable to false (BoundList is not focusable)
            if (this.focusable) {
                options.tabindex = '-1';
            }

            all.set(options);
        },

        createMask: function(mask) {
            var me = this,
                maskStore = me.getStore(),
                cfg;

            if (maskStore && !maskStore.isEmptyStore && !maskStore.loadsSynchronously()) {
                cfg = {
                    target: me,
                    msg: me.loadingText,
                    useMsg: me.loadingUseMsg,
                    // The store gets bound in initComponent, so while
                    // rendering let's push on the store
                    store: maskStore
                };
                // Do not overwrite default msgCls if we do not have a loadingCls
                if (me.loadingCls) {
                    cfg.msgCls = me.loadingCls;
                }
                // either a config object
                if (Ext.isObject(mask)) {
                    cfg = Ext.apply(cfg, mask);
                }
                // Attach the LoadMask to a *Component* so that it can be sensitive to resizing during long loads.
                // If this DataView is floating, then mask this DataView.
                // Otherwise, mask its owning Container (or this, if there *is* no owning Container).
                // LoadMask captures the element upon render.
                me.loadMask = new Ext.LoadMask(cfg);
                me.loadMask.on({
                    scope: me,
                    beforeshow: me.onMaskBeforeShow,
                    hide: me.onMaskHide
                });
            }
            return me.loadMask;
        },

        getOverflowEl: function() {
            // The desired behavior here is just to inherit from the superclass.  However,
            // the superclass method calls this.getTargetEl, which sends us into an infinte
            // loop because our getTargetEl may call getScrollerEl(), which calls getOverflowEl()
            return Ext.Component.prototype.getTargetEl.call(this);
        },

        getTargetEl: function() {
            return this.touchScroll ? this.getScrollerEl() : this.callParent();
        }
    }
}, function() {
    // all of this information is available directly
    // from the SelectionModel itself, the only added methods
    // to DataView regarding selection will perform some transformation/lookup
    // between HTMLElement/Nodes to records and vice versa.
    Ext.deprecate('extjs', '4.0', function() {
        Ext.view.AbstractView.override({
            /**
             * @cfg {Boolean} [multiSelect=false]
             * True to allow selection of more than one item at a time, false to allow selection of only a single item
             * at a time or no selection at all, depending on the value of {@link #singleSelect}.
             * @deprecated 4.0 Use {@link Ext.selection.Model#mode} 'MULTI' instead.
             * @since 2.3.0
             */
            /**
             * @cfg {Boolean} [singleSelect]
             * Allows selection of exactly one item at a time. As this is the default selection mode anyway, this config
             * is completely ignored.
             * @removed 4.0 Use {@link Ext.selection.Model#mode} 'SINGLE' instead.
             * @since 2.3.0
             */
            /**
             * @cfg {Boolean} [simpleSelect=false]
             * True to enable multiselection by clicking on multiple items without requiring the user to hold Shift or Ctrl,
             * false to force the user to hold Ctrl or Shift to select more than on item.
             * @deprecated 4.0 Use {@link Ext.selection.Model#mode} 'SIMPLE' instead.
             * @since 2.3.0
             */

            /**
             * Gets the number of selected nodes.
             * @return {Number} The node count
             * @deprecated 4.0 Use {@link Ext.selection.Model#getCount} instead.
             * @since 2.3.0
             */
            getSelectionCount: function(){
                if (Ext.global.console) {
                    Ext.global.console.warn("DataView: getSelectionCount will be removed, please interact with the Ext.selection.DataViewModel");
                }
                return this.selModel.getSelection().length;
            },

            /**
             * Gets an array of the selected records
             * @return {Ext.data.Model[]} An array of {@link Ext.data.Model} objects
             * @deprecated 4.0 Use {@link Ext.selection.Model#getSelection} instead.
             * @since 2.3.0
             */
            getSelectedRecords: function(){
                if (Ext.global.console) {
                    Ext.global.console.warn("DataView: getSelectedRecords will be removed, please interact with the Ext.selection.DataViewModel");
                }
                return this.selModel.getSelection();
            },

            // documented above
            // @ignore
            select: function(records, keepExisting, supressEvents) {
                if (Ext.global.console) {
                    Ext.global.console.warn("DataView: select will be removed, please access select through a DataView's SelectionModel, ie: view.getSelectionModel().select()");
                }
                var sm = this.getSelectionModel();
                return sm.select.apply(sm, arguments);
            },

            /**
             * Deselects all selected records.
             * @deprecated 4.0 Use {@link Ext.selection.Model#deselectAll} instead.
             * @since 2.3.0
             */
            clearSelections: function() {
                if (Ext.global.console) {
                    Ext.global.console.warn("DataView: clearSelections will be removed, please access deselectAll through DataView's SelectionModel, ie: view.getSelectionModel().deselectAll()");
                }
                var sm = this.getSelectionModel();
                return sm.deselectAll();
            }
        });
    });
});

redpajama_set_name: RedPajamaGithub


Parts of the Christmas story are really very earthy: the embarrassment of an unmarried pregnant girl, the harsh Roman world that would make that same woman take a long journey to register for a census, and the nativity of hills and caves and Caesar Augustus kings and shepherds that watched their flocks by night.
The Apostle Paul tells us that God created all things visible and invisible. And there are lots of angels. Ten thousand are said to have accompanied God at Mount Sinai. The Bible speaks of "the chariots of God" as "tens of thousands and thousands of thousands." John talks about myriads of myriads and thousands of thousands of angels.
The Bible also gives us some angelic health warnings. We are not to worship or pray to angels. An angel speaking to the Apostle John warned him, "You must not do that! I am a fellow servant with you and your brethren who hold the testimony of Jesus. Worship God." (Revelation 19:10).
Two parallel but unequal kingdoms simultaneously occur: the kingdom of God and the kingdom that is this broken world. One night, in the cold, in the dark, among the wrinkled hills of Bethlehem, these two worlds came together at a dramatic point of intersection. Jesus' birth is really a story of invasion — the kingdom of God breaking into the kingdom of the world.
When the kingdom of God breaks in it is the most wonderful thing. His kingdom of hope breaks into the kingdom of despair. His kingdom of light breaks into the kingdom of darkness. His eternal kingdom breaks into our finite kingdom and the miraculous breaks into the mundane.
I have a good friend in the United Kingdom who is now the dean of my former seminary. As a student, she worked at a summer camp situated on the coastline of North Devon. She vividly recalls a runaway tractor careening across the camp field and headed over the cliffs, with a group of young people on the beach below. She and many others watched a man run across the field and jump into the moving vehicle. With the tractor brakes broken, he managed to pull the tractor around and make a dramatic stop at the very edge of the cliff top. She and the others ran to thank the hero of the hour, only to find no one inside the cab of the tractor.
Another good friend was a missionary in a downtown part of Sydney, Australia. Returning home late one night and all alone, she took a shortcut through a dark underpass. In the middle of the tunnel, she was threatened by a gang who demanded her money or her life. But the gang fled when a large man appeared behind her. Shaken, she turned to thank the stranger but found herself completely alone.
In the Garden of Gethsemane, knowing the cross was before him, Jesus was confronted by "a great crowd with swords and clubs" who had come to seize him on behalf of the chief priests and elders. A disciple drew a sword, but Jesus rebuked him. "Put your sword back into its place … Do you think I cannot call on my father, and he will at once put at my disposal more than twelve legions of angels?" Why didn't Jesus call on the angelic guard? He made this choice because our eternal destiny was at stake. All of us who were "careening toward the cliff," separated from God, were about to be rescued. The company of angels serve God in the continued in-breaking of his kingdom, in the continuing story of our rescue.
There is a world out there that is seen and unseen — visible and invisible — and God sees it all. So if in God's estimation, I am in need of rescue, then I humbly accept his lifeline. If in God's estimation, I need some angelic backup, then bring it on. Personally, I would not be without Jesus and I am grateful to be living in the knowledge of the company of angels.
The Rev. Drew Williams is the senior pastor of Trinity Church.


Donald Trump has vetoed a movement that may have stopped the US offering army assist to Saudi Arabia for his or her ongoing conflict in Yemen.
Congress had handed a never-before-used conflict powers decision in a bid to vary White Home coverage on the battle, which has raged for 4 years.
Many in Washington have been eager for Mr Trump to distance himself from Riyadh since the October killing of journalist Jamal Khashoggi, however the president has been reluctant to sentence the dominion over his dying regardless of it being broadly suspected that Saudi Crown Prince Mohammed bin Salman was complicit.
The US has supplied billions of in weaponry to the Saudi-led coalition preventing towards rebels in Yemen, and the president has mentioned that the help will proceed.
The conflict in Yemen, which is broadly accepted as having begun formally in March 2015, has seen 1000's die and 20 million extra stay on the point of famine.
It's being fought between the Houthi rebels, backed by Iran, and a coalition of Saudi Arabia, the UAE, Egypt, Bahrain, Jordan, Kuwait, Senegal and Sudan, with backing from the US, the UK and France.
Members of congress have expressed concern in regards to the 1000's of civilians killed in coalition air strikes, and accepted the decision earlier this month on a 247-175 vote. The senate vote final month was 54-46.
Democratic consultant Eliot Engel, chairman of the home international affairs committee, mentioned the humanitarian disaster triggered by the battle "calls for ethical management".
However Mr Trump by no means appeared probably to provide it presidential approval, claiming that it could hurt bilateral relations and intervene along with his constitutional energy as commander in chief.
He additionally mentioned the movement was not wanted as a result of the US was not engaged within the battle past counter-terror operations towards Islamic State militants and al-Qaeda within the Arabian Peninsula.
He added that there have been no American troops in Yemen, insisting that the US had solely supplied restricted assist within the type of intelligence sharing, logistics assist, and in-flight refuelling of non-US plane.
The president additionally mentioned assist for the coalition was vital to guard the protection of 80,000 Individuals who stay in sure areas of the coalition nations topic to Houthi assaults.
"Houthis, supported by Iran, have used missiles, armed drones and explosive boats to assault civilian and army targets in these coalition nations, together with areas frequented by Americans, such because the airport in Riyadh, Saudi Arabia," Mr Trump wrote.
It marks the second time Mr Trump has utilised his presidential veto energy.
Final month, he prevented an try by congress to dam him from declaring a nationwide emergency in order that he may use extra money to assemble a wall on the US-Mexico border.
The president made the transfer after the Democrats, who management the home of representatives, refused to conform to launch funding for the wall.
The stand-off resulted in the longest authorities shutdown in US historical past.


Do we have any possiblities to filter out the document types that one can create based on his permissions ?
For example I want to allow Member to create only basic documents in a folder, like Audio, Note or File, where as Administrator should be able to create additional folders and/or document types at the same place.
I know well how to do this in JSF UI, but I have no idea how to do the same for WebUI.
Web UI subtypes filter mechanism is the same than JSF UI except that allowed subtypes are made available client side with the [SubtypesJsonEnricher.java ](https://github.com/nuxeo/nuxeo/blob/master/nuxeo-core/nuxeo-core-io/src/main/java/org/nuxeo/ecm/core/io/marshallers/json/enrichers/SubtypesJsonEnricher.java) Ultimately, you can even override this enricher with your own if you want ad-hoc logic.
Ultimately, you can even override this enricher with your own if you want ad-hoc logic.
I am looking for this solution in JSF UI. How to make the filter.