text:
/*
  Some tools to help developing and debugging Ember/Flame apps. Quick start guide:

   - Hold down ALT and move your mouse around your app. Elements are highlighted to show their extents.
   - While holding ALT, click on an element. This will bind the element to window.e and the associated
     view (if any) to window.v (accessible in JS console as e and v), for your further inspection.
   - While holding ALT, double click on an element. If there's a view associated with that element,
     an inspector panel is opened, showing various information about the view. Click around to explore.
   - While the inspector is open, ALT + single click also opens the view in the inspector panel.
   - You can also launch the inspector on any object in console: FlameInspector.inspect(someObject)
*/
window.FlameInspector = Ember.Object.create({
    _magicKey: 18,  // alt, if changed also has to change the .altKey check below

    _debugPanel: undefined,

    inspect: function(object, openInspector) {
        if (!FlameInspector._debugPanel && openInspector !== false) FlameInspector._debugPanel = FlameInspector.DebugPanel.create();
        if (FlameInspector._debugPanel) {
            FlameInspector._debugPanel.popup();
            FlameInspector._debugPanel.inspect(object);
        }
    },

    logEvent: function(event, eventName, view) {
        if (this._debugPanel) this._debugPanel.get('inspectorController').logEvent(event, eventName, view);
    },

    setup: function() {
        var events = {
            mouseout    : 'mouseOut',
            mouseover   : 'mouseOver',
            mousedown   : 'mouseDown',
            mouseup     : 'mouseUp',
            dblclick    : 'doubleClick'
        }, event;

        for (event in events) {
            if (events.hasOwnProperty(event)) {
                this._setupHandler(event, events[event]);
            }
        }

        this._setupHandler('keydown', 'keyDown', null);
        this._setupHandler('keyup', 'keyUp', null);
    },

    _setupHandler: function(event, handlerName, filter) {
        Ember.$(document).delegate(filter || '.ember-view', event + '.flame-inspector', function(evt, triggeringManager) {
            //console.log('%s, keycode %s', event, evt.keyCode);
            // When releasing alt, on keyup event altKey is no longer set, have to check the keyCode instead
            if (evt.altKey || (event === 'keyup' && evt.keyCode === FlameInspector._magicKey)) {
                if (FlameInspector.eventManager[handlerName]) {
                    FlameInspector.eventManager[handlerName](evt);
                }
            }

            return true;
        });
    },

    eventManager: Ember.Object.create({
        _lastView: undefined,

        keyDown: function(event) {
            // TODO would be nice to set this here, but can't seem to get the element mouse is on - target is body
            //if (event.keyCode === FlameInspector._magicKey) this.set('highlighted', event.target);
        },

        keyUp: function(event) {
            if (event.keyCode === FlameInspector._magicKey) this.set('highlighted', null);
        },

        mouseOver: function(event) {
            this.set('highlighted', event.target);
        },

        mouseOut: function(event) {
            this.set('highlighted', null);
        },

        mouseDown: function(event) {
            var element = Ember.$(event.target);
            var tagName = event.target.nodeName.toUpperCase();
            var id = element.attr('id');
            var viewElement = this._resolveOwnerViewElement(element);
            if (element === viewElement) {
                view = Ember.View.views[id];
                console.log("Clicked on element %s that is Ember view %s --> assigning to variables e and v", tagName, id);
            } else if (viewElement) {
                view = Ember.View.views[viewElement.attr('id')];
                console.log("Clicked on element %s owned by Ember view %s --> assigning to variables e and v", tagName, viewElement.attr('id'));
            } else {
                console.log("Clicked on element which is not owned by any Ember view --> assigning to variable e", tagName);
            }
            window.e = element;
            this._lastView = window.v = view;

            if (view) FlameInspector.inspect(view, false);
        },

        doubleClick: function(event) {
            FlameInspector.inspect(this._lastView);
        },

        _removeHighlight: function() {
            var element = Ember.$(this.get('highlighted'));
            element.css({backgroundColor: element.data('oldBackgroundColor') || '', backgroundImage: element.data('oldBackgroundImage')});
        }.observesBefore('highlighted'),

        _addHighlight: function() {
            var element = Ember.$(this.get('highlighted'));
            if (!element.data('oldBackgroundColor')) element.data('oldBackgroundColor', element.css('backgroundColor'));
            if (!element.data('oldBackgroundImage')) element.data('oldBackgroundImage', element.css('backgroundImage'));
            element.css({backgroundColor: '#ef6', backgroundImage: 'none'});
        }.observes('highlighted'),

        _isViewElement: function(element) {
            var id = Ember.$(element).attr('id');
            return id && id.match(/^ember[0-9]+$/);
        },

        _resolveOwnerViewElement: function(element) {
            while (element && element.length > 0 && !this._isViewElement(element)) {
                element = element.parent();
            }
            return element;
        }
    })

});

FlameInspector.RefView = Flame.LabelView.extend({
    classNames: ['flame-inspector-ref-view'],
    classNameBindings: ['typeClass', 'currentState'],
    defaultWidth: 60,
    defaultHeight: 15,

    action: function() {
        var content = this.get('content');
        if (content) {
            // We want to open it in the current inspector view (can have many inspectors open), thus look up the controller in ancestors
            Flame._lookupValueOfProperty(this, 'inspectorController').inspect(content);
            this.mouseLeave();  // Remove highlight, otherwise might get stuck

            if (content instanceof Ember.View) {
                console.log('Assigning inspected view to variable v');
                window.v = content;
            } else {
                console.log('Assigning inspected object to variable o');
                window.o = content;
            }
        }
    },

    currentState: function() {
        return this.getPath('ownerObject.currentState') === this.get('content');
    }.property('ownerObject.currentState').cacheable(),

    typeClass: function() {
        return 'flame-inspector-ref-view-'+this.get('type');
    }.property('type').cacheable(),

    type: function() {
        var content = this.get('content');
        if (Ember.none(content)) return 'none';
        else if (content instanceof Ember.View) return 'view';
        else if (content instanceof Flame.State) return 'state';
        else return 'object';
    }.property('content').cacheable(),

    value: function() {
        var content = this.get('content');
        var type = this.get('type');
        return type === 'view' ? Ember.guidFor(content) : type;
    }.property('content'),

    mouseEnter: function(event) {
        if (this.get('type') === 'view') FlameInspector.eventManager.set('highlighted', this.get('content').$());
    },

    mouseLeave: function(event) {
        if (this.get('type') === 'view') FlameInspector.eventManager.set('highlighted', undefined);
    }
});

FlameInspector.PropertyInspectorView = Flame.View.extend({
    classNames: ['flame-inspector-inspector-container'],
    childViews: ['list'],
    content: null,

    list: Flame.TreeView.extend({
        //useAbsolutePosition: true,
        layout: { left: 0, right: 0 },
        //layoutManager: Flame.VerticalStackLayoutManager.create({ topMargin: 0, spacing: 0, bottomMargin: 0 }),
        classNames: ['flame-inspector-inspector'],
        allowSelection: false,
        allowReordering: false,
        defaultIsExpanded: true,
        contentBinding: 'parentView.content',

        handlebarsForItem: function(content) {
            if (content instanceof FlameInspector.PropertyGroup) {
                return '
{{content.name}}
';
            } else {
                return '
{{content.key}}
{{#if content.refClass}}{{view content.refClass content=content.value ownerObject=content.ownerObject useAbsolutePosition=false}}{{else}}
{{content.value}}
{{/if}}';
            }
        },

        itemViewClass: Flame.TreeItemView.extend({
            //useAbsolutePosition: true,
            layout: { left: 0, right: 0, height: 20 },
            classNames: ['flame-inspector-item']
        })
    })
});

FlameInspector.EventLogView = Flame.View.extend({
    layoutManager: Flame.VerticalStackLayoutManager.create({spacing: 1}),
    classNames: ['flame-inspector-inspector-container'],
    childViews: ['toolbar', 'list'],
    content: null,

    toolbar: Flame.View.extend({
        layout: { left: 0, right: 0, height: 20 },
        classNames: ['flame-inspector-toolbar'],
        childViews: ['clearButton', 'filterButton'],

        clearButton: Flame.ButtonView.extend({
            layout: { right: 0, width: 50, height: 20 },
            classNames: ['flame-inspector-toolbar-button'],
            title: 'Clear',
            targetBinding: '^inspectorController',
            action: 'clearEventLog'
        }),

        filterButton: Flame.ButtonView.extend({
            layout: { right: 50, width: 70, height: 20 },
            classNames: ['flame-inspector-toolbar-button'],
            title: 'Filter...',
            action: function() {
                var filterItems = Flame._lookupValueOfProperty(this, 'inspectorController').get('filterItems');
                // XXX define subclass elsewhere
                var menu = Flame.Panel.create({
                    layout: { width: 150 },
                    layoutManager: Flame.VerticalStackLayoutManager.create({ topMargin: 0, spacing: 0, bottomMargin: 14 }),
                    classNames: ['flame-inspector-filter-menu', 'flame-inspector-panel'],
                    dimBackground: false,
                    acceptsKeyResponder: false,
                    contentView: Flame.StackView.extend({
                        classNames: ['flame-inspector-filter-list'],
                        content: filterItems,
                        itemViewClass: Flame.StackItemView.extend({
                            classNames: ['flame-inspector-filter-list-item'],
                            layout: { left: 0, right: 0, height: 22 },
                            childViews: ['checkboxView'],
                            checkboxView: Flame.CheckboxView.extend({
                                isSelectedBinding: 'parentView.content.isIncluded',
                                titleBinding: 'parentView.content.type'
                            })
                        })
                    })
                });
                menu.popup(this);
            }
        })
    }),

    list: Flame.ListView.extend({
        layout: { left: 0, right: 0, bottom: 0 },
        classNames: ['flame-inspector-event-log'],
        allowSelection: false,
        allowReordering: false,
        contentBinding: 'parentView.content',

        itemViewClass: Flame.ListItemView.extend({
            classNames: ['flame-inspector-event'],
            render: function(buffer) {
                this._super(buffer);
                var html = '

%@

%@

'.fmt(
                    this.getPath('content.color'),
                    this.getPath('content.eventName'),
                    this.getPath('content.info')
                );
                buffer.push(html);
            }
        }),

        // XXX sometimes causes a weird error when switching inspected view
        /*
        emptyView: Flame.LabelView.create({
            classNames: ['flame-inspector-no-events'],
            layout: { centerX: 0, centerY: 0, width: 120 },
            textAlign: Flame.ALIGN_CENTER,
            value: 'No events logged'
        }),
        */

        childViewsDidChange: function(views, start, removed, added) {
            this._super.apply(this, arguments);

            if (added > 0) {
                // Scroll to the bottom when new events arrive, but let the display get updated first
                var element = this.$();
                Ember.run.next(function() {
                    var scrollHeight = element[0].scrollHeight;
                    element.scrollTo((scrollHeight+100)+'px');
                });
            }
        }
    })
});

FlameInspector.inspectorViewMap = Ember.Object.create({

    view: Flame.View.extend({
        layout: { left: 0, right: 0, bottom: 0 },
        childViews: ['tabView'],
        target: null,

        tabView: Flame.TabView.extend({
            tabsHeight: 20,
            tabs: [
                {title: 'Properties', value: 'properties'},
                {title: 'Event Log', value: 'events'}
            ],
            properties: FlameInspector.PropertyInspectorView.extend({
                contentBinding: 'parentView.parentView.parentView.target.inspectedObjectProperties'
            }),
            events: FlameInspector.EventLogView.extend({
                contentBinding: 'parentView.parentView.parentView.target.inspectedObjectEvents'
            })
        })
    }),

    object: Flame.View.extend({
        layout: { left: 0, right: 0, bottom: 0 },
        childViews: ['properties'],
        target: null,

        properties: FlameInspector.PropertyInspectorView.extend({
            contentBinding: 'parentView.target.inspectedObjectProperties'
        })
    })

});

FlameInspector.getObjectType = function(object) {
    if (Ember.none(object)) return undefined;
    else if (typeof object === 'string') return 'string';
    else if (typeof object === 'number') return 'number';
    else if (object instanceof Ember.View) return 'view';
    else return 'object';
};

FlameInspector.ErrorValue = Ember.Object.extend();

FlameInspector.InspectorController = Ember.Object.extend({
    inspectedObjectEvents: [],
    filterItems: [
        {isIncluded: true, type: 'mouseDown'},
        {isIncluded: true, type: 'mouseMove'},
        {isIncluded: true, type: 'mouseUp'},
        {isIncluded: true, type: 'keyDown'},
        {isIncluded: true, type: 'keyUp'},
        {isIncluded: true, type: 'gotoState'},
        {isIncluded: true, type: 'propertyChange'}
    ],

    _inspectHistory: [],
    _historyIndex: -1,
    _currentObservers: [],

    inspect: function(object) {
        if (object === this.get('inspectedObject')) return;

        this.propertyWillChange('inspectedObject');
        var history = this.get('_inspectHistory');
        var index = this.get('_historyIndex') + 1;
        while (history.get('length') > index) {
            history.removeAt(index);
        }
        this._inspectHistory.push(object);
        this.set('_historyIndex', index);
        this.propertyDidChange('inspectedObject');
    },

    clearEventLog: function() {
        var events = this.get('inspectedObjectEvents');
        events.replace(0, events.get('length'), []);
    },

    logEvent: function(event, eventName, view) {
        if (view !== this.get('inspectedObject')) return;
        var filter = this.get('filterItems').find(function(filterDesc) {
            return filterDesc.type === eventName;
        });
        if (filter && !filter.isIncluded) return;

        var info;
        var color;

        if (eventName.match(/^mouse/)) {
            info = 'pageX %@, pageY %@'.fmt(event.pageX, event.pageY);
            color = {mouseMove: '#473', mouseDown: '#251', mouseUp: '#6a4'}[eventName];
        } else if (eventName.match(/^key/)) {
            info = 'which %@'.fmt(event.which);
            color = {keyDown: '#347', keyUp: '#569'}[eventName];
        } else if (eventName === 'gotoState') {
            info = '%@ → %@'.fmt(event.oldState, event.newState);
            color = '#728';
        } else if (eventName === 'propertyChange') {
            info = '%@: %@ → %@'.fmt(event.property, event.oldValue, event.newValue);
            color = 'darkred';
        } else {
            info = '';  // Unknown event type, shouldn't happen
            color = 'crimson';
        }

        var eventRow = Ember.Object.create({
            eventName: eventName,
            info: info,  //this._eventToString(event, eventName)
            color: color
        });

        var events = this.get('inspectedObjectEvents');
        if (events.get('length') > 200) events.removeAt(0);
        events.pushObject(eventRow);
    },

    _eventToString: function(event, eventName) {
        if (eventName.match(/^mouse/)) {
            return '%@: pageX %@, pageY %@'.fmt(eventName, event.pageX, event.pageY);
        } else if (eventName.match(/^key/)) {
            return '%@: which %@'.fmt(eventName, event.which);
        } else {
            return eventName;
        }
    },

    currentStateWillChange: function() {
        var object = this.get('inspectedObject');
        var oldState = object && object.get && object.get('currentState');
        if (oldState) {
            this._oldState = oldState;  // Sneakily store here, used in currentStateDidChange
        }
    },  //.observesBefore('inspectedObject.currentState'),

    currentStateDidChange: function() {
        var object = this.get('inspectedObject');
        var currentState = object && object.get && object.get('currentState');
        if (currentState) {
            var oldStateName = this._resolveStateName(object, this._oldState);
            var newStateName = this._resolveStateName(object, currentState);
            this.logEvent({oldState: oldStateName, newState: newStateName}, 'gotoState', object);
        }
    },  //.observes('inspectedObject.currentState'),

    _resolveStateName: function(view, state) {
        if (!Ember.none(state)) {
            for (var prop in view) {
                if (prop !== '_super' && view.hasOwnProperty(prop) && view.get(prop) === state) return prop;
            }
        }
        return '(unknown)';
    },

    prev: function() {
        if (this.get('allowPrev')) {
            this.propertyWillChange('inspectedObject');  // XXX ugly
            this.decrementProperty('_historyIndex');
            this.propertyDidChange('inspectedObject');
        }
    },

    allowPrev: function() {
        return this.get('_historyIndex') > 0;
    }.property('_historyIndex'),

    next: function() {
        if (this.get('allowNext')) {
            this.propertyWillChange('inspectedObject');  // XXX ugly
            this.incrementProperty('_historyIndex');
            this.propertyDidChange('inspectedObject');
        }
    },

    allowNext: function() {
        return this.get('_historyIndex') < this.getPath('_inspectHistory.length') - 1;
    }.property('_historyIndex'),

    inspectedObject: function() {
        return this._inspectHistory.objectAt(this.get('_historyIndex'));
    }.property().cacheable(),

    // Remove observers and flush event log when inspected object changes
    inspectedObjectWillChange: function() {
        this.get('_currentObservers').forEach(function(descriptor) {
            if (descriptor.type === 'before') {
                Ember.removeBeforeObserver(descriptor.object, descriptor.prop, descriptor.target, descriptor.observer);
            } else {
                Ember.removeObserver(descriptor.object, descriptor.prop, descriptor.target, descriptor.observer);
            }
        });
        this.set('_currentObservers', []);
        this.set('inspectedObjectEvents', []);
    }.observesBefore('inspectedObject'),

    inspectedObjectDidChange: function() {
        // If we just define observers for currentState with .observes(...), we end up adding 'currentState' property to all objects
        var object = this.get('inspectedObject');
        if (object && object.get && object.get('currentState')) {
            this._addObserverAndRegisterForRemoval(object, 'currentState', this, this.currentStateWillChange, 'before');
            this._addObserverAndRegisterForRemoval(object, 'currentState', this, this.currentStateDidChange);
        }
    }.observes('inspectedObject'),

    inspectedObjectGuid: function() {
        var cur = this.get('inspectedObject');
        return cur ? Ember.guidFor(cur) : '(none)';
    }.property('inspectedObject').cacheable(),

    inspectedObjectType: function() {
        var cur = this.get('inspectedObject');
        return cur ? FlameInspector.getObjectType(cur) : undefined;
    }.property('inspectedObject').cacheable(),

    inspectedObjectProperties: function() {
        var object = this.get('inspectedObject');
        var arr = [];
        if (!object) return arr;

        var childViews = object.get && object.get('childViews');
        var childViewArray = this._generateChildViewArray(object, childViews);
        if (childViewArray) {
            arr.push(FlameInspector.PropertyGroup.create({
                name: 'child views',
                treeItemChildren: childViewArray
            }));
        }

        var stateArray = this._generateStateArray(object);
        if (stateArray) {
            arr.push(FlameInspector.PropertyGroup.create({
                name: 'flame states',
                treeItemChildren: stateArray
            }));
        }

        arr.push(FlameInspector.PropertyGroup.create({
            name: 'public properties',
            treeItemChildren: this._generatePropertyArray(object, /^[^_]+/, ['childViews'], childViews, true)
        }));

        arr.push(FlameInspector.PropertyGroup.create({
            name: 'private properties',
            treeItemChildren: this._generatePropertyArray(object, /^_/)
        }));

        return arr;
    }.property('inspectedObject').cacheable(),

    _generateStateArray: function(object) {
        if (!object.get) return null;  // No getter, no states
        var arr = [];
        for (var prop in object) {
            if (prop !== '_super' && object.hasOwnProperty(prop) && prop !== 'currentState') {  // _super causes trouble
                var value = object.get(prop);
                if (value instanceof Flame.State) {
                    var item = Ember.Object.create({
                        key: prop,
                        value: value,
                        ownerObject: object,
                        refClass: FlameInspector.RefView,
                        cssClass: 'flame-inspector-value state'
                    });

                    arr.push(item);
                }
            }
        }

        return arr.get('length') > 0 ? arr : null;
    },

    _generateChildViewArray: function(object, childViews) {
        var arr = [];
        if (Ember.none(childViews) || childViews.get('length') === 0) return null;

        var self = this;
        return childViews.map(function(childView) {
            return Ember.Object.create({
                key: self._resolveChildViewName(object, childView),
                value: childView,
                refClass: FlameInspector.RefView,
                cssClass: 'flame-inspector-value view'
            });
        });
    },

    _resolveChildViewName: function(view, childView) {
        for (var prop in view) {
            if (prop !== '_super' && view.hasOwnProperty(prop) && view.get(prop) === childView) return prop;
        }
        return '(anonymous)';
    },

    _generatePropertyArray: function(object, filter, excludeKeys, excludeValues, bind) {
        var arr = [];

        for (var prop in object) {
            if (prop !== '_super' &&
              (object.hasOwnProperty(prop) || object.constructor.prototype.hasOwnProperty(prop)) &&
              (!filter || prop.match(filter)) && (!excludeKeys || !excludeKeys.contains(prop))) {
                var value;
                try {
                    value = object.get ? object.get(prop) : object[prop];  // XXX was there some handy util method for this?
                } catch (e) {
                    value = FlameInspector.ErrorValue.create({msg: e.toString()});
                }
                if (excludeValues && excludeValues.contains(value)) continue;
                if (value instanceof Flame.State) continue;  // States handled as a separate group

                var item = Ember.Object.create({key: prop});
                this._updatePropertyItem(item, value);

                if (bind && !(value instanceof FlameInspector.ErrorValue)) {
                    var observer = this._constructObserver(object, item, prop);  // Easier to use a helper method to close over the relevant variables
                    this._addObserverAndRegisterForRemoval(object, prop, null, observer);
                }

                arr.push(item);
            }
        }

        arr.sort(function(o1, o2) { return Ember.compare(o1.key, o2.key); });
        return arr;
    },

    _addObserverAndRegisterForRemoval: function(object, prop, target, observer, type) {
        if (type === 'before') {
            Ember.addBeforeObserver(object, prop, target, observer);
        } else {
            Ember.addObserver(object, prop, target, observer);
        }
        this.get('_currentObservers').push({object: object, prop: prop, target: target, observer: observer, type: type});
    },

    _updatePropertyItem: function(item, value) {
        var refValue = value;
        var cssClass = value === null ? 'null' : typeof value;
        var refClass = null;  // This initialization is seems to be needed, otherwise the handlebars 'if' always evaluates to true
        if (value === undefined) refValue = 'undefined';
        else if (value === null) refValue = 'null';
        else if (value === true || value === false || typeof value === 'number') refValue = value.toString();
        else if (typeof value === 'function') refValue = '(function)';
        else if (typeof value === 'string') refValue = '"'+value+'"';
        else if (value instanceof FlameInspector.ErrorValue) {
            refValue = '(%@)'.fmt(value.msg);
            cssClass = 'error';
        } else if (value instanceof Ember.View) {
            refClass = FlameInspector.RefView;
        } else if (value instanceof Array) {
            cssClass = 'array';
            refValue = '['+value.join(', ')+']';
        } else {
            refClass = FlameInspector.RefView;
        }

        item.set('refClass', refClass);
        item.set('value', refValue);
        // String-safe value to be shown as tooltip (refValue may change type while we're still using the literal presentation)
        item.set('stringValue', refValue.toString());
        item.set('cssClass', 'flame-inspector-value '+cssClass);
    },

    _constructObserver: function(object, item, prop) {
        var self = this;
        return function() {
            //console.log('Property changed: %s = %s', prop, object.get(prop));
            //item.set('value', object.get(prop));
            var oldStringValue = item.get('value');
            var newValue = object.get ? object.get(prop) : object[prop];
            self._updatePropertyItem(item, newValue);
            self.logEvent({property: prop, oldValue: oldStringValue, newValue: item.get('value')}, 'propertyChange', object);
        };
    }

});

FlameInspector.PropertyGroup = Ember.Object.extend({
    name: null,
    treeItemChildren: null
});

FlameInspector.DebugPanel = Flame.Panel.extend({
    //layoutManager: Flame.VerticalStackLayoutManager.create({ topMargin: 10, spacing: 10, bottomMargin: 4 }),
    layout: { right: 30, width: 300, top: 30, height: 600 },
    classNames: ['flame-inspector-panel'],
    isModal: false,
    destroyOnClose: false,
    title: 'Flame Inspector',

    inspectorController: FlameInspector.InspectorController.create(),
    currentInspectorView: null,

    inspectedObjectWillChange: function() {
        this.getPath('contentView.inspector').removeFromParent();
        if (this.get('currentInspectorView')) {
            this.get('currentInspectorView').destroy();
            this.set('currentInspectorView', null);
        }
    }.observesBefore('inspectorController.inspectedObject'),

    inspectedObjectDidChange: function() {
        var contentView = this.get('contentView');
        var type = this.getPath('inspectorController.inspectedObjectType');
        var newInspectorViewClass = FlameInspector.inspectorViewMap[type];
        if (!newInspectorViewClass) newInspectorViewClass = FlameInspector.inspectorViewMap.object;  // Default to object inspector
        var newInspectorView = contentView.createChildView(newInspectorViewClass.extend({targetBinding: 'parentView.parentView.inspectorController'}));

        contentView.get('childViews').addObject(newInspectorView);
        contentView.adjustLayout('height', '');  // Annoyingly, the layout manager sets a fixed height for us when the previous inspector is removed
        this.set('currentInspectorView', newInspectorView);
    }.observes('inspectorController.inspectedObject'),

    currentKeyResponder: function() {
        return Flame.keyResponderStack.current() || null;
    }.property('Flame.keyResponderStack.currentKeyResponder'),

    currentMouseResponder: function() {
        return Flame.get('mouseResponderView') || null;
    }.property('Flame.mouseResponderView'),

    keyResponderStack: function() {
        return Ember.copy(Flame.keyResponderStack._stack).reverse();
    }.property('Flame.keyResponderStack.currentKeyResponder').cacheable(),

    inspect: function(view) {
        this.inspectorController.inspect(view);
    },

    contentView: Flame.View.extend({
        layoutManager: Flame.VerticalStackLayoutManager.create({ topMargin: 5, spacing: 10, bottomMargin: 5 }),
        layout: { left: 6, right: 6, top: 30, bottom: 6 },
        childViews: 'curMouse curKey inspectorHeader inspector'.w(),

        curMouse: Flame.View.extend({
            layout: { left: 4, right: 4, height: 22 },
            childViews: 'curMouseLabel curMouseView'.w(),
            curMouseLabel: Flame.LabelView.label('Current mouse responder:', 0, 3, 180),
            curMouseView: FlameInspector.RefView.extend({
                layout: { right: 0, top: 0, width: 60, height: 15 },
                contentBinding: '^currentMouseResponder'
            })
        }),

        curKey: Flame.View.extend({
            layoutManager: Flame.VerticalStackLayoutManager.create(),
            layout: { left: 4, right: 4, height: 22 },
            childViews: 'curKeyLabel stackView'.w(),
            curKeyLabel: Flame.LabelView.extend({
                layout: { left: 0, top: 3, width: 180 },
                ignoreLayoutManager: true,
                value: 'Key responder stack:'
            }),
            stackView: Flame.StackView.extend({
                layout: { right: 0, width: 66, top: 0 },
                contentBinding: '^keyResponderStack',
                itemViewClass: Flame.StackItemView.extend({
                    layout: { left: 0, right: 0, height: 22 },
                    childViews: ['ref'],
                    ref: FlameInspector.RefView.extend({
                        layout: { left: 0, right: 0, height: 15 },
                        contentBinding: 'parentView.content'
                    })
                })
            })
        }),

        inspectorHeader: Flame.View.extend({
            layout: { left: 4, right: 4, height: 22 },
            childViews: 'labelView prevView nextView curView'.w(),

            labelView: Flame.LabelView.label('Inspector', 0, 3, 180),
            prevView: Flame.ButtonView.extend({
                layout: { right: 95, top: 0, width: 19, height: 19 },
                classNames: ['flame-inspector-hist', 'flame-inspector-prev'],
                handlebars: '◀',
                isDisabled: Flame.computed.not('target.allowPrev'),
                targetBinding: '^inspectorController',
                action: 'prev'
            }),
            nextView: Flame.ButtonView.extend({
                layout: { right: 72, top: 0, width: 19, height: 19 },
                classNames: ['flame-inspector-hist', 'flame-inspector-next'],
                handlebars: '▶',
                isDisabled: Flame.computed.not('target.allowNext'),
                targetBinding: '^inspectorController',
                action: 'next'
            }),
            curView: FlameInspector.RefView.extend({
                layout: { right: 0, top: 0, width: 60, height: 15 },
                contentBinding: '^inspectorController.inspectedObject'
            })
        }),

        inspector: Flame.View.extend({
            layout: { left: 0, right: 0, bottom: 0 }
        })
    })

});

FlameInspector.setup();


text:
<?php

namespace appitnetwork\wpthemes\helpers;

use Yii;
use yii\base\Component;
/**
 * Meta API: WP_Meta_Query class
 *
 * @package WordPress
 * @subpackage Meta
 * @since 4.4.0
 */

/**
 * Core class used to implement meta queries for the Meta API.
 *
 * Used for generating SQL clauses that filter a primary query according to metadata keys and values.
 *
 * `WP_Meta_Query` is a helper that allows primary query classes, such as {@see WP_Query} and {@see WP_User_Query},
 * to filter their results by object metadata, by generating `JOIN` and `WHERE` subclauses to be attached
 * to the primary SQL query string.
 *
 * @since 3.2.0
 * @package WordPress
 * @subpackage Meta
 */
class WP_Meta_Query extends Component
{
	/**
	 * Array of metadata queries.
	 *
	 * See {@see WP_Meta_Query::__construct()} for information on meta query arguments.
	 *
	 * @since 3.2.0
	 * @access public
	 * @var array
	 */
	public $queries = array();

	/**
	 * The relation between the queries. Can be one of 'AND' or 'OR'.
	 *
	 * @since 3.2.0
	 * @access public
	 * @var string
	 */
	public $relation;

	/**
	 * Database table to query for the metadata.
	 *
	 * @since 4.1.0
	 * @access public
	 * @var string
	 */
	public $meta_table;

	/**
	 * Column in meta_table that represents the ID of the object the metadata belongs to.
	 *
	 * @since 4.1.0
	 * @access public
	 * @var string
	 */
	public $meta_id_column;

	/**
	 * Database table that where the metadata's objects are stored (eg $wpdb->users).
	 *
	 * @since 4.1.0
	 * @access public
	 * @var string
	 */
	public $primary_table;

	/**
	 * Column in primary_table that represents the ID of the object.
	 *
	 * @since 4.1.0
	 * @access public
	 * @var string
	 */
	public $primary_id_column;

	/**
	 * A flat list of table aliases used in JOIN clauses.
	 *
	 * @since 4.1.0
	 * @access protected
	 * @var array
	 */
	protected $table_aliases = array();

	/**
	 * A flat list of clauses, keyed by clause 'name'.
	 *
	 * @since 4.2.0
	 * @access protected
	 * @var array
	 */
	protected $clauses = array();

	/**
	 * Whether the query contains any OR relations.
	 *
	 * @since 4.3.0
	 * @access protected
	 * @var bool
	 */
	protected $has_or_relation = false;

	/**
	 * Constructor.
	 *
	 * @since 3.2.0
	 * @since 4.2.0 Introduced support for naming query clauses by associative array keys.
	 *
	 * @access public
	 *
	 * @param array $meta_query {
	 *     Array of meta query clauses. When first-order clauses use strings as their array keys, they may be
	 *     referenced in the 'orderby' parameter of the parent query.
	 *
	 *     @type string $relation Optional. The MySQL keyword used to join
	 *                            the clauses of the query. Accepts 'AND', or 'OR'. Default 'AND'.
	 *     @type array {
	 *         Optional. An array of first-order clause parameters, or another fully-formed meta query.
	 *
	 *         @type string $key     Meta key to filter by.
	 *         @type string $value   Meta value to filter by.
	 *         @type string $compare MySQL operator used for comparing the $value. Accepts '=',
	 *                               '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN',
	 *                               'BETWEEN', 'NOT BETWEEN', 'REGEXP', 'NOT REGEXP', or 'RLIKE'.
	 *                               Default is 'IN' when `$value` is an array, '=' otherwise.
	 *         @type string $type    MySQL data type that the meta_value column will be CAST to for
	 *                               comparisons. Accepts 'NUMERIC', 'BINARY', 'CHAR', 'DATE',
	 *                               'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', or 'UNSIGNED'.
	 *                               Default is 'CHAR'.
	 *     }
	 * }
	 */
	public function __construct( $meta_query = false ) {
		if ( !$meta_query )
			return;

		if ( isset( $meta_query['relation'] ) && strtoupper( $meta_query['relation'] ) == 'OR' ) {
			$this->relation = 'OR';
		} else {
			$this->relation = 'AND';
		}

		$this->queries = $this->sanitize_query( $meta_query );
	}

	/**
	 * Ensure the 'meta_query' argument passed to the class constructor is well-formed.
	 *
	 * Eliminates empty items and ensures that a 'relation' is set.
	 *
	 * @since 4.1.0
	 * @access public
	 *
	 * @param array $queries Array of query clauses.
	 * @return array Sanitized array of query clauses.
	 */
	public function sanitize_query( $queries ) {
		$clean_queries = array();

		if ( ! is_array( $queries ) ) {
			return $clean_queries;
		}

		foreach ( $queries as $key => $query ) {
			if ( 'relation' === $key ) {
				$relation = $query;

			} elseif ( ! is_array( $query ) ) {
				continue;

			// First-order clause.
			} elseif ( $this->is_first_order_clause( $query ) ) {
				if ( isset( $query['value'] ) && array() === $query['value'] ) {
					unset( $query['value'] );
				}

				$clean_queries[ $key ] = $query;

			// Otherwise, it's a nested query, so we recurse.
			} else {
				$cleaned_query = $this->sanitize_query( $query );

				if ( ! empty( $cleaned_query ) ) {
					$clean_queries[ $key ] = $cleaned_query;
				}
			}
		}

		if ( empty( $clean_queries ) ) {
			return $clean_queries;
		}

		// Sanitize the 'relation' key provided in the query.
		if ( isset( $relation ) && 'OR' === strtoupper( $relation ) ) {
			$clean_queries['relation'] = 'OR';
			$this->has_or_relation = true;

		/*
		 * If there is only a single clause, call the relation 'OR'.
		 * This value will not actually be used to join clauses, but it
		 * simplifies the logic around combining key-only queries.
		 */
		} elseif ( 1 === count( $clean_queries ) ) {
			$clean_queries['relation'] = 'OR';

		// Default to AND.
		} else {
			$clean_queries['relation'] = 'AND';
		}

		return $clean_queries;
	}

	/**
	 * Determine whether a query clause is first-order.
	 *
	 * A first-order meta query clause is one that has either a 'key' or
	 * a 'value' array key.
	 *
	 * @since 4.1.0
	 * @access protected
	 *
	 * @param array $query Meta query arguments.
	 * @return bool Whether the query clause is a first-order clause.
	 */
	protected function is_first_order_clause( $query ) {
		return isset( $query['key'] ) || isset( $query['value'] );
	}

	/**
	 * Constructs a meta query based on 'meta_*' query vars
	 *
	 * @since 3.2.0
	 * @access public
	 *
	 * @param array $qv The query variables
	 */
	public function parse_query_vars( $qv ) {
		$meta_query = array();

		/*
		 * For orderby=meta_value to work correctly, simple query needs to be
		 * first (so that its table join is against an unaliased meta table) and
		 * needs to be its own clause (so it doesn't interfere with the logic of
		 * the rest of the meta_query).
		 */
		$primary_meta_query = array();
		foreach ( array( 'key', 'compare', 'type' ) as $key ) {
			if ( ! empty( $qv[ "meta_$key" ] ) ) {
				$primary_meta_query[ $key ] = $qv[ "meta_$key" ];
			}
		}

		// WP_Query sets 'meta_value' = '' by default.
		if ( isset( $qv['meta_value'] ) && '' !== $qv['meta_value'] && ( ! is_array( $qv['meta_value'] ) || $qv['meta_value'] ) ) {
			$primary_meta_query['value'] = $qv['meta_value'];
		}

		$existing_meta_query = isset( $qv['meta_query'] ) && is_array( $qv['meta_query'] ) ? $qv['meta_query'] : array();

		if ( ! empty( $primary_meta_query ) && ! empty( $existing_meta_query ) ) {
			$meta_query = array(
				'relation' => 'AND',
				$primary_meta_query,
				$existing_meta_query,
			);
		} elseif ( ! empty( $primary_meta_query ) ) {
			$meta_query = array(
				$primary_meta_query,
			);
		} elseif ( ! empty( $existing_meta_query ) ) {
			$meta_query = $existing_meta_query;
		}

		$this->__construct( $meta_query );
	}

	/**
	 * Return the appropriate alias for the given meta type if applicable.
	 *
	 * @since 3.7.0
	 * @access public
	 *
	 * @param string $type MySQL type to cast meta_value.
	 * @return string MySQL type.
	 */
	public function get_cast_for_type( $type = '' ) {
		if ( empty( $type ) )
			return 'CHAR';

		$meta_type = strtoupper( $type );

		if ( ! preg_match( '/^(?:BINARY|CHAR|DATE|DATETIME|SIGNED|UNSIGNED|TIME|NUMERIC(?:\(\d+(?:,\s?\d+)?\))?|DECIMAL(?:\(\d+(?:,\s?\d+)?\))?)$/', $meta_type ) )
			return 'CHAR';

		if ( 'NUMERIC' == $meta_type )
			$meta_type = 'SIGNED';

		return $meta_type;
	}

	/**
	 * Generates SQL clauses to be appended to a main query.
	 *
	 * @since 3.2.0
	 * @access public
	 *
	 * @param string $type              Type of meta, eg 'user', 'post'.
	 * @param string $primary_table     Database table where the object being filtered is stored (eg wp_users).
	 * @param string $primary_id_column ID column for the filtered object in $primary_table.
	 * @param object $context           Optional. The main query object.
	 * @return false|array {
	 *     Array containing JOIN and WHERE SQL clauses to append to the main query.
	 *
	 *     @type string $join  SQL fragment to append to the main JOIN clause.
	 *     @type string $where SQL fragment to append to the main WHERE clause.
	 * }
	 */
	public function get_sql( $type, $primary_table, $primary_id_column, $context = null ) {
		if ( ! $meta_table = _get_meta_table( $type ) ) {
			return false;
		}

		$this->meta_table     = $meta_table;
		$this->meta_id_column = sanitize_key( $type . '_id' );

		$this->primary_table     = $primary_table;
		$this->primary_id_column = $primary_id_column;

		$sql = $this->get_sql_clauses();

		/*
		 * If any JOINs are LEFT JOINs (as in the case of NOT EXISTS), then all JOINs should
		 * be LEFT. Otherwise posts with no metadata will be excluded from results.
		 */
		if ( false !== strpos( $sql['join'], 'LEFT JOIN' ) ) {
			$sql['join'] = str_replace( 'INNER JOIN', 'LEFT JOIN', $sql['join'] );
		}

		/**
		 * Filter the meta query's generated SQL.
		 *
		 * @since 3.1.0
		 *
		 * @param array $args {
		 *     An array of meta query SQL arguments.
		 *
		 *     @type array  $clauses           Array containing the query's JOIN and WHERE clauses.
		 *     @type array  $queries           Array of meta queries.
		 *     @type string $type              Type of meta.
		 *     @type string $primary_table     Primary table.
		 *     @type string $primary_id_column Primary column ID.
		 *     @type object $context           The main query object.
		 * }
		 */
		return apply_filters_ref_array( 'get_meta_sql', array( $sql, $this->queries, $type, $primary_table, $primary_id_column, $context ) );
	}

	/**
	 * Generate SQL clauses to be appended to a main query.
	 *
	 * Called by the public {@see WP_Meta_Query::get_sql()}, this method
	 * is abstracted out to maintain parity with the other Query classes.
	 *
	 * @since 4.1.0
	 * @access protected
	 *
	 * @return array {
	 *     Array containing JOIN and WHERE SQL clauses to append to the main query.
	 *
	 *     @type string $join  SQL fragment to append to the main JOIN clause.
	 *     @type string $where SQL fragment to append to the main WHERE clause.
	 * }
	 */
	protected function get_sql_clauses() {
		/*
		 * $queries are passed by reference to get_sql_for_query() for recursion.
		 * To keep $this->queries unaltered, pass a copy.
		 */
		$queries = $this->queries;
		$sql = $this->get_sql_for_query( $queries );

		if ( ! empty( $sql['where'] ) ) {
			$sql['where'] = ' AND ' . $sql['where'];
		}

		return $sql;
	}

	/**
	 * Generate SQL clauses for a single query array.
	 *
	 * If nested subqueries are found, this method recurses the tree to
	 * produce the properly nested SQL.
	 *
	 * @since 4.1.0
	 * @access protected
	 *
	 * @param array $query Query to parse, passed by reference.
	 * @param int   $depth Optional. Number of tree levels deep we currently are.
	 *                     Used to calculate indentation. Default 0.
	 * @return array {
	 *     Array containing JOIN and WHERE SQL clauses to append to a single query array.
	 *
	 *     @type string $join  SQL fragment to append to the main JOIN clause.
	 *     @type string $where SQL fragment to append to the main WHERE clause.
	 * }
	 */
	protected function get_sql_for_query( &$query, $depth = 0 ) {
		$sql_chunks = array(
			'join'  => array(),
			'where' => array(),
		);

		$sql = array(
			'join'  => '',
			'where' => '',
		);

		$indent = '';
		for ( $i = 0; $i < $depth; $i++ ) {
			$indent .= "  ";
		}

		foreach ( $query as $key => &$clause ) {
			if ( 'relation' === $key ) {
				$relation = $query['relation'];
			} elseif ( is_array( $clause ) ) {

				// This is a first-order clause.
				if ( $this->is_first_order_clause( $clause ) ) {
					$clause_sql = $this->get_sql_for_clause( $clause, $query, $key );

					$where_count = count( $clause_sql['where'] );
					if ( ! $where_count ) {
						$sql_chunks['where'][] = '';
					} elseif ( 1 === $where_count ) {
						$sql_chunks['where'][] = $clause_sql['where'][0];
					} else {
						$sql_chunks['where'][] = '( ' . implode( ' AND ', $clause_sql['where'] ) . ' )';
					}

					$sql_chunks['join'] = array_merge( $sql_chunks['join'], $clause_sql['join'] );
				// This is a subquery, so we recurse.
				} else {
					$clause_sql = $this->get_sql_for_query( $clause, $depth + 1 );

					$sql_chunks['where'][] = $clause_sql['where'];
					$sql_chunks['join'][]  = $clause_sql['join'];
				}
			}
		}

		// Filter to remove empties.
		$sql_chunks['join']  = array_filter( $sql_chunks['join'] );
		$sql_chunks['where'] = array_filter( $sql_chunks['where'] );

		if ( empty( $relation ) ) {
			$relation = 'AND';
		}

		// Filter duplicate JOIN clauses and combine into a single string.
		if ( ! empty( $sql_chunks['join'] ) ) {
			$sql['join'] = implode( ' ', array_unique( $sql_chunks['join'] ) );
		}

		// Generate a single WHERE clause with proper brackets and indentation.
		if ( ! empty( $sql_chunks['where'] ) ) {
			$sql['where'] = '( ' . "\n  " . $indent . implode( ' ' . "\n  " . $indent . $relation . ' ' . "\n  " . $indent, $sql_chunks['where'] ) . "\n" . $indent . ')';
		}

		return $sql;
	}

	/**
	 * Generate SQL JOIN and WHERE clauses for a first-order query clause.
	 *
	 * "First-order" means that it's an array with a 'key' or 'value'.
	 *
	 * @since 4.1.0
	 * @access public
	 *
	 * @global wpdb $wpdb WordPress database abstraction object.
	 *
	 * @param array  $clause       Query clause, passed by reference.
	 * @param array  $parent_query Parent query array.
	 * @param string $clause_key   Optional. The array key used to name the clause in the original `$meta_query`
	 *                             parameters. If not provided, a key will be generated automatically.
	 * @return array {
	 *     Array containing JOIN and WHERE SQL clauses to append to a first-order query.
	 *
	 *     @type string $join  SQL fragment to append to the main JOIN clause.
	 *     @type string $where SQL fragment to append to the main WHERE clause.
	 * }
	 */
	public function get_sql_for_clause( &$clause, $parent_query, $clause_key = '' ) {
		global $wpdb;

		$sql_chunks = array(
			'where' => array(),
			'join' => array(),
		);

		if ( isset( $clause['compare'] ) ) {
			$clause['compare'] = strtoupper( $clause['compare'] );
		} else {
			$clause['compare'] = isset( $clause['value'] ) && is_array( $clause['value'] ) ? 'IN' : '=';
		}

		if ( ! in_array( $clause['compare'], array(
			'=', '!=', '>', '>=', '<', '<=',
			'LIKE', 'NOT LIKE',
			'IN', 'NOT IN',
			'BETWEEN', 'NOT BETWEEN',
			'EXISTS', 'NOT EXISTS',
			'REGEXP', 'NOT REGEXP', 'RLIKE'
		) ) ) {
			$clause['compare'] = '=';
		}

		$meta_compare = $clause['compare'];

		// First build the JOIN clause, if one is required.
		$join = '';

		// We prefer to avoid joins if possible. Look for an existing join compatible with this clause.
		$alias = $this->find_compatible_table_alias( $clause, $parent_query );
		if ( false === $alias ) {
			$i = count( $this->table_aliases );
			$alias = $i ? 'mt' . $i : $this->meta_table;

			// JOIN clauses for NOT EXISTS have their own syntax.
			if ( 'NOT EXISTS' === $meta_compare ) {
				$join .= " LEFT JOIN $this->meta_table";
				$join .= $i ? " AS $alias" : '';
				$join .= $wpdb->prepare( " ON ($this->primary_table.$this->primary_id_column = $alias.$this->meta_id_column AND $alias.meta_key = %s )", $clause['key'] );

			// All other JOIN clauses.
			} else {
				$join .= " INNER JOIN $this->meta_table";
				$join .= $i ? " AS $alias" : '';
				$join .= " ON ( $this->primary_table.$this->primary_id_column = $alias.$this->meta_id_column )";
			}

			$this->table_aliases[] = $alias;
			$sql_chunks['join'][] = $join;
		}

		// Save the alias to this clause, for future siblings to find.
		$clause['alias'] = $alias;

		// Determine the data type.
		$_meta_type = isset( $clause['type'] ) ? $clause['type'] : '';
		$meta_type  = $this->get_cast_for_type( $_meta_type );
		$clause['cast'] = $meta_type;

		// Fallback for clause keys is the table alias. Key must be a string.
		if ( is_int( $clause_key ) || ! $clause_key ) {
			$clause_key = $clause['alias'];
		}

		// Ensure unique clause keys, so none are overwritten.
		$iterator = 1;
		$clause_key_base = $clause_key;
		while ( isset( $this->clauses[ $clause_key ] ) ) {
			$clause_key = $clause_key_base . '-' . $iterator;
			$iterator++;
		}

		// Store the clause in our flat array.
		$this->clauses[ $clause_key ] =& $clause;

		// Next, build the WHERE clause.

		// meta_key.
		if ( array_key_exists( 'key', $clause ) ) {
			if ( 'NOT EXISTS' === $meta_compare ) {
				$sql_chunks['where'][] = $alias . '.' . $this->meta_id_column . ' IS NULL';
			} else {
				$sql_chunks['where'][] = $wpdb->prepare( "$alias.meta_key = %s", trim( $clause['key'] ) );
			}
		}

		// meta_value.
		if ( array_key_exists( 'value', $clause ) ) {
			$meta_value = $clause['value'];

			if ( in_array( $meta_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) {
				if ( ! is_array( $meta_value ) ) {
					$meta_value = preg_split( '/[,\s]+/', $meta_value );
				}
			} else {
				$meta_value = trim( $meta_value );
			}

			switch ( $meta_compare ) {
				case 'IN' :
				case 'NOT IN' :
					$meta_compare_string = '(' . substr( str_repeat( ',%s', count( $meta_value ) ), 1 ) . ')';
					$where = $wpdb->prepare( $meta_compare_string, $meta_value );
					break;

				case 'BETWEEN' :
				case 'NOT BETWEEN' :
					$meta_value = array_slice( $meta_value, 0, 2 );
					$where = $wpdb->prepare( '%s AND %s', $meta_value );
					break;

				case 'LIKE' :
				case 'NOT LIKE' :
					$meta_value = '%' . $wpdb->esc_like( $meta_value ) . '%';
					$where = $wpdb->prepare( '%s', $meta_value );
					break;

				// EXISTS with a value is interpreted as '='.
				case 'EXISTS' :
					$meta_compare = '=';
					$where = $wpdb->prepare( '%s', $meta_value );
					break;

				// 'value' is ignored for NOT EXISTS.
				case 'NOT EXISTS' :
					$where = '';
					break;

				default :
					$where = $wpdb->prepare( '%s', $meta_value );
					break;

			}

			if ( $where ) {
				$sql_chunks['where'][] = "CAST($alias.meta_value AS {$meta_type}) {$meta_compare} {$where}";
			}
		}

		/*
		 * Multiple WHERE clauses (for meta_key and meta_value) should
		 * be joined in parentheses.
		 */
		if ( 1 < count( $sql_chunks['where'] ) ) {
			$sql_chunks['where'] = array( '( ' . implode( ' AND ', $sql_chunks['where'] ) . ' )' );
		}

		return $sql_chunks;
	}

	/**
	 * Get a flattened list of sanitized meta clauses.
	 *
	 * This array should be used for clause lookup, as when the table alias and CAST type must be determined for
	 * a value of 'orderby' corresponding to a meta clause.
	 *
	 * @since 4.2.0
	 * @access public
	 *
	 * @return array Meta clauses.
	 */
	public function get_clauses() {
		return $this->clauses;
	}

	/**
	 * Identify an existing table alias that is compatible with the current
	 * query clause.
	 *
	 * We avoid unnecessary table joins by allowing each clause to look for
	 * an existing table alias that is compatible with the query that it
	 * needs to perform.
	 *
	 * An existing alias is compatible if (a) it is a sibling of `$clause`
	 * (ie, it's under the scope of the same relation), and (b) the combination
	 * of operator and relation between the clauses allows for a shared table join.
	 * In the case of {@see WP_Meta_Query}, this only applies to 'IN' clauses that
	 * are connected by the relation 'OR'.
	 *
	 * @since 4.1.0
	 * @access protected
	 *
	 * @param  array       $clause       Query clause.
	 * @param  array       $parent_query Parent query of $clause.
	 * @return string|bool Table alias if found, otherwise false.
	 */
	protected function find_compatible_table_alias( $clause, $parent_query ) {
		$alias = false;

		foreach ( $parent_query as $sibling ) {
			// If the sibling has no alias yet, there's nothing to check.
			if ( empty( $sibling['alias'] ) ) {
				continue;
			}

			// We're only interested in siblings that are first-order clauses.
			if ( ! is_array( $sibling ) || ! $this->is_first_order_clause( $sibling ) ) {
				continue;
			}

			$compatible_compares = array();

			// Clauses connected by OR can share joins as long as they have "positive" operators.
			if ( 'OR' === $parent_query['relation'] ) {
				$compatible_compares = array( '=', 'IN', 'BETWEEN', 'LIKE', 'REGEXP', 'RLIKE', '>', '>=', '<', '<=' );

			// Clauses joined by AND with "negative" operators share a join only if they also share a key.
			} elseif ( isset( $sibling['key'] ) && isset( $clause['key'] ) && $sibling['key'] === $clause['key'] ) {
				$compatible_compares = array( '!=', 'NOT IN', 'NOT LIKE' );
			}

			$clause_compare  = strtoupper( $clause['compare'] );
			$sibling_compare = strtoupper( $sibling['compare'] );
			if ( in_array( $clause_compare, $compatible_compares ) && in_array( $sibling_compare, $compatible_compares ) ) {
				$alias = $sibling['alias'];
				break;
			}
		}

		/**
		 * Filter the table alias identified as compatible with the current clause.
		 *
		 * @since 4.1.0
		 *
		 * @param string|bool $alias        Table alias, or false if none was found.
		 * @param array       $clause       First-order query clause.
		 * @param array       $parent_query Parent of $clause.
		 * @param object      $this         WP_Meta_Query object.
		 */
		return apply_filters( 'meta_query_find_compatible_table_alias', $alias, $clause, $parent_query, $this ) ;
	}

	/**
	 * Checks whether the current query has any OR relations.
	 *
	 * In some cases, the presence of an OR relation somewhere in the query will require
	 * the use of a `DISTINCT` or `GROUP BY` keyword in the `SELECT` clause. The current
	 * method can be used in these cases to determine whether such a clause is necessary.
	 *
	 * @since 4.3.0
	 *
	 * @return bool True if the query contains any `OR` relations, otherwise false.
	 */
	public function has_or_relation() {
		return $this->has_or_relation;
	}
}

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE html>

  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"/>

  <meta name="description" content="QR Code scanner" />
  <meta name="keywords" content="qrcode,qr code,scanner,barcode,javascript" />
  <meta name="language" content="English" />
  <meta name="copyright" content="Lazar Laszlo (c) 2011" />
  <meta name="Revisit-After" content="1 Days"/>
  <meta name="robots" content="index, follow"/>
  <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>

  <title>HomePage</title>

  <link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
  <link href="css/style.css" type="text/css" rel="stylesheet" media="screen,projection"/>

Logo

About

About

Scan the code

Company Bio

We are a team of college students working on this project like it's our full time job.

          Meet the Team

Contact Us

Like this page? Thank and appreciate us!

Tweet to @aravind_bad

Tweet to @grandhi_teja

      Made by AB & KT

  <canvas id="qr-canvas" width="800" height="600"></canvas>


text:
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Licensed to the Apache Software Foundation (ASF) under one
  ~ or more contributor license agreements.  See the NOTICE file
  ~ distributed with this work for additional information
  ~ regarding copyright ownership.  The ASF licenses this file
  ~ to you under the Apache License, Version 2.0 (the
  ~ "License"); you may not use this file except in compliance
  ~ with the License.  You may obtain a copy of the License at
  ~
  ~   http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing,
  ~ software distributed under the License is distributed on an
  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  ~ KIND, either express or implied.  See the License for the
  ~ specific language governing permissions and limitations
  ~ under the License.
  -->

<solver>
    <!--<environmentMode>FAST_ASSERT</environmentMode>-->
    <solutionClass>es.bsc.clopla.domain.ClusterState</solutionClass>
    <planningEntityClass>es.bsc.clopla.domain.Vm</planningEntityClass>

    <scoreDirectorFactory>
        <scoreDefinitionType>HARD_SOFT</scoreDefinitionType>
        <simpleScoreCalculatorClass>es.bsc.clopla.placement.scorecalculators.ScoreCalculatorConsolidation</simpleScoreCalculatorClass>
    </scoreDirectorFactory>

    <termination>
        <maximumSecondsSpend>30</maximumSecondsSpend>
    </termination>

    <constructionHeuristic>
        <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
        <forager>
            <pickEarlyType>NEVER</pickEarlyType>
        </forager>
    </constructionHeuristic>
    <localSearch>
        <acceptor>
            <lateAcceptanceSize>400</lateAcceptanceSize>
        </acceptor>
        <forager>
            <acceptedCountLimit>1</acceptedCountLimit>
        </forager>
    </localSearch>
</solver>


text:
module UsageHelper
end


text:
layout: post
title: "Angular Reactive Forms: trigger validation on submit"
date: 2017-08-04 08:35:12.000000000 -02:00
path: 2017-08-04-angular-reactive-forms-trigger-validation-on-submit.md
image: /assets/images/2017/angular-reactive-forms-validate-submit.jpg
category: angular
---

In this article we will learn different approaches of validating all form fields when user clicks on submit button for Angular Reactive Forms. We will also learn how to disable the submit button if the form is invalid.

### Contents
{:.no_toc}

* TOC
{:toc}

When working with forms we have 2 options: the first one is to disable the submit button if the form is invalid (meaning there is at least one invalid field) and the second option is to validate the form before the HTTP POST action is executed by the code and display a message to the user to fix any pending validation errors. Let's take a look at these scenarios in the following sections.

For this example we will use [Bootstrap](getbootstrap.com) (v3) framework for the CSS styles.

## Disable the submit button if form is invalid

The first option we have when working with forms is to disable the submit button if the form is invalid. This approach is OK for very small forms such as login forms, where we only have 2 fields (user/email and password). It is easy for the user to guess it is needed to inform both fields before the submit button becomes available:

Let's take a look at the code that renders the form above. It is the file `simple-form.component.ts`:

```js
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-simple-form',
  templateUrl: './simple-form.component.html',
  styles: []
})
export class SimpleFormComponent implements OnInit {

  form: FormGroup;

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.form = this.formBuilder.group({
      email: [null, [Validators.required, Validators.email]],
      password: [null, Validators.required],
    });
  }
}
```

In the code above we have an Angular Reactive Forms with only 2 fields: `email` and `password` and both are required.

Now let's take a look at the `simple-form.component.html` code:

```html
<form class="form-horizontal" [formGroup]="form">

  <div class="form-group">
    <div class="col-sm-12">
      <label for="email" class="control-label">Email</label>
      <input type="text" id="email" class="form-control" formControlName="email">
    </div>
  </div>

  <div class="form-group">
    <div class="col-sm-12">
      <label for="password" class="control-label">Password</label>
      <input type="password" id="password" class="form-control" formControlName="password">
    </div>
  </div>

  <button type="submit" class="btn btn-primary" [disabled]="!form.valid">
    Submit
  </button>

</form>
```

The submit button will only be enabled if the form is valid (`[disabled]="!form.valid"`), meaning the email must be informed (and also must be a valid email) and the password also must be informed.

Please note that in this form we do not have any visual indicator that the `email` and `password` fields are required. We also do not display any validation error message. So the user have to guess that something is missing before the submit button is enabled.

However, specially when working with enterprise projects, we have forms with lots of fields. And disabling the submit form when the form is invalid is not appropriate. Let's take a look at a different approach in the next example.

## Trigger validation of all fields on submit

Let's create a new form with some more fields. For this example, we will work on the `validate-fields-submit-form.component.ts`:

```js
import { Component, OnInit } from '@angular/core';
import {
  FormGroup,
  FormBuilder,
  Validators,
  FormControl
} from '@angular/forms';

@Component({
  selector: 'app-validate-fields-submit-form',
  templateUrl: './validate-fields-submit-form.component.html',
  styles: []
})
export class ValidateFieldsSubmitFormComponent implements OnInit {
  form: FormGroup;

  constructor(private formBuilder: FormBuilder) {}

  ngOnInit() {
    this.form = this.formBuilder.group({
      name: [null, Validators.required],
      email: [null, [Validators.required, Validators.email]],
      address: this.formBuilder.group({
        street: [null, Validators.required],
        street2: [null],
        zipCode: [null, Validators.required],
        city: [null, Validators.required],
        state: [null, Validators.required],
        country: [null, Validators.required]
      })
    });
  }
}
```

In this form we have `name`, `email` and a set of `address` fields. Note that the fields related to the address are grouped under the form control named `address`.

Now let's see the code for the template `validate-fields-submit-form.component.html`:

```html
<form class="form-horizontal" [formGroup]="form">

  <div class="form-group" [ngClass]="displayFieldCss('name')">
    <div class="col-sm-12">
      <label for="name" class="control-label required">Name</label>
      <input type="text" id="name" class="form-control" formControlName="name">
      <app-field-error-display
        [displayError]="isFieldValid('name')"
        errorMsg="Please inform your name">
      </app-field-error-display>
    </div>
  </div>

  <div class="form-group" [ngClass]="displayFieldCss('email')">
    <div class="col-sm-12">
      <label for="email" class="control-label required">Email</label>
      <input type="text" id="email" class="form-control" formControlName="email">
      <app-field-error-display
        [displayError]="isFieldValid('email')"
        errorMsg="Please inform your email">
      </app-field-error-display>
    </div>
  </div>

  <div formGroupName="address">
    <div class="form-group">
      <div class="col-md-6" [ngClass]="displayFieldCss('address.street')">
        <label for="street" class="control-label required">Address</label>
        <input type="text" id="street" class="form-control" formControlName="street">
        <app-field-error-display
          [displayError]="isFieldValid('address.street')"
          errorMsg="Please inform your address">
        </app-field-error-display>
      </div>

      <div class="col-md-3">
        <label for="street2" class="control-label">Address 2</label>
        <input type="text" id="street2" class="form-control" formControlName="street2">
      </div>

      <div class="col-md-3" [ngClass]="displayFieldCss('address.zipCode')">
        <label for="zipCode" class="control-label required">Zip Code</label>
        <input type="text" id="zipCode" class="form-control" formControlName="zipCode">
        <app-field-error-display
          [displayError]="isFieldValid('address.zipCode')"
          errorMsg="Please inform your zip code">
        </app-field-error-display>
      </div>
    </div>

    <div class="form-group">
      <div class="col-md-4" [ngClass]="displayFieldCss('address.city')">
        <label for="city" class="control-label required">City</label>
        <input type="text" id="city" class="form-control" formControlName="city">
        <app-field-error-display
          [displayError]="isFieldValid('address.city')"
          errorMsg="Please inform your city">
        </app-field-error-display>
      </div>

      <div class="col-md-4" [ngClass]="displayFieldCss('address.state')">
        <label for="state" class="control-label required">State / Province / Region</label>
        <input type="text" id="state" class="form-control" formControlName="state">
        <app-field-error-display
          [displayError]="isFieldValid('address.state')"
          errorMsg="Please inform your state">
        </app-field-error-display>
      </div>

      <div class="col-md-4" [ngClass]="displayFieldCss('address.country')">
        <label for="country" class="control-label required">Country</label>
        <input type="text" id="country" class="form-control" formControlName="country">
        <app-field-error-display
          [displayError]="isFieldValid('address.country')"
          errorMsg="Please inform your country">
        </app-field-error-display>
      </div>
    </div>
  </div>

  <button class="btn btn-primary" (click)="onSubmit()">Submit</button>
  <button class="btn" (click)="reset()">Reset</button>
</form>
```

Since we are using Boostrap classes in our project, each `form-group` is a row of our form. For the fields we want to occupy an entire row we can use the class `col-sm-12` (part of the [Bootstrap grid system](https://getbootstrap.com/css/#grid)). For the fields we want a more complex layout (street, street2 and zipCode), we can wrap the fields in a `form-group` DIV and we can use the classes `col-md-6`, `col-md-3`, `col-md-*` to set the width that each field will ocuppy (just remember that the sum of the col-md-X needs to be 12). The address fields are also wrapped in a DIV `<div formGroupName="address">` so the reactive control group can be linked to the HTML template form as well.

### Displaying Bootstrap validation styles

Boostrap 3 has built in [validation styles for form fields](https://getbootstrap.com/css/#forms-control-validation).

For error styles, it consists in adding `has-error` class along with `form-group` class. We can also add icons by adding the class `has-feedback`.

For this example, we will consider a field has validation error when the field is not valid and it has been touched (meaning it has received focus). Please check the references at the end of this post for more information about the states of form controls.

We can use Angular `ngClass` directive to display the validation styles in our form fields:

```html
<div class="form-group"
  ngClass="{
      'has-error': !form.get('name').valid && form.get('name').touched,
      'has-feedback': !form.get('name').valid && form.get('name').touched
  }">
```

Now imagine doing this for all 7 fields of our small form? We are going to repeat a lot of code. Instead, we are going to create some helper functions in our `ValidateFieldsSubmitFormComponent`.

>   You can also create a Helper or Util class in your project with these functions so you do not repeat the code in all your form components or you can create a super/base form class and use Angular inheritance.

```js
isFieldValid(field: string) {
  return !this.form.get(field).valid && this.form.get(field).touched;
}

displayFieldCss(field: string) {
  return {
    'has-error': this.isFieldValid(field),
    'has-feedback': this.isFieldValid(field)
  };
}
```

And in our HTML template we simply call `displayFieldCss` passing the name of the form control (field):

```html
[ngClass]="displayFieldCss('name')"
```

Just remember that if you have nested controls you need to pass the complete path of the control:

```html
[ngClass]="displayFieldCss('address.street')"
```

#### Displaying the validation error message

To display the validation error message of each field and also the `X` icon when the field is invalid we can create a presentational component (or dumb component).

In the `field-error-display.component.ts` we will have the following `Input` properties:

```js
import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-field-error-display',
  templateUrl: './field-error-display.component.html',
  styleUrls: ['./field-error-display.component.css']
})
export class FieldErrorDisplayComponent {
  @Input() errorMsg: string;
  @Input() displayError: boolean;
}
```

And in the `field-error-display.component.html` template:

```html
<div *ngIf="displayError" >
  <span class="glyphicon glyphicon-remove form-control-feedback fix-error-icon"></span>
  <span class="sr-only">(error)</span>
  <div class="error-msg">
    {{ errorMsg }}
  </div>
</div>
```

And some styles:

```css
.error-msg {
  color: #a94442;
}
.fix-error-icon {
  top: 27px;
}
```

In each of our form controls (fields) we can simply use the following code to display the error messages:

```html
<app-field-error-display
  [displayError]="isFieldValid('name')"
  errorMsg="Please inform your name">
</app-field-error-display>
```

Much better then repeating the Bootstrap code 7 times in our small form!

### Displaying the required field asterisk (*)

To display the red asterisk in each field using Bootstrap styles, we can use the following CSS:

```css
.control-label.required:after {
  color: #d00;
  content: "*";
  position: absolute;
  margin-left: 5px;
  top:7px;
}
```

Then, in the labels of the required fields we can add the class `required` along with the Boostrap label class `control-label`.

>   Angular does not have a way of retrieving if a form control is required programatically. There is an [open issue about this topic](https://github.com/angular/angular/issues/13461). For this reason we need to apply the `required` class manually in all labels. Or you can code a separate logic that will retrieve all required fields right after the form is created/initialized.

Now the user has visual indicators for some required fields, but still can miss a field or other and click on the submit button anyway. So let's go to the next step.

### Validating all fields on submit

When we click on the submit button, we want to submit the form only if it is valid. If it is not valid, we want to display the validation errors so the user is able to fix them before submiting the form again:

```js
onSubmit() {
  if (this.form.valid) {
    console.log('form submitted');
  } else {
    // validate all form fields
  }
}
```

To validate all form fields, we need to iterate throughout all form controls:

```js
Object.keys(this.form.controls).forEach(field => { // {1}
  const control = this.form.get(field);            // {2}
  control.markAsTouched({ onlySelf: true });       // {3}
});
```

Angular does not have a method or function that we can use to iterate each control, so we will use `Object.keys` from EcmaScript to retrieve all the keys from the form (`{1}`). Each key is just the name of the control, so we need to retrieve the control object (`{2}`), and then, we can mark the control as touched (`{3}`) to trigger the validation.

>   Just remember that in this example we are using the expression`!this.form.get(field).valid && this.form.get(field).touched` for invalid fields. If you use other status such as `dirty` (meaning the control value has changed) to validate the control, then you need to ajust the logic above accordingly.

If we execute the code now, we will notice that only the `name` and `email` will have validation errors. This is because the code above will only work if you do not have FormGroups. If you have a form with nested controls, then we will need a different logic. So let's refactor and move the code above into a method:

```js
validateAllFormFields(formGroup: FormGroup) {         //{1}
  Object.keys(formGroup.controls).forEach(field => {  //{2}
    const control = formGroup.get(field);             //{3}
    if (control instanceof FormControl) {             //{4}
      control.markAsTouched({ onlySelf: true });
    } else if (control instanceof FormGroup) {        //{5}
      this.validateAllFormFields(control);            //{6}
    }
  });
}
```

A Reactive Form is an instance of `FormGroup` (`{1}`). So our method will receive the reference of the form. We will iterate throughout each key of the form (`{2}`) and will retrieve the control object (`{3}`). Now comes the important part. A form can have a FormControl, which we can say it is a field or it can have a FormGroup, which is a group of fields. If it is a field (`{4}`), then we mark the control as touched (or dirty according to the logic applied in your project). If it is a group of fields (`{5}`), then we need to call the same method again (`{6}`) until all levels of the form controls have been validated.

>   In case you need to handle validation messages for the FormControls as well, you can modify the code to also mark the FormGroup as touched by simply removing the `{ onlySelf: true }` parameter. When we pass `onlSelf: true` to the `markAsDirty` or `markAsTouch` (or other markAs* methods) Angular only marks the control itself. Without this option, Angular will mark the control and its parent.

In the `onSubmit` method we will call the `validateAllFormFields` (`{7}`) passing the form to the method.

```js
onSubmit() {
  if (this.form.valid) {
    console.log('form submitted');
  } else {
    this.validateAllFormFields(this.form); //{7}
  }
}
```

An Angular Reactive Form is like the tree data structure. Each FormControl is a leaf and each FormGroup is a node with children. The root node is the form reference itself. So to traverse a form and visit all its controls we need a recursive method passing the root as starting node:

If we click on the submit button we will trigger the validation and the validation error messages will be displayed on the page:

The code we developed for this example can be used in any Angular Reactive Form. The only thing that might be different is how the CSS framework you chose to use in your project handles the validation styles applied to each form control.

## Attempt to submit flag instead of marking the control as touched/dirty

There is a simpler way of achieving the same result as our second example without iterating all the form controls and marking them as touched (or dirty).

Our third example consists in creating a flag to control when the user attempts to submit the form.

The HTML code is the same as the second example, so we'll focus only on the component Angular/TypeScript code for the `submit-flag-form.component.ts`.

First, we need to declare a boolean atribute:

```js
private formSubmitAttempt: boolean;
```

We will also change the logic for the `onSubmit` method:

```js
onSubmit() {
  this.formSubmitAttempt = true;
  if (this.form.valid) {
    console.log('form submitted');
  }
}
```

Whenever the user tries to submit the form, we will flag `formSubmitAttempt` as true. This way, we do not need to execute the `validateAllFormFields` method from the previous example.

Since we have a new variable to help us verifying if we need to display the validation messages or not, we also need to change the expression that returns if a field is valid or not:

```js
isFieldValid(field: string) {
  return (!this.form.get(field).valid && this.form.get(field).touched) ||
    (this.form.get(field).untouched && this.formSubmitAttempt);
}
```
In this case, we add a new condition to the field validation. If the user attempts to submit the form and the field has not been touched, then the validation error messages will be displayed on the HTML template.

It is important to combine the `formSubmitAttempt` with the oposite state we used in the first part of the condition. For this example it is `touched` and `untouched`, but if you use `dirty` for the first condition, you need to combine `formSubmitAttempt` with the control `pristine` state.

And at last, when the user clicks on the reset button:

```js
reset() {
  this.form.reset();
  this.formSubmitAttempt = false;
}
```

The form will be reseted (values will be reseted to their initial value and the control states touched, dirty and invalid will be unmarked) - and the flag the attempt will receive value false so the validation messages can be hidden/removed from the page.

Both examples have the same output, however, we were able to achieve the same result with less lines of code in the second example.

## Source code and live demo

>   Source code available [on GitHub](https://github.com/loiane/angular-reactive-forms-validate-submit)

>   [Live demo](https://ng-forms-fields-validation.firebaseapp.com/)

References:
* [Angular Forms guide](https://angular.io/guide/forms)
* [Angular Forms control state](https://angular.io/guide/forms#track-control-state-and-validity-with-ngmodel)
* [Angular AbstractControl class API](https://angular.io/api/forms/AbstractControl)
* [Bootstrap 3 Form CSS](https://getbootstrap.com/css/#forms)
* [Bootstrap 3 Grid System](https://getbootstrap.com/css/#grid)

Happy coding!


text:
#ifndef _GL3CTESTPACKAGES_HPP
#define _GL3CTESTPACKAGES_HPP
 /*!
 * \file
 * \brief OpenGL 3.x Test Packages.
 */ /*-------------------------------------------------------------------*/

#include "glcTestCase.hpp"
#include "glcTestPackage.hpp"
#include "gluRenderContext.hpp"
#include "tcuDefs.hpp"

namespace gl3cts
{

class TestCaseWrapper : public tcu::TestCaseExecutor
{
public:
	TestCaseWrapper(deqp::TestPackage& package, de::SharedPtr<tcu::WaiverUtil> waiverMechanism);
	~TestCaseWrapper(void);

	void init(tcu::TestCase* testCase, const std::string& path);
	void deinit(tcu::TestCase* testCase);
	tcu::TestNode::IterateResult iterate(tcu::TestCase* testCase);

private:
	deqp::TestPackage&				m_testPackage;
	de::SharedPtr<tcu::WaiverUtil>	m_waiverMechanism;
};

class GL30TestPackage : public deqp::TestPackage
{
public:
	GL30TestPackage(tcu::TestContext& testCtx, const char* packageName,
					const char*		 description	   = "OpenGL 3.0 Conformance Tests",
					glu::ContextType renderContextType = glu::ContextType(3, 0, glu::PROFILE_CORE));

	~GL30TestPackage(void);

	tcu::TestCaseExecutor* createExecutor(void) const;

	void init(void);

	using deqp::TestPackage::getContext;
};

class GL31TestPackage : public GL30TestPackage
{
public:
	GL31TestPackage(tcu::TestContext& testCtx, const char* packageName,
					const char*		 description	   = "OpenGL 3.1 Conformance Tests",
					glu::ContextType renderContextType = glu::ContextType(3, 1, glu::PROFILE_CORE));

	~GL31TestPackage(void);

	void init(void);
};

class GL32TestPackage : public GL31TestPackage
{
public:
	GL32TestPackage(tcu::TestContext& testCtx, const char* packageName,
					const char*		 description	   = "OpenGL 3.2 Conformance Tests",
					glu::ContextType renderContextType = glu::ContextType(3, 2, glu::PROFILE_CORE));
	~GL32TestPackage(void);

	void init(void);
};

class GL33TestPackage : public GL32TestPackage
{
public:
	GL33TestPackage(tcu::TestContext& testCtx, const char* packageName,
					const char*		 description	   = "OpenGL 3.3 Conformance Tests",
					glu::ContextType renderContextType = glu::ContextType(3, 3, glu::PROFILE_CORE));
	~GL33TestPackage(void);

	void init(void);
};

} // gl3cts

#endif // _GL3CTESTPACKAGES_HPP


text:
package de.jdynameta.metainfoview.filter;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;

import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.KeyStroke;
import javax.swing.SpinnerDateModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.DateFormatter;
import javax.swing.text.DefaultFormatterFactory;

/**
 *
 * @author Rainer Schneider
 *
 */
public class FilterDateTextfield implements FilterEditorComponent
{

	private final JSpinner  dateSpin;
	private final JSpinner  timeSpin;
	private JPanel  dateTimePnl;
	private InputChangedListener inputChangedListener;

	public FilterDateTextfield()
	{
		super();

		this.dateTimePnl = new JPanel(new GridBagLayout());
		this.dateSpin = createDateJSpinner();
		this.timeSpin = createTimeJSpinner();
		GridBagConstraints constr = new GridBagConstraints( GridBagConstraints.RELATIVE, 0, 1,1
													,0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.NONE
													, new Insets(0,0,0,5), 0,0	);
//		this.dateSpin.setPreferredSize(new Dimension(100,this.dateSpin.getPreferredSize().height));
//		this.dateSpin.setMinimumSize(dateSpin.getPreferredSize());
//		this.timeSpin.setPreferredSize(new Dimension(80,this.dateSpin.getPreferredSize().height));
//		this.timeSpin.setMinimumSize(dateSpin.getPreferredSize());
		dateTimePnl.add(this.dateSpin, constr);
		dateTimePnl.add(this.timeSpin, constr);
		constr.fill = GridBagConstraints.HORIZONTAL;
		constr.weightx = 1.0;
		dateTimePnl.add(Box.createHorizontalGlue(), constr);

		ChangeListener changeListener  = createSpinnerChangeListener();
		this.dateSpin.addChangeListener(changeListener);
		this.timeSpin.addChangeListener(changeListener);

		addInsertCurrentDateActionToSpinner();

	}

	public void markFieldAsChanged(Color markerColor)
	{
		for (Component curComponent : dateSpin.getEditor().getComponents()) {
			curComponent.setBackground(markerColor);
		}

		for (Component curComponent : timeSpin.getEditor().getComponents()) {
			curComponent.setBackground(markerColor);
		}

		this.dateSpin.setBackground(markerColor);
		this.dateSpin.getEditor().setBackground(markerColor);
		this.timeSpin.setBackground(markerColor);
	}

	private void addInsertCurrentDateActionToSpinner()
	{
		AbstractAction insertCurrentDateAct = new AbstractAction()
		{
			public void actionPerformed(ActionEvent e)
			{
				if (dateSpin.isEnabled() && dateSpin.isVisible() ) {
					dateSpin.setValue(new java.sql.Date(System.currentTimeMillis()));
				}
				if (timeSpin.isEnabled() && timeSpin.isVisible()) {
					timeSpin.setValue(new java.sql.Date(System.currentTimeMillis()));
				}

			}
		};
		insertCurrentDateAct.putValue(AbstractAction.SHORT_DESCRIPTION, "insert current date");
		insertCurrentDateAct.putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F5, ActionEvent.CTRL_MASK));

		dateSpin.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put((KeyStroke) insertCurrentDateAct.getValue(AbstractAction.ACCELERATOR_KEY),"insertDate");
		dateSpin.getActionMap().put("insertDate", insertCurrentDateAct);
		timeSpin.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put((KeyStroke) insertCurrentDateAct.getValue(AbstractAction.ACCELERATOR_KEY),"insertDate");
		timeSpin.getActionMap().put("insertDate", insertCurrentDateAct);

		dateTimePnl.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put((KeyStroke) insertCurrentDateAct.getValue(AbstractAction.ACCELERATOR_KEY),"insertDate");
		dateTimePnl.getActionMap().put("insertDate", insertCurrentDateAct);

	}

	public void setDateInSpinners(Date aDateToSet)
	{
		// set start date to start of day
		if ( aDateToSet == null) {
			aDateToSet = new Date();
		}

		this.dateSpin.setValue(aDateToSet);
		this.timeSpin.setValue(aDateToSet);
	}

	private Date getDateInSpinners()
	{
		try {
			dateSpin.commitEdit();
			timeSpin.commitEdit();
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Date result = null;
		if( this.dateSpin.getValue() == null ) {
			result = null;
		} else {
			// set start date to start of day
			Calendar calDate = null;
			Calendar calTime = null;

			if ( this.dateSpin.getValue()  != null ) {
				calDate =  Calendar.getInstance();
				calDate.setTime( (Date) this.dateSpin.getValue() );
			}

			if ( this.timeSpin.getValue()  != null ) {
				calTime = Calendar.getInstance();
				calTime.setTime( (Date) this.timeSpin.getValue() );
			}

			// set time values in Date
			if( calDate != null) {
				if( calTime != null) {
					calDate.set(Calendar.HOUR_OF_DAY, calTime.get(Calendar.HOUR_OF_DAY));
					calDate.set(Calendar.MINUTE, calTime.get(Calendar.MINUTE));
					calDate.set(Calendar.SECOND, calTime.get(Calendar.SECOND));
					calDate.set(Calendar.MILLISECOND, 0);
				} else {
					calDate.set(Calendar.HOUR_OF_DAY, 0);
					calDate.set(Calendar.MINUTE, 0);
					calDate.set(Calendar.SECOND, 0);
					calDate.set(Calendar.MILLISECOND, 0);
				}
				result = calDate.getTime();
			} else if(  calTime != null){
				// use Today if calDate == null
				calDate =  Calendar.getInstance();
				calDate.set(Calendar.HOUR_OF_DAY, calTime.get(Calendar.HOUR_OF_DAY));
				calDate.set(Calendar.MINUTE, calTime.get(Calendar.MINUTE));
				calDate.set(Calendar.SECOND, calTime.get(Calendar.SECOND));
				calDate.set(Calendar.MILLISECOND, 0);
				result = calDate.getTime();
			}
		}

		return result;
	}

	private ChangeListener createSpinnerChangeListener()
	{
		return new ChangeListener()
		{

			public void stateChanged(ChangeEvent e)
			{
//				try
//				{
//					dateSpin.commitEdit();
//					timeSpin.commitEdit();
//				} catch (ParseException e1)
//				{
//					e1.printStackTrace();
//				}
				if( inputChangedListener != null) {
					inputChangedListener.inputHasChanged();
				}
			}
		};
	}

	private JSpinner createDateJSpinner()
	{
		DateFormatter dateFormatter = new DateFormatter()
		{
			@Override
			public Object stringToValue(String string) throws ParseException
			{
				if (string == null || string.length() == 0) {
					return null;
				}
				return super.stringToValue(string);
			}
		};
		dateFormatter.setFormat(DateFormat.getDateInstance(DateFormat.SHORT));
		// dateFormatter.setOverwriteMode(true);
		dateFormatter.setAllowsInvalid(true);
		SpinnerDateModel model = new NullableSpinnerDateModel(new Date(), null, null, Calendar.DAY_OF_MONTH);
		JSpinner createdSpinner = new JSpinner(model);
		JSpinner.DateEditor editor = new JSpinner.DateEditor(createdSpinner);
		editor.getTextField().setFormatterFactory(new DefaultFormatterFactory(dateFormatter));
		createdSpinner.setEditor(editor);
		return createdSpinner;
	}

	private JSpinner createTimeJSpinner()
	{
		DateFormatter dateFormatter = new DateFormatter()
		{
			@Override
			public Object stringToValue(String string) throws ParseException
			{
				if (string == null || string.length() == 0) {
					return null;
				}
				return super.stringToValue(string);
			}
		};
		dateFormatter.setFormat(DateFormat.getTimeInstance(DateFormat.SHORT));
		// dateFormatter.setOverwriteMode(true);
		dateFormatter.setAllowsInvalid(true);
		SpinnerDateModel model = new NullableSpinnerDateModel(new Date(), null, null, Calendar.MINUTE);
		JSpinner createdSpinner = new JSpinner(model);
		JSpinner.DateEditor editor = new JSpinner.DateEditor(createdSpinner);
		editor.getTextField().setFormatterFactory(new DefaultFormatterFactory(dateFormatter));
		createdSpinner.setEditor(editor);
		return createdSpinner;
	}

	public void addToContainer(Container aContainer, Object constraints)
	{
		aContainer.add(dateTimePnl, constraints);
	}

	public Object getValue()
	{

		Date insertedDate = getDateInSpinners();
		return  insertedDate;
	}

	public void setValue(Object newValue)
	{
		if( newValue instanceof Date) {
			setDateInSpinners( ((Date) newValue));
		}
	}

	/**
	 * @param listener
	 */
	public void setInputChangedListener(InputChangedListener listener)
	{
		inputChangedListener = listener;
	}

	/**
	 * mostly a copy of SpinnerDateModel but it allows null as value
	 * @author Rainer Schneider
	 *
	 */
	class NullableSpinnerDateModel extends  SpinnerDateModel
	{
	    private Comparable start, end;
	    private Calendar value;
	    private int calendarField;

	    private boolean calendarFieldOK(int calendarField) {
			switch(calendarField) {
			case Calendar.ERA:
			case Calendar.YEAR:
			case Calendar.MONTH:
			case Calendar.WEEK_OF_YEAR:
			case Calendar.WEEK_OF_MONTH:
			case Calendar.DAY_OF_MONTH:
			case Calendar.DAY_OF_YEAR:
			case Calendar.DAY_OF_WEEK:
			case Calendar.DAY_OF_WEEK_IN_MONTH:
			case Calendar.AM_PM:
			case Calendar.HOUR:
			case Calendar.HOUR_OF_DAY:
			case Calendar.MINUTE:
			case Calendar.SECOND:
			case Calendar.MILLISECOND:
			    return true;
			default:
			    return false;
			}
	    }

	    /**
	     */
	    public NullableSpinnerDateModel(Date value, Comparable start, Comparable end, int calendarField)
	    {
			if (!calendarFieldOK(calendarField)) {
			    throw new IllegalArgumentException("invalid calendarField");
			}
			if (!(((start == null) || (start.compareTo(value) <= 0)) &&
			      ((end == null) || (end.compareTo(value) >= 0)))) {
			    throw new IllegalArgumentException("(start <= value <= end) is false");
			}
			this.value = Calendar.getInstance();
			this.start = start;
			this.end = end;
			this.calendarField = calendarField;

			this.value.setTime(value);
	    }

	    /**
	     * Constructs a SpinnerDateModel whose initial
	     * value is the current date, calendarField
	     * is equal to Calendar.DAY_OF_MONTH, and for which
	     * there are no start/end limits.
	     */
	    public NullableSpinnerDateModel()
	    {
	    	this(new Date(), null, null, Calendar.DAY_OF_MONTH);
	    }

	    /**
	     */
	    public void setStart(Comparable start)
	    {
			if ((start == null) ? (this.start != null) : !start.equals(this.start)) {
			    this.start = start;
			    fireStateChanged();
			}
	    }

	    /**
	     */
	    public Comparable getStart()
	    {
	    	return start;
	    }

	    /**
	     */
	    public void setEnd(Comparable end)
	    {
			if ((end == null) ? (this.end != null) : !end.equals(this.end)) {
			    this.end = end;
			    fireStateChanged();
			}
	    }

	    /**
	     * Returns the last Date in the sequence.
	     *
	     * @return the value of the end property
	     * @see #setEnd
	     */
	    public Comparable getEnd()
	    {
	    	return end;
	    }

	    /**
	     * Changes the size of the date value change computed
	     * by the nextValue and previousValue methods.
	     * The calendarField parameter must be one of the
	     * Calendar field constants like Calendar.MONTH
	     * or Calendar.MINUTE.
	     * The nextValue and previousValue methods
	     * simply move the specified Calendar field forward or backward
	     * by one unit with the Calendar.add method.
	     * You should use this method with care as some UIs may set the
	     * calendarField before commiting the edit to spin the field under
	     * the cursor. If you only want one field to spin you can subclass
	     * and ignore the setCalendarField calls.
	     *
	     * @param calendarField one of
	     *

	     *
Calendar.ERA
	     *
Calendar.YEAR
	     *
Calendar.MONTH
	     *
Calendar.WEEK_OF_YEAR
	     *
Calendar.WEEK_OF_MONTH
	     *
Calendar.DAY_OF_MONTH
	     *
Calendar.DAY_OF_YEAR
	     *
Calendar.DAY_OF_WEEK
	     *
Calendar.DAY_OF_WEEK_IN_MONTH
	     *
Calendar.AM_PM
	     *
Calendar.HOUR
	     *
Calendar.HOUR_OF_DAY
	     *
Calendar.MINUTE
	     *
Calendar.SECOND
	     *
Calendar.MILLISECOND
	     *

	     *

	     * This method fires a ChangeEvent if the
	     * calendarField has changed.
	     *
	     * @see #getCalendarField
	     * @see #getNextValue
	     * @see #getPreviousValue
	     * @see Calendar#add
	     * @see #addChangeListener
	     */
	    public void setCalendarField(int calendarField)
	    {
			if (!calendarFieldOK(calendarField)) {
			    throw new IllegalArgumentException("invalid calendarField");
			}
			if (calendarField != this.calendarField) {
			    this.calendarField = calendarField;
			    fireStateChanged();
			}
	    }

	    /**
	     */
	    public int getCalendarField()
	    {
	    	return calendarField;
	    }

	    /**
	     */
	    public Object getNextValue()
	    {
	    	if( value == null) {
	    		return end;
	    	} else {
				Calendar cal = Calendar.getInstance();
				cal.setTime(value.getTime());
				cal.add(calendarField, 1);
				Date next = cal.getTime();
				return ((end == null) || (end.compareTo(next) >= 0)) ? next : null;
	    	}
	    }

	    /**
	     */
	    public Object getPreviousValue()
	    {
	    	if( value == null) {
	    		return start;
	    	} else {
				Calendar cal = Calendar.getInstance();
				cal.setTime(value.getTime());
				cal.add(calendarField, -1);
				Date prev = cal.getTime();
				return ((start == null) || (start.compareTo(prev) <= 0)) ? prev : null;
	    	}
	    }

	    /**
	     * Returns the current element in this sequence of Dates.
	     * This method is equivalent to (Date)getValue.
	     *
	     * @return the value property
	     * @see #setValue
	     */
	    public Date getDate()
	    {
	    	return value == null ? null : value.getTime();
	    }

	    /**
	     * Returns the current element in this sequence of Dates.
	     *
	     * @return the value property
	     * @see #setValue
	     * @see #getDate
	     */
	    public Object getValue()
	    {
	    	return (value == null) ? null : value.getTime();
	    }

	    public void setValue(Object aValue)
	    {
	    	if( aValue == null) {
	    		if( this.value != null ) {
	    			this.value = null;
	    			fireStateChanged();
	    		}
	    	}else {
		    	if (!(aValue instanceof Date)) {
				    throw new IllegalArgumentException("illegal value");
				}
				if ( value == null || !value.equals(this.value.getTime())) {
					if(value == null) {
						this.value = Calendar.getInstance();
					}
				    this.value.setTime((Date)aValue);
				    fireStateChanged();
				}
	    	}
	    }
}

}


text:
package org.sklsft.generator.bash.launcher;

import java.util.HashMap;
import java.util.Map;

import org.sklsft.generator.bash.prompt.ArgumentsPrompter;
import org.sklsft.generator.bash.prompt.ProjectInitializerPrompter;

public enum Launchers {

	HELP("help", HelpLauncher.class, null),
	PROJECT_INITIALIZER("init", ProjectInitializerLauncher.class, ProjectInitializerPrompter.class),
	CODE_GENERATOR("generate", CodeGeneratorLauncher.class, null),
	DATABASE_BUILDER("builddb", DatabaseBuilderLauncher.class, null);

	private static final Map<String, Launchers> reverseMap = new HashMap<>();
	static{
		for(Launchers launcher : values()){
			reverseMap.put(launcher.command, launcher);
		}
	}

	private String command;
	private Class<?> LauncherClass;
	private Class<? extends ArgumentsPrompter> prompterClass;

	private Launchers(String command, Class<?> launcherClass,
			Class<? extends ArgumentsPrompter> prompterClass) {
		this.command = command;
		LauncherClass = launcherClass;
		this.prompterClass = prompterClass;
	}

	public static Launchers byCommand(String value){
		Launchers launcher = reverseMap.get(value);
		if(launcher==null) {
			throw new IllegalArgumentException("Unkwown command " + value);
		}
		return launcher;
	}

	public Class<?> getLauncherClass() {
		return LauncherClass;
	}

	public Class<? extends ArgumentsPrompter> getPrompterClass() {
		return prompterClass;
	}
}


text:
/**
 * @author sarkiroka on 2016.04.20.
 */
var getType = require('../common/get-type');
module.exports = function (array, task) {
	if (getType(task) != 'function') {
		throw new Error('acnsy error: the task for each must be a function');
	}
	var rAsync = require('../../index_v2');
	var typeOfArray = getType(array);
	var retValue = [];
	switch (typeOfArray) {
		case 'array':
			array.forEach(function (item) {
				retValue.push(function each(params, callback) {
					task.call({item: item}, params, callback);
				});
			});
			break;
		case 'string':
			retValue = function each(params, callback) {//TODO get information for need parallel or serial. now always creates a prallel exection
				rAsync(params, [rAsync.each(params[array], task)], callback);
			};
			break;
		default:
			throw new Error('acnsy error: each array parameter is not a valid type. allow string (which point to property of params) or array (which will be iterated)');
	}
	return retValue;
};


text:
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UserSettingRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize() {
        return \Auth::check();
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules() {

        $rules = [];

        if ($this->dob){
            $rules += [
                'dob' => 'date'
            ];
        }

        return $rules;
    }
}