The Ivy Brasserie in Cambridge is quickly becoming one of my favourite places to eat. Not only is the interior design absolutely gorgeous (and a constant source of inspiration for my new house), but the regular special menus add something new to the food scene in Cambridge. It's somewhere I always recommend if you are looking for something "traditionally British" like many visitors want to experience when they visit Cambridge, which isn't too pricey. This month, to celebrate Isaac Newton's birth month, the Ivy have a launched a "month of Inspiration" to celebrate this Cambridge icon and his history.
Isaac Newton is one of the most famous alumni of Cambridge, who studied at Trinity College and wrote his "Prinicipia Mathematica" during his time there. Trinity College lies just across the road from the Ivy and a cutting from the famous tree in Newton's mother's garden, which inspired his first thoughts on gravity, grows outside . The Ivy have embraced this apple theme with their special menu, dedicated cocktails and an "Inspiration Tree" where you can add your own quotes to the branches in the centre of the restaurant - oh and there's the chance to win prizes too!
As you walk into the restaurant, you are greeted by a giant tree - the Inspiration Tree. The huge branches trail across the walkway to the main restaurant, adorned with golden apples and note tags, tied with string. Some of the note tags are inscribed with hand written inspiration quotes, by famous writers or celebrities, and there is a small table with tags and pens so you can add your own. The interactive hub of inspiration is the perfect way to be greeted before experiencing the month of inspiration, inspired by Isaac Newton's birthday.
As part of the Newton celebrations, the Ivy Cambridge is offering a special "Inspiration Menu" from 11:30-6:30pm Monday to Friday until the 8th February. Two courses are £22, including a Newton inspired cocktail, or you can add another course for £5. I chose two courses and the non-alcoholic Newton cocktail - perfect for those who are driving or taking part in Dry January. The Seedlip Spicy Apple was created with Seedlip Spice, apple juice and star anise and the result is a spicy long drink, with a strong taste of cinnamon. I love the spice, so I enjoyed it, but it may be a little too much for some. As ever, the presentation was perfect and I love that the Ivy Cambridge are always developing their cocktail menu to offer more than traditional cocktails.
For my main, I chose the hoisin-glazed crispy duck leg, served with coriander mashed potatoes, greens and red wine sauce. It arrived steaming hot to the table and perfectly presented. It would have been great to see more apple throughout the menu, not just the cocktails, as I really loved this theme and it would have been fantastic to see how the chef could work apple throughout the courses too. However, my duck was delicious, fell off the bone and the red wine sauce was rich and packed full of flavour.
For dessert, I couldn't resist a bit of chocolate and chose the dark chocolate mousse with raspberries and a salted peanut caramel topping. Again it would have nice to see at least one apple themed dessert, but I will always be a fan of the classic chocolate and raspberries! The mousse was rich and smooth and the tart raspberries cut through the luxurious chocolate. We finished with some coffees, which were absolutely delicious and served impeccably by the staff, who were attentive and friendly throughout our meal. The service is really exceptional every time I visit the Ivy Cambridge and if you want to experience the Ivy but don't have time for a whole meal, I'd highly recommend popping in for a coffee or cocktail to soak up the atmosphere and opulent surroundings.
Finally, we were presented with a beautiful golden apple, which, when opened, revealed a card which could have a prize. Unfortunately it wasn't our lucky night but diners can win a huge variety of prizes, including dinner, afternoon tea or bottles of champagne, so it's another reason to dine there soon!
The "Month of Inspiration" runs until the 8th February and you can take a look at the Ivy Cambridge Inspiration Set Menu online.
I was invited to review The Ivy Cambridge Brasserie in exchange for this review.
Previous Post Will I Still Travel Now I've Bought A House?


#QUARTER TON CLASS – With a decline in big boat sailing here (some say we will be lucky to even field a Commodore's Cup team this year), people are turning to what other classes that are around for competitive and cost effective sailing.
Some one design classes like the 1720 are flourishing again, but some sailors prefer a class that alterations can be made to the boats to suit their sailing styles and weight and the Quarter ton class fits that bill.
The retro class of sailing boats gave a shot in the arm to the two major south-coast regattas last June. Although its heyday was 30 years ago, the revitalised Quarter Ton class in Britain and Ireland, is experiencing a new lease of life. The class competed at both the ICRA Nationals and the Sovereign's Cup.
Up until recently the Quarter tonner Tiger, owned by Neil Kenefick (it made the cover of the Irish Sailing Annual 2012) was the only boat making the running but last year Eamonn Rohan bought "Anchor Challenge" and campaigned it well. At the end of the year he sold it to another Cork sailor Diarmuid Foley.
The budget-minded class has been back building numbers steadily since 2001 when Peter Morton revived the class on the south coast of England.
Representing good value for money there has been a lot of movement in Quarter Ton boat sales. A further two Quarter Tonners have been bought during last summer and are currently in Cowes having a full reconfiguration and updrade. The first is owned by Ian Travers and the second by Jason Losty from Cobh.
In the UK there are a further three boats going through full ugrades and others are changing keels and masts.
The highlight of racing for the class is the Quarter Ton Cup held annually in Cowes. This year's event will be held from June 24th to 27th. These boats are very competitive under IRC as can be seen by Tiger winning class 3 at last year's IRC nationals.
There will be 30 to 35 boats expected for this years Quarter Ton Cup.


Vp plc has posted a year-on-year revenues growth of 22%, to £303.6 million (€345.81 million), for the fiscal year ending 31 March 2018.
The company's earnings before interest, taxes, depreciation and amortization (EBITDA) grew 18% for the period, to £84.3 million (€96 million).
In November last year, Vp acquired fellow UK rental company Brandon Hire in a deal worth £41.6 million (€47.12 million). The deal was agreed between Vp and Brandon's former parent company Wolseley Group, which bought Brandon in 2006.
Vp also took on Brandon's net debt of £27.2 million (€30.81 million), and the company posted a net debt for the year of £179.2 million (€204.12 million), up from £98.9 million (€112.65 million) last year. The company also invested £64.9 million (€73.92 million) in new equipment, contributing to its rise in net debt.
Jeremy Pilkington, chairman of Vp plc, said, "It has been another year of significant progress for the group underpinned by record profits and the acquisition of Brandon Hire, our largest to date. In view of this outstanding set of results, the board is recommending a final dividend of 19.2 pence per share making a total for the year of 26 pence per share, an increase of 18%.
Meanwhile, Neil Stothard, CEO, added, "The start to the new financial year has been positive. We anticipate that our core UK markets will continue to provide a strong platform for future growth to our UK division.


Established recruitment theory suggests without the assistance of a recruiter, a passive candidate must be made aware of a career opportunity at least five times through social media before becoming motivated to apply. This process of allowing a position to percolate through multiple industry channels is a "Hobsons' Choice" approach to targeting talent, and simply takes too long.
Studies indicate that a corporate career portal might take as long as 55 days, while job posting on a social media platform takes 39 days. Our referral based approach rarely exceeds 29 days which translates into a much shorter period to conduct effective on-boarding.
A person's income is generally equal to the average income of a person's five closest friends, so the old adage "birds of a feather flock together" bears some truth. We restrict our referral sources to members of NEXTalent's proprietary networks and known industry professionals.
Participants in NEXTalent's Talent Marketplace and HiP Community recognize the importance of contributing to their business network's success by participating in our peer2peer referral program. They put NEXTalent's clients in front of prospects in their business networks who matter – educated, prepared and primed for success.


text:
class CompanyProject < ActiveRecord::Base
	belong_to :company
	belong_to :project
end

redpajama_set_name: RedPajamaGithub


text:
Q: Why the TableRow is not centered on the screen? I don't understand why, in this code the TableRow appears in the upper left instead of center
HorizontalScrollView HSC = new HorizontalScrollView(this);
ScrollView VSC = new ScrollView(this);
HSC.setBackgroundResource(R.drawable.lavagna);
tableLayout = new TableLayout(this);
tableLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
tableLayout.setGravity(Gravity.CENTER)
for (int i = 0; i < 3; i++){
tableRow = new TableRow(this);
tableRow.setGravity(Gravity.CENTER);
for (int j = 0; j < 3; j++){
values[i][j] = new EditText(this);
values[i][j].setHint("r: " + (i) + " " + "c: " + (j));
values[i][j].setPadding(10, 10, 10, 10);
tableRow.addView(values[i][j]);
}
tableLayout.addView(tableRow);
}
VSC.addView(tableLayout);
HSC.addView(VSC);
setContentView(HSC);
}

A: HorizontalScrollView HSC = new HorizontalScrollView(this);
ScrollView VSC = new ScrollView(this);
VSC.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,  LayoutParams.MATCH_PARENT, Gravity.CENTER));
HSC.setBackgroundResource(R.drawable.lavagna);
tableLayout = new TableLayout(this);
tableLayout.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER));
values = new EditText[15][15];
for (int i = 0; i < 15; i++){
tableRow = new TableRow(this);
tableRow.setGravity(Gravity.CENTER);
for (int j = 0; j < 15; j++){
values[i][j] = new EditText(this);
valo[i][j].setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED | InputType.TYPE_NUMBER_FLAG_DECIMAL);
values[i][j].setHint("r: " + (i) + " " + "c: " + (j));
values[i][j].setPadding(10, 10, 10, 10);
tableRow.addView(valore[i][j]);
}
VSC.addView(tableLayout);
HSC.addView(VSC);
setContentView(HSC);

A: I think after initializing tableLayout object, you should also define its layout parameters.
tableLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
    LayoutParams.WRAP_CONTENT));

redpajama_set_name: RedPajamaStackExchange


text:
Rīga airport taxis still risky, says State Audit Office
Photo: LETA, Zane Bitere
State Audit Office (VK) said October 7 that the situation with taxis at Rīga International Airport is far from ideal and there is still a chance passengers might encounter unfair pricing.
Unfair pricing of taxi service at Rīga International airport has been a long-standing issue, Until 2017, the airport had set criteria for taxis that were permitted to provide services on its territory, and only two companies - Red Cab and Baltic Taxi - met the conditions. However, in 2017, the Competition Council ruled that such a procedure was unacceptable and opened up the market to all firms.
New norms came in force in 2019 to improve service and prevent taxi fraud as tourists are known to have been greatly overcharged.
According to the statement from VK, the State Audit Office only partially agrees with the statement by the airport and the Transport Ministry (SM) that the regulatory framework currently eliminates all problems related to the provision of taxi services at the airport. SM has yet to do "homework" to enable passengers at the airport to choose a safe and appropriate taxi service. For example, the auditors have indicated the possibility under the regulation to pay a taxi service with a prepaid voucher, which is not provided at the moment.
VK said that public transport should be the priority at a modern airport, but the infrastructure of the Rīga airport is designed so that the passenger should consider using a taxi as a priority. The situation should change significantly by building the new passenger terminal and connecting to Rail Baltica. However, taxi services will continue to play an important role in the airport area in the coming years.
The auditors pointed to the need to provide convenient taxi services for passengers who choose taxi services by using electronic means on-line via the website or mobile app. Action should be taken to avoid the risk that outside the taxi line, suppliers of services require a disproportionate fee after the journey from the passenger.
According to VK, the taxi service at the airport is directly linked to the country's reputation.
"This is why, with the reduction in the number of flights and passengers caused by the pandemic, the airport management and the Ministry of Transport should do everything possible to finally put an end to the old story of the taxi "wars" and possible passenger fraud at Riga airport," noted VK.
At the end of the audit, taking into account good practices of foreign airports, the State Audit Office recommended that the airport provide detailed information on the home page regarding carriers entitled to provide services on the airport taxi line, their appropriate tariffs, as well as the risks that passengers, including foreign guests, may face when choosing a taxi service provider.
Riga International Airport
Rīga Airport served 434,000 passengers in November
Rīga Airport revival continues
december 2, 2022, 9:31
Rīga Airport figures in October show continuous upward trend
Construction costs in December up 19%
Latvia's electricity production fell by 14.5% in 2022
Minimum income threshold set to rise regularly in Latvia

redpajama_set_name: RedPajamaCommonCrawl


Valerie Concepcion Returns to GMA-7 and Stars in a New Teleserye!
Valerie Concepcion makes a great comeback in GMA-7! After seven years with the Kapamilya station, Valerie decided to return to the network where her career started.
We may recall that Valerie transferred to ABS-CBN in 2007 after Angel Locsin switch from Kapuso to Kapamilya because she and Angel have the same manager before who was Becky Aguilla.
In the Kapamilya network, Valerie was given a hosting stunt via the defunct noontime show "Wowowee." She even got supporting roles in the afternoon soaps like "Precious Hearts Romances Presents."
Valerie even appeared in different TV5 shows like "Mga Nagbabagang Bulaklak," "Talentadong Pinoy" and "Star Confessions" where she portrayed the role of the late Bella Flores.
In GMA-7 before, Valerie starred in the youth-oriented show "Click" opposite JC De Vera. Now back in her home network, Valerie is set to play 'kontrabida' to the characters of Barbie Forteza, Krystal Reyes and Joyce Ching in the remake of "Anna Karenina!"


text:
/* */
(function(process) {
  'use strict';
  var _extends = Object.assign || function(target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = arguments[i];
      for (var key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          target[key] = source[key];
        }
      }
    }
    return target;
  };
  Object.defineProperty(exports, "__esModule", {value: true});
  var _react = require('react');
  var _react2 = _interopRequireDefault(_react);
  var _reactDom = require('react-dom');
  var _reactDom2 = _interopRequireDefault(_reactDom);
  var _cssEvent = require('../utils/css-event');
  var _cssEvent2 = _interopRequireDefault(_cssEvent);
  var _keyLine = require('../utils/key-line');
  var _keyLine2 = _interopRequireDefault(_keyLine);
  var _keyCode = require('../utils/key-code');
  var _keyCode2 = _interopRequireDefault(_keyCode);
  var _stylePropable = require('../mixins/style-propable');
  var _stylePropable2 = _interopRequireDefault(_stylePropable);
  var _transitions = require('../styles/transitions');
  var _transitions2 = _interopRequireDefault(_transitions);
  var _clickAwayable = require('../mixins/click-awayable');
  var _clickAwayable2 = _interopRequireDefault(_clickAwayable);
  var _paper = require('../paper');
  var _paper2 = _interopRequireDefault(_paper);
  var _menuItem2 = require('./menu-item');
  var _menuItem3 = _interopRequireDefault(_menuItem2);
  var _linkMenuItem = require('./link-menu-item');
  var _linkMenuItem2 = _interopRequireDefault(_linkMenuItem);
  var _subheaderMenuItem = require('./subheader-menu-item');
  var _subheaderMenuItem2 = _interopRequireDefault(_subheaderMenuItem);
  var _getMuiTheme = require('../styles/getMuiTheme');
  var _getMuiTheme2 = _interopRequireDefault(_getMuiTheme);
  var _warning = require('warning');
  var _warning2 = _interopRequireDefault(_warning);
  function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {default: obj};
  }
  function _objectWithoutProperties(obj, keys) {
    var target = {};
    for (var i in obj) {
      if (keys.indexOf(i) >= 0)
        continue;
      if (!Object.prototype.hasOwnProperty.call(obj, i))
        continue;
      target[i] = obj[i];
    }
    return target;
  }
  var NestedMenuItem = _react2.default.createClass({
    displayName: 'NestedMenuItem',
    propTypes: {
      active: _react2.default.PropTypes.bool,
      disabled: _react2.default.PropTypes.bool,
      index: _react2.default.PropTypes.number.isRequired,
      menuItemStyle: _react2.default.PropTypes.object,
      menuItems: _react2.default.PropTypes.array.isRequired,
      onItemTap: _react2.default.PropTypes.func,
      onMouseOut: _react2.default.PropTypes.func,
      onMouseOver: _react2.default.PropTypes.func,
      style: _react2.default.PropTypes.object,
      text: _react2.default.PropTypes.string,
      zDepth: _react2.default.PropTypes.number
    },
    contextTypes: {muiTheme: _react2.default.PropTypes.object},
    childContextTypes: {muiTheme: _react2.default.PropTypes.object},
    mixins: [_clickAwayable2.default, _stylePropable2.default],
    getDefaultProps: function getDefaultProps() {
      return {disabled: false};
    },
    getInitialState: function getInitialState() {
      return {
        muiTheme: this.context.muiTheme || (0, _getMuiTheme2.default)(),
        open: false,
        activeIndex: 0
      };
    },
    getChildContext: function getChildContext() {
      return {muiTheme: this.state.muiTheme};
    },
    componentDidMount: function componentDidMount() {
      this._positionNestedMenu();
      _reactDom2.default.findDOMNode(this).focus();
    },
    componentDidUpdate: function componentDidUpdate() {
      this._positionNestedMenu();
    },
    componentClickAway: function componentClickAway() {
      this._closeNestedMenu();
    },
    getSpacing: function getSpacing() {
      return this.state.muiTheme.rawTheme.spacing;
    },
    getStyles: function getStyles() {
      var styles = {
        root: {
          userSelect: 'none',
          cursor: 'pointer',
          lineHeight: this.getTheme().height + 'px',
          color: this.state.muiTheme.rawTheme.palette.textColor
        },
        icon: {
          float: 'left',
          lineHeight: this.getTheme().height + 'px',
          marginRight: this.getSpacing().desktopGutter
        },
        toggle: {
          marginTop: (this.getTheme().height - this.state.muiTheme.radioButton.size) / 2,
          float: 'right',
          width: 42
        },
        rootWhenHovered: {backgroundColor: this.getTheme().hoverColor},
        rootWhenSelected: {color: this.getTheme().selectedTextColor},
        rootWhenDisabled: {
          cursor: 'default',
          color: this.state.muiTheme.rawTheme.palette.disabledColor
        }
      };
      return styles;
    },
    getTheme: function getTheme() {
      return this.state.muiTheme.menuItem;
    },
    toggleNestedMenu: function toggleNestedMenu() {
      if (!this.props.disabled)
        this.setState({open: !this.state.open});
    },
    isOpen: function isOpen() {
      return this.state.open;
    },
    _positionNestedMenu: function _positionNestedMenu() {
      var el = _reactDom2.default.findDOMNode(this);
      var nestedMenu = _reactDom2.default.findDOMNode(this.refs.nestedMenu);
      nestedMenu.style.left = el.offsetWidth + 'px';
    },
    _openNestedMenu: function _openNestedMenu() {
      if (!this.props.disabled)
        this.setState({open: true});
    },
    _closeNestedMenu: function _closeNestedMenu() {
      this.setState({open: false});
      _reactDom2.default.findDOMNode(this).focus();
    },
    _onParentItemTap: function _onParentItemTap() {
      this.toggleNestedMenu();
    },
    _onMenuItemTap: function _onMenuItemTap(e, index, menuItem) {
      if (this.props.onItemTap)
        this.props.onItemTap(e, index, menuItem);
      this._closeNestedMenu();
    },
    _handleMouseOver: function _handleMouseOver(e) {
      if (!this.props.disabled && this.props.onMouseOver)
        this.props.onMouseOver(e, this.props.index);
    },
    _handleMouseOut: function _handleMouseOut(e) {
      if (!this.props.disabled && this.props.onMouseOut)
        this.props.onMouseOut(e, this.props.index);
    },
    render: function render() {
      var styles = this.getStyles();
      styles = this.mergeStyles(styles.root, this.props.active && !this.props.disabled && styles.rootWhenHovered, {position: 'relative'}, this.props.style);
      var iconCustomArrowDropRight = {
        marginRight: this.getSpacing().desktopGutterMini * -1,
        color: this.state.muiTheme.dropDownMenu.accentColor
      };
      var _props = this.props;
      var index = _props.index;
      var menuItemStyle = _props.menuItemStyle;
      var other = _objectWithoutProperties(_props, ['index', 'menuItemStyle']);
      return _react2.default.createElement('div', {
        ref: 'root',
        style: this.prepareStyles(styles),
        onMouseEnter: this._openNestedMenu,
        onMouseLeave: this._closeNestedMenu,
        onMouseOver: this._handleMouseOver,
        onMouseOut: this._handleMouseOut
      }, _react2.default.createElement(_menuItem3.default, {
        index: index,
        style: menuItemStyle,
        disabled: this.props.disabled,
        iconRightStyle: iconCustomArrowDropRight,
        iconRightClassName: 'muidocs-icon-custom-arrow-drop-right',
        onTouchTap: this._onParentItemTap
      }, this.props.text), _react2.default.createElement(Menu, _extends({}, other, {
        ref: 'nestedMenu',
        menuItems: this.props.menuItems,
        menuItemStyle: menuItemStyle,
        onItemTap: this._onMenuItemTap,
        hideable: true,
        visible: this.state.open,
        onRequestClose: this._closeNestedMenu,
        zDepth: this.props.zDepth + 1
      })));
    }
  });
  var Menu = _react2.default.createClass({
    displayName: 'Menu',
    propTypes: {
      autoWidth: _react2.default.PropTypes.bool,
      hideable: _react2.default.PropTypes.bool,
      menuItemClassName: _react2.default.PropTypes.string,
      menuItemClassNameLink: _react2.default.PropTypes.string,
      menuItemClassNameSubheader: _react2.default.PropTypes.string,
      menuItemStyle: _react2.default.PropTypes.object,
      menuItemStyleLink: _react2.default.PropTypes.object,
      menuItemStyleSubheader: _react2.default.PropTypes.object,
      menuItems: _react2.default.PropTypes.array.isRequired,
      onItemTap: _react2.default.PropTypes.func,
      onItemToggle: _react2.default.PropTypes.func,
      onRequestClose: _react2.default.PropTypes.func,
      onToggle: _react2.default.PropTypes.func,
      selectedIndex: _react2.default.PropTypes.number,
      style: _react2.default.PropTypes.object,
      visible: _react2.default.PropTypes.bool,
      zDepth: _react2.default.PropTypes.number
    },
    contextTypes: {muiTheme: _react2.default.PropTypes.object},
    childContextTypes: {muiTheme: _react2.default.PropTypes.object},
    mixins: [_stylePropable2.default],
    getDefaultProps: function getDefaultProps() {
      return {
        autoWidth: true,
        hideable: false,
        visible: true,
        zDepth: 1,
        onRequestClose: function onRequestClose() {}
      };
    },
    getInitialState: function getInitialState() {
      process.env.NODE_ENV !== "production" ? (0, _warning2.default)(false, 'This menu component is deprecated use menus/menu instead.') : undefined;
      return {
        muiTheme: this.context.muiTheme || (0, _getMuiTheme2.default)(),
        nestedMenuShown: false,
        activeIndex: 0
      };
    },
    getChildContext: function getChildContext() {
      return {muiTheme: this.state.muiTheme};
    },
    componentDidMount: function componentDidMount() {
      var el = _reactDom2.default.findDOMNode(this);
      this._setKeyWidth(el);
      this._renderVisibility();
    },
    componentWillReceiveProps: function componentWillReceiveProps(nextProps, nextContext) {
      var newMuiTheme = nextContext.muiTheme ? nextContext.muiTheme : this.state.muiTheme;
      this.setState({muiTheme: newMuiTheme});
      this._setKeyWidth(_reactDom2.default.findDOMNode(this));
    },
    componentDidUpdate: function componentDidUpdate(prevProps) {
      if (this.props.visible !== prevProps.visible || this.props.menuItems.length !== prevProps.menuItems.length) {
        this._renderVisibility();
      }
    },
    getTheme: function getTheme() {
      return this.state.muiTheme.menu;
    },
    getSpacing: function getSpacing() {
      return this.state.muiTheme.rawTheme.spacing;
    },
    getStyles: function getStyles() {
      var styles = {
        root: {
          backgroundColor: this.getTheme().containerBackgroundColor,
          paddingTop: this.getSpacing().desktopGutterMini,
          paddingBottom: this.getSpacing().desktopGutterMini,
          transition: _transitions2.default.easeOut(null, 'height'),
          outline: 'none !important'
        },
        subheader: {
          paddingLeft: this.state.muiTheme.menuSubheader.padding,
          paddingRight: this.state.muiTheme.menuSubheader.padding
        },
        hideable: {
          overflow: 'hidden',
          position: 'absolute',
          top: 0,
          zIndex: 1
        },
        item: {height: 34}
      };
      return styles;
    },
    _getChildren: function _getChildren() {
      var menuItem = undefined;
      var itemComponent = undefined;
      var isDisabled = undefined;
      var styles = this.getStyles();
      this._children = [];
      this._nestedChildren = [];
      for (var i = 0; i < this.props.menuItems.length; i++) {
        menuItem = this.props.menuItems[i];
        isDisabled = menuItem.disabled === undefined ? false : menuItem.disabled;
        var _menuItem = menuItem;
        var icon = _menuItem.icon;
        var data = _menuItem.data;
        var attribute = _menuItem.attribute;
        var number = _menuItem.number;
        var toggle = _menuItem.toggle;
        var onTouchTap = _menuItem.onTouchTap;
        var other = _objectWithoutProperties(_menuItem, ['icon', 'data', 'attribute', 'number', 'toggle', 'onTouchTap']);
        switch (menuItem.type) {
          case _menuItem3.default.Types.LINK:
            itemComponent = _react2.default.createElement(_linkMenuItem2.default, {
              key: i,
              index: i,
              active: this.state.activeIndex === i,
              text: menuItem.text,
              disabled: isDisabled,
              className: this.props.menuItemClassNameLink,
              style: this.props.menuItemStyleLink,
              payload: menuItem.payload,
              target: menuItem.target
            });
            break;
          case _menuItem3.default.Types.SUBHEADER:
            itemComponent = _react2.default.createElement(_subheaderMenuItem2.default, {
              key: i,
              index: i,
              className: this.props.menuItemClassNameSubheader,
              style: this.mergeStyles(styles.subheader, this.props.menuItemStyleSubheader),
              firstChild: i === 0,
              text: menuItem.text
            });
            break;
          case _menuItem3.default.Types.NESTED:
            var _props2 = this.props;
            var zDepth = _props2.zDepth;
            var other = _objectWithoutProperties(_props2, ['zDepth']);
            itemComponent = _react2.default.createElement(NestedMenuItem, _extends({}, other, {
              ref: i,
              key: i,
              index: i,
              nested: true,
              active: this.state.activeIndex === i,
              text: menuItem.text,
              disabled: isDisabled,
              menuItems: menuItem.items,
              menuItemStyle: this.props.menuItemStyle,
              zDepth: this.props.zDepth,
              onMouseEnter: this._onItemActivated,
              onMouseLeave: this._onItemDeactivated,
              onItemTap: this._onNestedItemTap
            }));
            this._nestedChildren.push(i);
            break;
          default:
            itemComponent = _react2.default.createElement(_menuItem3.default, _extends({}, other, {
              selected: this.props.selectedIndex === i,
              key: i,
              index: i,
              active: this.state.activeIndex === i,
              icon: menuItem.icon,
              data: menuItem.data,
              className: this.props.menuItemClassName,
              style: this.props.menuItemStyle,
              attribute: menuItem.attribute,
              number: menuItem.number,
              toggle: menuItem.toggle,
              onToggle: this.props.onToggle,
              disabled: isDisabled,
              onTouchTap: this._onItemTap,
              onMouseEnter: this._onItemActivated,
              onMouseLeave: this._onItemDeactivated
            }), menuItem.text);
        }
        this._children.push(itemComponent);
      }
      return this._children;
    },
    _setKeyWidth: function _setKeyWidth(el) {
      var menuWidth = '100%';
      if (this.props.autoWidth) {
        el.style.width = 'auto';
        menuWidth = _keyLine2.default.getIncrementalDim(el.offsetWidth) + 'px';
      }
      el.style.width = menuWidth;
    },
    _renderVisibility: function _renderVisibility() {
      if (this.props.hideable) {
        if (this.props.visible)
          this._expandHideableMenu();
        else
          this._collapseHideableMenu();
      }
    },
    _expandHideableMenu: function _expandHideableMenu() {
      var _this = this;
      var el = _reactDom2.default.findDOMNode(this);
      var container = _reactDom2.default.findDOMNode(this.refs.paperContainer);
      var padding = this.getSpacing().desktopGutterMini;
      var height = this._getHiddenMenuHeight(el, padding);
      if (!el.style.transition) {
        el.style.transition = _transitions2.default.easeOut();
      }
      this._nextAnimationFrame(function() {
        container.style.overflow = 'hidden';
        el.style.paddingTop = padding + 'px';
        el.style.paddingBottom = padding + 'px';
        el.style.height = height + 'px';
        el.style.opacity = 1;
        _cssEvent2.default.onTransitionEnd(el, function() {
          if (_this.props.visible)
            container.style.overflow = 'visible';
          el.style.transition = null;
          el.focus();
        });
      });
    },
    _getHiddenMenuHeight: function _getHiddenMenuHeight(el, padding) {
      var height = padding * 2;
      el.style.visibility = 'hidden';
      el.style.height = 'auto';
      height += el.offsetHeight;
      el.style.height = '0px';
      el.style.visibility = 'visible';
      return height;
    },
    _collapseHideableMenu: function _collapseHideableMenu() {
      var el = _reactDom2.default.findDOMNode(this);
      var container = _reactDom2.default.findDOMNode(this.refs.paperContainer);
      var originalOpacity = el.style.opacity;
      if (!el.style.transition && originalOpacity !== '') {
        el.style.transition = _transitions2.default.easeOut();
      }
      this._nextAnimationFrame(function() {
        container.style.overflow = 'hidden';
        el.style.opacity = 0;
        el.style.height = '0px';
        el.style.paddingTop = '0px';
        el.style.paddingBottom = '0px';
        var end = function end() {
          el.style.transition = null;
        };
        if (originalOpacity === '')
          end();
        else
          _cssEvent2.default.onTransitionEnd(el, end);
      });
    },
    _nextAnimationFrame: function _nextAnimationFrame(func) {
      if (window.requestAnimationFrame) {
        return window.requestAnimationFrame(func);
      }
      return setTimeout(func, 16);
    },
    _onNestedItemTap: function _onNestedItemTap(e, index, menuItem) {
      if (this.props.onItemTap)
        this.props.onItemTap(e, index, menuItem);
    },
    _onItemTap: function _onItemTap(e, index) {
      if (this.props.onItemTap)
        this.props.onItemTap(e, index, this.props.menuItems[index]);
    },
    _onItemToggle: function _onItemToggle(e, index, toggled) {
      if (this.props.onItemToggle)
        this.props.onItemToggle(e, index, this.props.menuItems[index], toggled);
    },
    _onItemActivated: function _onItemActivated(e, index) {
      this.setState({activeIndex: index});
    },
    _onItemDeactivated: function _onItemDeactivated(e, index) {
      if (this.state.activeKey === index)
        this.setState({activeIndex: 0});
    },
    _onKeyDown: function _onKeyDown(e) {
      if (!(this.state.open || this.props.visible))
        return;
      var nested = this._children[this.state.activeIndex];
      if (nested && nested.props.nested && this.refs[this.state.activeIndex].isOpen())
        return;
      switch (e.which) {
        case _keyCode2.default.UP:
          this._activatePreviousItem();
          break;
        case _keyCode2.default.DOWN:
          this._activateNextItem();
          break;
        case _keyCode2.default.RIGHT:
          this._tryToggleNested(this.state.activeIndex);
          break;
        case _keyCode2.default.LEFT:
          this._close();
          break;
        case _keyCode2.default.ESC:
          this._close();
          break;
        case _keyCode2.default.TAB:
          this._close();
          return;
        case _keyCode2.default.ENTER:
        case _keyCode2.default.SPACE:
          e.stopPropagation();
          this._triggerSelection(e);
          break;
        default:
          return;
      }
      e.preventDefault();
      e.stopPropagation();
    },
    _activatePreviousItem: function _activatePreviousItem() {
      var active = this.state.activeIndex || 0;
      active = Math.max(active - 1, 0);
      this.setState({activeIndex: active});
    },
    _activateNextItem: function _activateNextItem() {
      var active = this.state.activeIndex || 0;
      active = Math.min(active + 1, this._children.length - 1);
      this.setState({activeIndex: active});
    },
    _triggerSelection: function _triggerSelection(e) {
      var index = this.state.activeIndex || 0;
      this._onItemTap(e, index);
    },
    _close: function _close() {
      this.props.onRequestClose();
    },
    _tryToggleNested: function _tryToggleNested(index) {
      var item = this.refs[index];
      if (item && item.toggleNestedMenu)
        item.toggleNestedMenu();
    },
    render: function render() {
      var styles = this.getStyles();
      return _react2.default.createElement(_paper2.default, {
        ref: 'paperContainer',
        tabIndex: '0',
        onKeyDown: this._onKeyDown,
        zDepth: this.props.zDepth,
        style: this.mergeStyles(styles.root, this.props.hideable && styles.hideable, this.props.style)
      }, this._getChildren());
    }
  });
  exports.default = Menu;
  module.exports = exports['default'];
})(require('process'));


Guidance and advice about ARCP outcomes related to the matrix of educational progression. For information about the possible ARCP outcomes, please visit the main ARCP page.
The Matrix of Educational Progression (ST1-7) is available to all trainees at the start of the academic year and they will be assessed against it at the next ARCP. If a trainee achieves all the standards for that training year as listed in the matrix then they should be issued with an ARCP outcome 1. The Matrix defines the minimum standard required. Trainees are encouraged to exceed these requirements.
It is acknowledged that not all trainees are being assessed at the end of their training year due to the timing of the ARCPs and changes in an individual's anticipated CCT date for a variety of reasons.
Likewise many trainees have an annual ARCP (calendar years) whilst not undertaking 12 months of fulltime training during the time since the last assessment e.g. Less than full time training (LTFT).
In this situation the ARCP panel will judge the progress the trainee has made during, the time period, pro rata against the standards detailed in the Matrix (which describe the standards to be achieved over a 12 month period).
The educational supervisor must confirm that the trainee has met the specific requirements to pass through way points (see below). Alternatively a panel may wish to have a further formal assessment.
An outcome 1 is issued if the trainee has gained the competences and standards for the training year (or part of), as described in the RCOG training matrix.
If there is failure to achieve any standard for that training year then the trainee should not be issued an outcome 1. The determination of which alternative outcome will be made by the ARCP panel with the advice and support of the LETB as appropriate. This document provides the RCOG guidance for the ARCP outcome to be issued for trainees who fail to achieve the standards. The purpose is to provide consistency between deaneries, and within deaneries between ARCP panels.
The issuing of an outcome 2 signifies that the development of specific competences are required, but additional training time is not required. This will enable the Postgraduate Dean (PGD) to ensure that the trainee's next attachment will be appropriate to achieve the necessary training opportunities.
An outcome 2 should not be regarded as a failure by the trainee, but as an opportunity to undertake an educational package that will help the trainee achieve the standard.
An outcome 2 does not alter the CCT date for the trainee. Trainees issued with an outcome 2 at the end of ST5 should usually be allowed to register for ATSMs.
The issuing of an outcome 3 will enable the trainee to obtain specific competencies with additional training time. It should be noted that the total additional training time available to trainees is limited to one year as outlined in the Gold Guide. Exceptionally this additional training time may be extended at the discretion of the PGD, but with an absolute maximum of 2 years within the total duration of the training programme.
For LTFT trainees, should an extension to training be required following the award of Outcome 3, this will be on a pro rata basis if training requirements for progression have not been met. If an extension to training is required following the award of Outcome 3 and the LTFT trainee has failed to progress solely on the basis of exam failure, then an extension to training will be on a fixed-term basis and is not pro rata.
Issuing an outcome 4 means the ARCP panel recommends releasing the trainee from the specialty training programme, following insufficient and sustained lack of progress despite having had up to 1 year of additional training to address concerns.
Outcome 5 is reserved for a very small number of cases where the panel can make no statement about progress or otherwise, since the trainee has supplied either no information or incomplete information to the panel.
The panel should agree what outstanding evidence is required from the trainee and the timescale in which it must be provided to be able to issue an outcome.
If the panel considers that an Outcome 1 is likely on the basis of the evidence available and satisfactory outstanding evidence is received, the panel can give authority to the Chair to issue an Outcome 1. However, if the Chair does not receive the agreed evidence to support an Outcome 1 or if the panel considers that an Outcome 2, 3 or 4 is likely on the basis of the evidence available, then a panel will be reconvened. This reconvened panel could be undertaken "virtually".
There are key Way Points in the curriculum for obstetric and gynaecology trainees when the ARCP process is particularly important. It is particularly important to ensure that trainees are clinically competent to move from junior to middle grade level (ST2-3) and from middle to a senior trainee level (ST5-6).
ST2s should have passed MRCOG Part 1, completed the basic logbook competencies and have the OSATS as listed in the Matrix of Educational Progression, confirming that they have the skills to work 2nd on call in obstetrics and gynaecology. If they have achieved the competencies to work 2nd on call but failed to pass MRCOG Part 1 then the trainee can be allowed to work 2nd on call under the educational plan issued after an outcome 3. Failure to achieve OSATs in Manual Removal of Placenta (MROP) and Fetal Blood Sampling are specific exceptions to this. Please see below for details.
ST5s should have passed MRCOG Part 2 and Part 3; completed the core section of the logbook; completed the basic ultrasound modules, have undertaken all appropriate training as specified in the Matrix of Educational Progression; and have all the OSATS listed in the matrix to show evidence of practical procedures competences required to move to ST6 level. Trainees issued with an outcome 2 at the end of ST5 should be allowed to register for ATSMs. Trainees issued with an outcome 3 should not register for an ATSM until the ARCP panel have agreed that the standards to pass to ST6 have been met.
The ARCP provides a formal process that uses the evidence collected by the trainee, relating to their progress in the training programme.
It should normally be undertaken on at least an annual basis for all trainees in specialty training, and it will enable the trainee, the Postgraduate Dean and employers to document that the competences required are being gained at an appropriate rate and through appropriate experience.
The process may be conducted more frequently if there is a need to deal with performance and progression issues outside the annual review. It is not in itself a means or tool of assessment.
The matrix of educational progression (available at the top of this page) is a useful objective tool for benchmarking trainees. For guidance regarding the ARCP outcome for each of the standards within the matrix, please read the screening for future issues page.


text:
Branding for Startups and Beyond
Presented by Radim Malinic, Founder of Brand Nu
Storytelling has been an integral part of human evolution. For thousands of years, we have used stories to understand to the world and to make sense of it. As a creative, designer or artist, we aim to tell stories through our own work and that for others. However, it can feel intimidating to be bombarded with messages that every designer should be a storyteller.
We all have our unique visions and narratives to tell. This webinar will showcase the behind the scenes of how visual storytelling can be integrated into brand identity creation to achieve visually rich design systems. It hopes to show you the way how to implement these ideas in your own work.
Insight into building visually rich design systems
Use of visual storytelling in branding
Use of diverse research influences
The importance of being a multifaceted creative
How to build teams that pull together
About Radim
Radim is a creative director and designer living and work in London, England. He is the founder of Brand Nu, an award-winning branding and creative studio working across a broad spectrum of clients. From individuals and emerging startups all the way to multinational corporates, Brand Nu combines visually rich design, creativity and strategy in its work for the big brands of the future. Some of his clients include Harry Potter Platform 9/34, 007 Store, Bafta, Coca Cola, Google, Adobe Systems, WWF and USAID, among many others. Before finding his calling in the creative industry, Czech-born Malinic was an ice hockey player, a bassist in death metal bands, an indie DJ, a music journalist and a student of economics and business management. In March 2016, he released his debut publication Book of Ideas, Volume 2 was released in September 2018, and his latest title Book of Branding was just released in November 2019.
Get Webinar Updates by Email
RGD Members receive weekly email updates on RGD Webinars. If you are not a Member but would like to be notified about upcoming webinars, subscribe here.
environmental graphic design
skillsharing


Shrek The Musical, the all-singing, all-dancing, must-see musical comedy, is coming to the King's Theatre Glasgow this Autumn!
Join Shrek, and his loyal steed Donkey as they set off on a quest to rescue the beautiful Princess Fiona from her tower, guarded by a fire breathing love-sick dragon. Add the vertically challenged Lord Farquaad, a gang of fairytale misfits, and a biscuit with attitude, and you've got an irresistible mix of adventure, laughter and romance, guaranteed to delight audiences of all ages!
While we take every opportunity to ensure the details for Shrek The Musical are accurate, we always advise that you contact the event organiser before setting out for the event to avoid disapointment.


text:
A podcast about what crawls from under the rock.
McDonalds, RTÉ & McSecrecy
Episode 2: The Right to Know
Episode 1: The POD
Insurance industry talking points for government minister
New podcast: Adventu… on Episode 1: The POD
Alice on Episode 1: The POD
teddwyercitylife on Episode 1: The POD
FOI News
17 August 2016 Rossa McMahon
Jack Chambers TD is in the news today criticising RTÉ for having McDonalds as sponsor of its Big Big Movie.
Mr Chambers said the national broadcaster could be in breach of its standards, adding that the sponsorship could encourage unhealthy eating habits among children.
"It is remarkable that RTE are allowing McDonald's to sponsor this slot, despite the ban on high-fat, salt and sugary foods during children's programming," he said.
"As their own website details, this programme slot has a quarter-of-a-million viewers including a 31pc average share of viewing for kids.
"Sponsorship can reach 85pc of households with children.
Now, some are already complaining that only a Nanny State would prohibit such sponsorship but it is remarkable for a State owned broadcaster to sell the sponsorship of one of the main child/family television slots in the week to McDonalds.
What has interested me about the story is RTÉ's approach to freedom of information when dealing with the issue. A few months ago, I was watching the Big Big Movie and was surprised to see McDonalds as sponsor.
The @rte Big Big Movie, today Planes, is sponsored by @McDonalds. Is that even allowed?
— Rossa McMahon (@rossamcmahon) April 2, 2016
I suspected it was not allowed. I was interested to see what I could find out about the arrangement so I submitted an FOI request. Here's the sequence.
On 4 April 2016 I requested a copy of all records "relating to the arrangement between RTÉ and McDonalds involving the sponsorship by the latter of the "Big Big Movie" screened by RTÉ on Saturdays weekly".
On 6 April 2016 an acknowledgement letter was sent by RTÉ by email. Strangely, I got that email but it did not appear in my inbox at the time which may have been due to an issue with Gmail. At any rate, it immediately sought an extension to 1 June 2016 on the basis of general workload issues.
Without the extension I should have received a response by 2 May 2016. I hadn't read the extension letter and heard nothing more from RTÉ. The Freedom of Information Act says that if you do not receive a decision from an FOI body your request is deemed to have been refused, and you can seek an internal review.
I wrote to RTÉ on 11 May 2016 seeking an internal review. I received no response.
I submitted an application for review (an appeal) to the Information Commissioner on 15 June 2016. The Commissioner's office essentially treated the application as an opportunity to prod RTÉ, who then issued a decision letter (months late) refusing my request in full.
RTÉ's decision letter provided no schedule or description of the documents they hold (which is standard in FOI decisions). RTÉ decided that every single document they hold relating to the McDonalds sponsorship is exempt from release under FOI because (a) it includes information given in confidence and/or (b) it is commercially sensitive.
It is difficult to see how the "information received in confidence" exemption could apply to this situation. Commercial sensitivity is a frequent basis for refusals and is widely abused by FOI bodies but it is unsurprising to see it invoked by RTÉ. Their reasoning, however, is that their competitors don't have to release commercially sensitive information so they should not. By applying it to every record held though, RTÉ has effectively carved itself out of the FOI legislation.
For now, despite RTÉ failing to deal with the initial request and ignoring it until prodded by the Information Commissioner, I have to again seek an internal review and will be doing so. RTÉ bought themselves at least two months by failing to issue a decision on the request within the statutory timeframe.
Whatever one's views about Nanny States and McDonalds, the level of secrecy RTÉ is attaching to the issue is itself a story.
← Episode 2: The Right to Know
Stay tuned! →


When you create a new FAQ, Friday uses its own built-in default settings to create a new FQA file. If you create new FAQs often, remembering to copy all your customizations to the new FQA file is a nuisance.
You can override Friday's default settings for new FAQs by creating your own defaults file.
From now on when Friday creates a new FAQ, it'll use the contents of this file rather than creating a new FRIDAY.FQA file from its default internal values.
Note that it deletes several entries in the DEFAULT.FQA and warns you what they are -- you'll need to visit the settings dialog to check/re-set them.
Friday also sets the HTML folder back to \HTML off the current FAQ folder.
The same mechanism also applies to MAIN.TPL, ANSWER.TPL and FULLFAQ.TPL.
When creating a new FAQ, Friday checks the Friday folder for these three files.
If it finds them, it copies them to the newly created FAQ rather than creating default templates.


text:
package vtgate

import (
	"context"
	"fmt"
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"vitess.io/vitess/go/mysql"
	"vitess.io/vitess/go/sqltypes"
	"vitess.io/vitess/go/test/endtoend/cluster"
	"vitess.io/vitess/go/test/utils"
)

func TestSelectNull(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	exec(t, conn, "begin")
	exec(t, conn, "insert into t5_null_vindex(id, idx) values(1, 'a'), (2, 'b'), (3, null)")
	exec(t, conn, "commit")

	assertMatches(t, conn, "select id, idx from t5_null_vindex order by id", "[[INT64(1) VARCHAR(\"a\")] [INT64(2) VARCHAR(\"b\")] [INT64(3) NULL]]")
	assertIsEmpty(t, conn, "select id, idx from t5_null_vindex where idx = null")
	assertMatches(t, conn, "select id, idx from t5_null_vindex where idx is null", "[[INT64(3) NULL]]")
	assertMatches(t, conn, "select id, idx from t5_null_vindex where idx is not null order by id", "[[INT64(1) VARCHAR(\"a\")] [INT64(2) VARCHAR(\"b\")]]")
	assertIsEmpty(t, conn, "select id, idx from t5_null_vindex where id IN (null)")
	assertMatches(t, conn, "select id, idx from t5_null_vindex where id IN (1,2,null) order by id", "[[INT64(1) VARCHAR(\"a\")] [INT64(2) VARCHAR(\"b\")]]")
	assertIsEmpty(t, conn, "select id, idx from t5_null_vindex where id NOT IN (1,null) order by id")
	assertMatches(t, conn, "select id, idx from t5_null_vindex where id NOT IN (1,3)", "[[INT64(2) VARCHAR(\"b\")]]")

	exec(t, conn, "delete from t5_null_vindex")
}

func TestDoStatement(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	exec(t, conn, "do 1")
	exec(t, conn, "do 'a', 1+2,database()")
}

func TestShowColumns(t *testing.T) {
	conn, err := mysql.Connect(context.Background(), &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	expected := `[[VARCHAR("id") TEXT("bigint(20)") VARCHAR("NO") VARCHAR("PRI") NULL VARCHAR("")] [VARCHAR("idx") TEXT("varchar(50)") VARCHAR("YES") VARCHAR("") NULL VARCHAR("")]]`
	assertMatches(t, conn, "show columns from `t5_null_vindex` in `ks`", expected)
	assertMatches(t, conn, "SHOW COLUMNS from `t5_null_vindex` in `ks`", expected)
	assertMatches(t, conn, "SHOW columns FROM `t5_null_vindex` in `ks`", expected)
}

func TestShowTables(t *testing.T) {
	conn, err := mysql.Connect(context.Background(), &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	query := "show tables;"
	qr := exec(t, conn, query)

	assert.Equal(t, "information_schema", qr.Fields[0].Database)
	assert.Equal(t, "Tables_in_ks", qr.Fields[0].Name)
}

func TestCastConvert(t *testing.T) {
	conn, err := mysql.Connect(context.Background(), &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	assertMatches(t, conn, `SELECT CAST("test" AS CHAR(60))`, `[[VARCHAR("test")]]`)
}

func TestCompositeIN(t *testing.T) {
	conn, err := mysql.Connect(context.Background(), &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	// clean up before & after
	exec(t, conn, "delete from t1")
	defer exec(t, conn, "delete from t1")

	exec(t, conn, "insert into t1(id1, id2) values(1, 2), (4, 5)")

	// Just check for correct results. Plan generation is tested in unit tests.
	assertMatches(t, conn, "select id1 from t1 where (id1, id2) in ((1, 2))", "[[INT64(1)]]")
}

func TestUnionAll(t *testing.T) {
	conn, err := mysql.Connect(context.Background(), &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	// clean up before & after
	exec(t, conn, "delete from t1")
	exec(t, conn, "delete from t2")
	defer exec(t, conn, "delete from t1")
	defer exec(t, conn, "delete from t2")

	exec(t, conn, "insert into t1(id1, id2) values(1, 1), (2, 2)")
	exec(t, conn, "insert into t2(id3, id4) values(3, 3), (4, 4)")

	// union all between two selectuniqueequal
	assertMatches(t, conn, "select id1 from t1 where id1 = 1 union all select id1 from t1 where id1 = 4", "[[INT64(1)]]")

	// union all between two different tables
	assertMatches(t, conn, "(select id1,id2 from t1 order by id1) union all (select id3,id4 from t2 order by id3)",
		"[[INT64(1) INT64(1)] [INT64(2) INT64(2)] [INT64(3) INT64(3)] [INT64(4) INT64(4)]]")

	// union all between two different tables
	result := exec(t, conn, "(select id1,id2 from t1) union all (select id3,id4 from t2)")
	assert.Equal(t, 4, len(result.Rows))

	// union all between two different tables
	assertMatches(t, conn, "select tbl2.id1 FROM  ((select id1 from t1 order by id1 limit 5) union all (select id1 from t1 order by id1 desc limit 5)) as tbl1 INNER JOIN t1 as tbl2  ON tbl1.id1 = tbl2.id1",
		"[[INT64(1)] [INT64(2)] [INT64(2)] [INT64(1)]]")

	exec(t, conn, "insert into t1(id1, id2) values(3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8)")

	// union all between two selectuniquein tables
	assertMatchesNoOrder(t, conn, "select id1 from t1 where id1 in (1, 2, 3, 4, 5, 6, 7, 8) union all select id1 from t1 where id1 in (1, 2, 3, 4, 5, 6, 7, 8)",
		"[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(5)] [INT64(4)] [INT64(6)] [INT64(7)] [INT64(8)] [INT64(1)] [INT64(2)] [INT64(3)] [INT64(5)] [INT64(4)] [INT64(6)] [INT64(7)] [INT64(8)]]")
}

func TestUnionDistinct(t *testing.T) {
	conn, err := mysql.Connect(context.Background(), &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	// clean up before & after
	exec(t, conn, "delete from t1")
	exec(t, conn, "delete from t2")
	defer func() {
		exec(t, conn, "set workload = oltp")
		exec(t, conn, "delete from t1")
		exec(t, conn, "delete from t2")
	}()

	exec(t, conn, "insert into t1(id1, id2) values (1, 1), (2, 2), (3,3), (4,4)")
	exec(t, conn, "insert into t2(id3, id4) values (2, 3), (3, 4), (4,4), (5,5)")

	for _, workload := range []string{"oltp", "olap"} {
		t.Run(workload, func(t *testing.T) {
			exec(t, conn, "set workload = "+workload)
			assertMatches(t, conn, "select 1 union select null", "[[INT64(1)] [NULL]]")
			assertMatches(t, conn, "select null union select null", "[[NULL]]")
			assertMatches(t, conn, "select * from (select 1 as col union select 2) as t", "[[INT64(1)] [INT64(2)]]")
			assertMatches(t, conn, "select 1 from dual where 1 IN (select 1 as col union select 2)", "[[INT64(1)]]")

			// test with real data coming from mysql
			assertMatches(t, conn, "select id1 from t1 where id1 = 1 union select id1 from t1 where id1 = 5", "[[INT64(1)]]")
			assertMatchesNoOrder(t, conn, "select id1 from t1 where id1 = 1 union select id1 from t1 where id1 = 4", "[[INT64(1)] [INT64(4)]]")
			assertMatchesNoOrder(t, conn, "select id1 from t1 where id1 = 1 union select 452 union select id1 from t1 where id1 = 4", "[[INT64(1)] [INT64(452)] [INT64(4)]]")
			assertMatchesNoOrder(t, conn, "select id1, id2 from t1 union select 827, 452 union select id3,id4 from t2",
				"[[INT64(4) INT64(4)] [INT64(1) INT64(1)] [INT64(2) INT64(2)] [INT64(3) INT64(3)] [INT64(827) INT64(452)] [INT64(2) INT64(3)] [INT64(3) INT64(4)] [INT64(5) INT64(5)]]")
		})
	}
}

func TestUnionAllOlap(t *testing.T) {
	conn, err := mysql.Connect(context.Background(), &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	// clean up before & after
	exec(t, conn, "delete from t1")
	exec(t, conn, "delete from t2")
	defer func() {
		exec(t, conn, "set workload = oltp")
		exec(t, conn, "delete from t1")
		exec(t, conn, "delete from t2")
	}()

	exec(t, conn, "insert into t1(id1, id2) values(1, 1), (2, 2)")
	exec(t, conn, "insert into t2(id3, id4) values(3, 3), (4, 4)")

	exec(t, conn, "set workload = olap")

	// union all between two selectuniqueequal
	assertMatches(t, conn, "select id1 from t1 where id1 = 1 union all select id1 from t1 where id1 = 4", "[[INT64(1)]]")

	// union all between two different tables
	// union all between two different tables
	result := exec(t, conn, "(select id1,id2 from t1 order by id1) union all (select id3,id4 from t2 order by id3)")
	assert.Equal(t, 4, len(result.Rows))

	// union all between two different tables
	result = exec(t, conn, "(select id1,id2 from t1) union all (select id3,id4 from t2)")
	assert.Equal(t, 4, len(result.Rows))

	// union all between two different tables
	result = exec(t, conn, "select tbl2.id1 FROM ((select id1 from t1 order by id1 limit 5) union all (select id1 from t1 order by id1 desc limit 5)) as tbl1 INNER JOIN t1 as tbl2  ON tbl1.id1 = tbl2.id1")
	assert.Equal(t, 4, len(result.Rows))

	exec(t, conn, "set workload = oltp")
	exec(t, conn, "insert into t1(id1, id2) values(3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8)")
	exec(t, conn, "set workload = olap")

	// union all between two selectuniquein tables
	assertMatchesNoOrder(t, conn, "select id1 from t1 where id1 in (1, 2, 3, 4, 5, 6, 7, 8) union all select id1 from t1 where id1 in (1, 2, 3, 4, 5, 6, 7, 8)",
		"[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(5)] [INT64(4)] [INT64(6)] [INT64(7)] [INT64(8)] [INT64(1)] [INT64(2)] [INT64(3)] [INT64(5)] [INT64(4)] [INT64(6)] [INT64(7)] [INT64(8)]]")

}

func TestUnion(t *testing.T) {
	conn, err := mysql.Connect(context.Background(), &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	assertMatches(t, conn, `SELECT 1 UNION SELECT 1 UNION SELECT 1`, `[[INT64(1)]]`)
	assertMatches(t, conn, `SELECT 1,'a' UNION SELECT 1,'a' UNION SELECT 1,'a' ORDER BY 1`, `[[INT64(1) VARCHAR("a")]]`)
	assertMatches(t, conn, `SELECT 1,'z' UNION SELECT 2,'q' UNION SELECT 3,'b' ORDER BY 2`, `[[INT64(3) VARCHAR("b")] [INT64(2) VARCHAR("q")] [INT64(1) VARCHAR("z")]]`)
	assertMatches(t, conn, `SELECT 1,'a' UNION ALL SELECT 1,'a' UNION ALL SELECT 1,'a' ORDER BY 1`, `[[INT64(1) VARCHAR("a")] [INT64(1) VARCHAR("a")] [INT64(1) VARCHAR("a")]]`)
	assertMatches(t, conn, `(SELECT 1,'a') UNION ALL (SELECT 1,'a') UNION ALL (SELECT 1,'a') ORDER BY 1`, `[[INT64(1) VARCHAR("a")] [INT64(1) VARCHAR("a")] [INT64(1) VARCHAR("a")]]`)
	assertMatches(t, conn, `(SELECT 1,'a') ORDER BY 1`, `[[INT64(1) VARCHAR("a")]]`)
	assertMatches(t, conn, `(SELECT 1,'a' order by 1) union (SELECT 1,'a' ORDER BY 1)`, `[[INT64(1) VARCHAR("a")]]`)
}

func TestSavepointInTx(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.Nil(t, err)
	defer conn.Close()

	exec(t, conn, "savepoint a")
	exec(t, conn, "start transaction")
	exec(t, conn, "savepoint b")
	exec(t, conn, "rollback to b")
	exec(t, conn, "release savepoint b")
	exec(t, conn, "savepoint b")
	exec(t, conn, "insert into t1(id1, id2) values(1,1)") // -80
	exec(t, conn, "savepoint c")
	exec(t, conn, "insert into t1(id1, id2) values(4,4)") // 80-
	exec(t, conn, "savepoint d")
	exec(t, conn, "insert into t1(id1, id2) values(2,2)") // -80
	exec(t, conn, "savepoint e")

	// Validate all the data.
	exec(t, conn, "use `ks:-80`")
	assertMatches(t, conn, "select id1 from t1 order by id1", `[[INT64(1)] [INT64(2)]]`)
	exec(t, conn, "use `ks:80-`")
	assertMatches(t, conn, "select id1 from t1 order by id1", `[[INT64(4)]]`)
	exec(t, conn, "use")
	assertMatches(t, conn, "select id1 from t1 order by id1", `[[INT64(1)] [INT64(2)] [INT64(4)]]`)

	_, err = conn.ExecuteFetch("rollback work to savepoint a", 1000, true)
	require.Error(t, err)

	exec(t, conn, "release savepoint d")

	_, err = conn.ExecuteFetch("rollback to d", 1000, true)
	require.Error(t, err)
	assertMatches(t, conn, "select id1 from t1 order by id1", `[[INT64(1)] [INT64(2)] [INT64(4)]]`)

	exec(t, conn, "rollback to c")
	assertMatches(t, conn, "select id1 from t1 order by id1", `[[INT64(1)]]`)

	exec(t, conn, "insert into t1(id1, id2) values(2,2),(3,3),(4,4)")
	assertMatches(t, conn, "select id1 from t1 order by id1", `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)]]`)

	exec(t, conn, "rollback to b")
	assertMatches(t, conn, "select id1 from t1 order by id1", `[]`)

	exec(t, conn, "commit")
	assertMatches(t, conn, "select id1 from t1 order by id1", `[]`)

	exec(t, conn, "start transaction")

	exec(t, conn, "insert into t1(id1, id2) values(2,2),(3,3),(4,4)")
	assertMatches(t, conn, "select id1 from t1 order by id1", `[[INT64(2)] [INT64(3)] [INT64(4)]]`)

	// After previous commit all the savepoints are cleared.
	_, err = conn.ExecuteFetch("rollback to b", 1000, true)
	require.Error(t, err)

	exec(t, conn, "rollback")
	assertMatches(t, conn, "select id1 from t1 order by id1", `[]`)
}

func TestSavepointOutsideTx(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.Nil(t, err)
	defer conn.Close()

	exec(t, conn, "savepoint a")
	exec(t, conn, "savepoint b")

	_, err = conn.ExecuteFetch("rollback to b", 1, true)
	require.Error(t, err)
	_, err = conn.ExecuteFetch("release savepoint a", 1, true)
	require.Error(t, err)
}

func TestSavepointAdditionalCase(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.Nil(t, err)
	defer conn.Close()

	exec(t, conn, "start transaction")
	exec(t, conn, "savepoint a")
	exec(t, conn, "insert into t1(id1, id2) values(1,1)")             // -80
	exec(t, conn, "insert into t1(id1, id2) values(2,2),(3,3),(4,4)") // -80 & 80-
	assertMatches(t, conn, "select id1 from t1 order by id1", `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)]]`)

	exec(t, conn, "rollback to a")
	assertMatches(t, conn, "select id1 from t1 order by id1", `[]`)

	exec(t, conn, "commit")
	assertMatches(t, conn, "select id1 from t1 order by id1", `[]`)

	exec(t, conn, "start transaction")
	exec(t, conn, "insert into t1(id1, id2) values(1,1)") // -80
	exec(t, conn, "savepoint a")
	exec(t, conn, "insert into t1(id1, id2) values(2,2),(3,3)") // -80
	exec(t, conn, "insert into t1(id1, id2) values(4,4)")       // 80-
	assertMatches(t, conn, "select id1 from t1 order by id1", `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)]]`)

	exec(t, conn, "rollback to a")
	assertMatches(t, conn, "select id1 from t1 order by id1", `[[INT64(1)]]`)

	exec(t, conn, "rollback")
	assertMatches(t, conn, "select id1 from t1 order by id1", `[]`)
}

func TestExplainPassthrough(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.Nil(t, err)
	defer conn.Close()

	result := exec(t, conn, "explain select * from t1")
	got := fmt.Sprintf("%v", result.Rows)
	require.Contains(t, got, "SIMPLE") // there is a lot more coming from mysql,
	// but we are trying to make the test less fragile

	result = exec(t, conn, "explain ks.t1")
	require.EqualValues(t, 2, len(result.Rows))
}

func TestXXHash(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.Nil(t, err)
	defer conn.Close()

	exec(t, conn, "insert into t7_xxhash(uid, phone, msg) values('u-1', 1, 'message')")
	assertMatches(t, conn, "select uid, phone, msg from t7_xxhash where phone = 1", `[[VARCHAR("u-1") INT64(1) VARCHAR("message")]]`)
	assertMatches(t, conn, "select phone, keyspace_id from t7_xxhash_idx", `[[INT64(1) VARBINARY("\x1cU^f\xbfyE^")]]`)
	exec(t, conn, "update t7_xxhash set phone = 2 where uid = 'u-1'")
	assertMatches(t, conn, "select uid, phone, msg from t7_xxhash where phone = 1", `[]`)
	assertMatches(t, conn, "select uid, phone, msg from t7_xxhash where phone = 2", `[[VARCHAR("u-1") INT64(2) VARCHAR("message")]]`)
	assertMatches(t, conn, "select phone, keyspace_id from t7_xxhash_idx", `[[INT64(2) VARBINARY("\x1cU^f\xbfyE^")]]`)
	exec(t, conn, "delete from t7_xxhash where uid = 'u-1'")
	assertMatches(t, conn, "select uid, phone, msg from t7_xxhash where uid = 'u-1'", `[]`)
	assertMatches(t, conn, "select phone, keyspace_id from t7_xxhash_idx", `[]`)
}

func TestShowTablesWithWhereClause(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.Nil(t, err)
	defer conn.Close()

	assertMatches(t, conn, "show tables from ks where Tables_in_ks='t6'", `[[VARCHAR("t6")]]`)
	exec(t, conn, "begin")
	assertMatches(t, conn, "show tables from ks where Tables_in_ks='t3'", `[[VARCHAR("t3")]]`)
}

func TestOffsetAndLimitWithOLAP(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()
	defer exec(t, conn, "set workload=oltp;delete from t1")

	exec(t, conn, "insert into t1(id1, id2) values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)")
	assertMatches(t, conn, "select id1 from t1 order by id1 limit 3 offset 2", "[[INT64(3)] [INT64(4)] [INT64(5)]]")
	exec(t, conn, "set workload='olap'")
	assertMatches(t, conn, "select id1 from t1 order by id1 limit 3 offset 2", "[[INT64(3)] [INT64(4)] [INT64(5)]]")
}

func TestSwitchBetweenOlapAndOltp(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	assertMatches(t, conn, "select @@workload", `[[VARBINARY("OLTP")]]`)

	exec(t, conn, "set workload='olap'")

	assertMatches(t, conn, "select @@workload", `[[VARBINARY("OLAP")]]`)

	exec(t, conn, "set workload='oltp'")

	assertMatches(t, conn, "select @@workload", `[[VARBINARY("OLTP")]]`)
}

func TestFoundRowsOnDualQueries(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	exec(t, conn, "select 42")
	assertMatches(t, conn, "select found_rows()", "[[UINT64(1)]]")
}

func TestUseStmtInOLAP(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	queries := []string{"set workload='olap'", "use `ks:80-`", "use `ks:-80`"}
	for i, q := range queries {
		t.Run(fmt.Sprintf("%d-%s", i, q), func(t *testing.T) {
			exec(t, conn, q)
			require.NoError(t, err)
		})
	}
}

func TestInsertStmtInOLAP(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	exec(t, conn, `set workload='olap'`)
	_, err = conn.ExecuteFetch(`insert into t1(id1, id2) values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)`, 1000, true)
	require.Error(t, err)
	assertMatches(t, conn, `select id1 from t1 order by id1`, `[]`)
}

func TestDistinct(t *testing.T) {
	defer cluster.PanicHandler(t)

	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.Nil(t, err)
	defer conn.Close()
	exec(t, conn, "insert into t3(id5,id6,id7) values(1,3,3), (2,3,4), (3,3,6), (4,5,7), (5,5,6)")
	exec(t, conn, "insert into t7_xxhash(uid,phone) values('1',4), ('2',4), ('3',3), ('4',1), ('5',1)")
	exec(t, conn, "insert into aggr_test(id, val1, val2) values(1,'a',1), (2,'A',1), (3,'b',1), (4,'c',3), (5,'c',4)")
	exec(t, conn, "insert into aggr_test(id, val1, val2) values(6,'d',null), (7,'e',null), (8,'E',1)")
	assertMatches(t, conn, "select distinct val2, count(*) from aggr_test group by val2", `[[NULL INT64(2)] [INT64(1) INT64(4)] [INT64(3) INT64(1)] [INT64(4) INT64(1)]]`)
	assertMatches(t, conn, "select distinct id6 from t3 join t7_xxhash on t3.id5 = t7_xxhash.phone", `[[INT64(3)] [INT64(5)]]`)
	exec(t, conn, "delete from t3")
	exec(t, conn, "delete from t7_xxhash")
	exec(t, conn, "delete from aggr_test")
}

func TestCreateIndex(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()
	// Test that create index with the correct table name works
	_, err = conn.ExecuteFetch(`create index i1 on t1 (id1)`, 1000, true)
	require.NoError(t, err)
	// Test routing rules for create index.
	_, err = conn.ExecuteFetch(`create index i2 on ks.t1000 (id1)`, 1000, true)
	require.NoError(t, err)
}

func TestCreateView(t *testing.T) {
	// The test wont work since we cant change the vschema without reloading the vtgate.
	t.Skip()
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()
	defer exec(t, conn, `delete from t1`)
	// Test that create view works and the output is as expected
	exec(t, conn, `create view v1 as select * from t1`)
	exec(t, conn, `insert into t1(id1, id2) values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)`)
	// This wont work, since ALTER VSCHEMA ADD TABLE is only supported for unsharded keyspaces
	exec(t, conn, "alter vschema add table v1")
	assertMatches(t, conn, "select * from v1", `[[INT64(1) INT64(1)] [INT64(2) INT64(2)] [INT64(3) INT64(3)] [INT64(4) INT64(4)] [INT64(5) INT64(5)]]`)
}

func TestVersions(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	qr := exec(t, conn, `select @@version`)
	assert.Contains(t, fmt.Sprintf("%v", qr.Rows), "vitess")

	qr = exec(t, conn, `select @@version_comment`)
	assert.Contains(t, fmt.Sprintf("%v", qr.Rows), "Git revision")
}

func TestFlush(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()
	exec(t, conn, "flush local tables t1, t2")
}

func TestShowVariables(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()
	res := exec(t, conn, "show variables like \"%version%\";")
	found := false
	for _, row := range res.Rows {
		if row[0].ToString() == "version" {
			assert.Contains(t, row[1].ToString(), "vitess")
			found = true
		}
	}
	require.True(t, found, "Expected a row for version in show query")
}

func TestOrderBy(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.Nil(t, err)
	defer conn.Close()
	exec(t, conn, "insert into t4(id1, id2) values(1,'a'), (2,'Abc'), (3,'b'), (4,'c'), (5,'test')")
	exec(t, conn, "insert into t4(id1, id2) values(6,'d'), (7,'e'), (8,'F')")
	// test ordering of varchar column
	assertMatches(t, conn, "select id1, id2 from t4 order by id2 desc", `[[INT64(5) VARCHAR("test")] [INT64(8) VARCHAR("F")] [INT64(7) VARCHAR("e")] [INT64(6) VARCHAR("d")] [INT64(4) VARCHAR("c")] [INT64(3) VARCHAR("b")] [INT64(2) VARCHAR("Abc")] [INT64(1) VARCHAR("a")]]`)
	// test ordering of int column
	assertMatches(t, conn, "select id1, id2 from t4 order by id1 desc", `[[INT64(8) VARCHAR("F")] [INT64(7) VARCHAR("e")] [INT64(6) VARCHAR("d")] [INT64(5) VARCHAR("test")] [INT64(4) VARCHAR("c")] [INT64(3) VARCHAR("b")] [INT64(2) VARCHAR("Abc")] [INT64(1) VARCHAR("a")]]`)

	defer func() {
		exec(t, conn, "set workload = oltp")
		exec(t, conn, "delete from t4")
	}()
	// Test the same queries in streaming mode
	exec(t, conn, "set workload = olap")
	assertMatches(t, conn, "select id1, id2 from t4 order by id2 desc", `[[INT64(5) VARCHAR("test")] [INT64(8) VARCHAR("F")] [INT64(7) VARCHAR("e")] [INT64(6) VARCHAR("d")] [INT64(4) VARCHAR("c")] [INT64(3) VARCHAR("b")] [INT64(2) VARCHAR("Abc")] [INT64(1) VARCHAR("a")]]`)
	assertMatches(t, conn, "select id1, id2 from t4 order by id1 desc", `[[INT64(8) VARCHAR("F")] [INT64(7) VARCHAR("e")] [INT64(6) VARCHAR("d")] [INT64(5) VARCHAR("test")] [INT64(4) VARCHAR("c")] [INT64(3) VARCHAR("b")] [INT64(2) VARCHAR("Abc")] [INT64(1) VARCHAR("a")]]`)
}

func TestSubQueryOnTopOfSubQuery(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()
	defer exec(t, conn, `delete from t1`)

	exec(t, conn, `insert into t1(id1, id2) values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)`)
	exec(t, conn, `insert into t2(id3, id4) values (1, 3), (2, 4)`)

	assertMatches(t, conn, "select id1 from t1 where id1 not in (select id3 from t2) and id2 in (select id4 from t2) order by id1", `[[INT64(3)] [INT64(4)]]`)
}

func TestShowVGtid(t *testing.T) {
	conn, err := mysql.Connect(context.Background(), &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	query := "show global vgtid_executed from ks"
	qr := exec(t, conn, query)
	require.Equal(t, 1, len(qr.Rows))
	require.Equal(t, 2, len(qr.Rows[0]))

	defer exec(t, conn, `delete from t1`)
	exec(t, conn, `insert into t1(id1, id2) values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)`)
	qr2 := exec(t, conn, query)
	require.Equal(t, 1, len(qr2.Rows))
	require.Equal(t, 2, len(qr2.Rows[0]))

	require.Equal(t, qr.Rows[0][0], qr2.Rows[0][0], "keyspace should be same")
	require.NotEqual(t, qr.Rows[0][1].ToString(), qr2.Rows[0][1].ToString(), "vgtid should have changed")
}

func TestShowGtid(t *testing.T) {
	conn, err := mysql.Connect(context.Background(), &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	query := "show global gtid_executed from ks"
	qr := exec(t, conn, query)
	require.Equal(t, 2, len(qr.Rows))

	res := make(map[string]string, 2)
	for _, row := range qr.Rows {
		require.Equal(t, KeyspaceName, row[0].ToString())
		res[row[2].ToString()] = row[1].ToString()
	}

	defer exec(t, conn, `delete from t1`)
	exec(t, conn, `insert into t1(id1, id2) values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)`)
	qr2 := exec(t, conn, query)
	require.Equal(t, 2, len(qr2.Rows))

	for _, row := range qr2.Rows {
		require.Equal(t, KeyspaceName, row[0].ToString())
		gtid, exists := res[row[2].ToString()]
		require.True(t, exists, "gtid not cached for row: %v", row)
		require.NotEqual(t, gtid, row[1].ToString())
	}
}

func TestQueryAndSubQWithLimit(t *testing.T) {
	conn, err := mysql.Connect(context.Background(), &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	exec(t, conn, "insert into t1(id1, id2) values(0,0),(1,1),(2,2),(3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8),(9,9)")
	result := exec(t, conn, `select id1, id2 from t1 where id1 >= ( select id1 from t1 order by id1 asc limit 1) limit 100`)
	assert.Equal(t, 10, len(result.Rows))
}

func TestDeleteAlias(t *testing.T) {
	conn, err := mysql.Connect(context.Background(), &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	exec(t, conn, "delete t1 from t1 where id1 = 1")
	exec(t, conn, "delete t.* from t1 t where t.id1 = 1")
}

func TestFunctionInDefault(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	// set the sql mode ALLOW_INVALID_DATES
	exec(t, conn, `SET sql_mode = 'ALLOW_INVALID_DATES'`)

	_, err = conn.ExecuteFetch(`create table function_default (x varchar(25) DEFAULT (TRIM(" check ")))`, 1000, true)
	// this query fails because mysql57 does not support functions in default clause
	require.Error(t, err)

	// verify that currenet_timestamp and it's aliases work as default values
	exec(t, conn, `create table function_default (
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
dt2 DATETIME DEFAULT CURRENT_TIMESTAMP,
ts3 TIMESTAMP DEFAULT 0,
dt3 DATETIME DEFAULT 0,
ts4 TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP,
dt4 DATETIME DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP,
ts5 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
ts6 TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP,
dt5 DATETIME ON UPDATE CURRENT_TIMESTAMP,
dt6 DATETIME NOT NULL ON UPDATE CURRENT_TIMESTAMP,
ts7 TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
ts8 TIMESTAMP DEFAULT NOW(),
ts9 TIMESTAMP DEFAULT LOCALTIMESTAMP,
ts10 TIMESTAMP DEFAULT LOCALTIME,
ts11 TIMESTAMP DEFAULT LOCALTIMESTAMP(),
ts12 TIMESTAMP DEFAULT LOCALTIME()
)`)
	exec(t, conn, "drop table function_default")

	_, err = conn.ExecuteFetch(`create table function_default (ts TIMESTAMP DEFAULT UTC_TIMESTAMP)`, 1000, true)
	// this query fails because utc_timestamp is not supported in default clause
	require.Error(t, err)

	exec(t, conn, `create table function_default (x varchar(25) DEFAULT "check")`)
	exec(t, conn, "drop table function_default")
}

func TestRenameFieldsOnOLAP(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.NoError(t, err)
	defer conn.Close()

	_ = exec(t, conn, "set workload = olap")
	defer func() {
		exec(t, conn, "set workload = oltp")
	}()

	qr := exec(t, conn, "show tables")
	require.Equal(t, 1, len(qr.Fields))
	assert.Equal(t, `Tables_in_ks`, fmt.Sprintf("%v", qr.Fields[0].Name))
	_ = exec(t, conn, "use mysql")
	qr = exec(t, conn, "select @@workload")
	assert.Equal(t, `[[VARBINARY("OLAP")]]`, fmt.Sprintf("%v", qr.Rows))
}

func assertMatches(t *testing.T, conn *mysql.Conn, query, expected string) {
	t.Helper()
	qr := exec(t, conn, query)
	got := fmt.Sprintf("%v", qr.Rows)
	diff := cmp.Diff(expected, got)
	if diff != "" {
		t.Errorf("Query: %s (-want +got):\n%s", query, diff)
	}
}

func assertMatchesNoOrder(t *testing.T, conn *mysql.Conn, query, expected string) {
	t.Helper()
	qr := exec(t, conn, query)
	actual := fmt.Sprintf("%v", qr.Rows)
	assert.Equal(t, utils.SortString(expected), utils.SortString(actual), "for query: [%s] expected \n%s \nbut actual \n%s", query, expected, actual)
}

func assertIsEmpty(t *testing.T, conn *mysql.Conn, query string) {
	t.Helper()
	qr := exec(t, conn, query)
	assert.Empty(t, qr.Rows, "for query: "+query)
}

func exec(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result {
	t.Helper()
	qr, err := conn.ExecuteFetch(query, 1000, true)
	require.NoError(t, err, "for query: "+query)
	return qr
}


text:
Juan Rodrigues o Rodríguez (nederlandés: , portugués: ; sus datos de nacimiento y muerte son desconocidos) fue un dominicano de linaje portugués y africano, considerado el primer inmigrante en el área que hoy es la ciudad de Nueva York. Moraba en Manhattan desde 1613.

Biografía
Nacido en la antigua Capitanía General de Santo Domingo, era hijo de una africana con un marinero portugués. Por ser políglota (hablaba español, portugués, e inglés) fue convidado por el capitán del barco mercante holandés Jonge Tobias para servir de traductor en un viaje para la colonia inglesa en el Nuevo Mundo. En el verano de 1613, la embarcación holandesa llegó a la isla Lenape, en Manhattan, y Rodrigues rápidamente se integró con el pueblo Lenape, al casarse con una indígena local, y aprendió su lengua algonquina, munsee.

Cuando la embarcación holandesa partió, Rodrigues permaneció en la isla y abrió un puesto comercial con mercaderías que le fueron dadas por el capitán holandés. En 1621, obtuvo del gobierno holandés el monopolio comercial en Nuevos Países Bajos y en 1624, su presencia en la región fue fundamental para el asentamiento de una colonia holandesa en Governors Island.

Homenaje
En octubre de 2012, el Consejo de la Ciudad de Nueva York promulgó una ley que renombró algunas calles de Broadway  como "Juan Rodríguez Way".

Véase también

 Historia de Nueva York (prehistoria-1664)

Referencias
Historia de la Ciudad de Nueva York

Enlaces externos
Juan Rodriguez and the Beginnings of New York City
Inmigración en Estados Unidos

redpajama_set_name: RedPajamaWikipedia


11501074Enter Dull, Holofernes, the Pedant and Nathaniel.
11561080a Crab on the face of Terra, the soyle, the land, the earth.
11601083it was a Bucke of the first head.
12091124rault cald the Deare: the Princesse kild a Pricket.
12131127Holo. I wil somthing affect the letter, for it argues facilitie.
12181131 till now made sore with shooting.
12221135 the people fall a hooting.
12261139 by adding but one more l.
12401153member of the common wealth.
12451158Enter Iaquenetta and the Clowne.
12461159Iaquenetta God giue you good morrow M. Person.
12481161be perst, Which is the one?
12491162Clo. Marrie M. Scholemaster, he that is liklest to a hoggs-(head.
12531165for a Swine: tis prettie, it is well.
12561168I beseech you read it.
12631175race sayes in his, What my soule verses.
12641176Holo. I sir, and very learned.
12651177Nath. Let me heare a staffe, a stauze, a verse, Lege domine.
12681179Ah neuer fayth could hold, yf not to beautie vowed.
12691180Though to my selfe forsworne, to thee Ile faythfull proue.
12721182Studie his byas leaues, and makes his booke thine eyes.
12731183Where all those pleasures liue, that Art would comprehend.
12751184If knowledge be the marke, to know thee shall suffise.
12761185Well learned is that tongue, that well can thee commend.
12771186All ignorant that soule, that sees thee without wonder.
12811189Which not to anger bent, is musique, and sweete fier.
12831191That singes heauens prayse, with such an earthly tong.
12851193accent. Let me superuise the cangenet.
13291233Sir I do inuite you too, you shall not say me nay: pauca verba.


text:
Веласкез има више значења:

 Веласкез
 Веласкез (Идалго дел Парал), насеље у савезној држави Чивава у Мексику
 Веласкез (Акамбаро), насеље у савезној држави Гванахуато у Мексику


Wood Earrings | Pura Vida. ivory wood earrings.
Home › Earrings › Pura Vida. ivory wood earrings.
Very Light Weight. Beautiful Blonde Wood. Ivory Hand Carved Natural Tribal Earrings : Carved Jewelry.
Our earrings and natural organic jewelry are always handmade and fair-trade. crocodile wood earrings.


You want to be involved in our activities?
You want to help needy cancer patients?
You want to raise cancer awareness?
You want to break the taboo about cancer?
If YES, don't wait anymore! Contact us to become an active member in our association.


text:
Home > Muslim News > Europe > UK Pastor: Islam Closer to Christ than Christianity
UK Pastor: Islam Closer to Christ than Christianity
LONDON – A Christian pastor has confirmed that Islamic teachings are closer to the Christ than many churches in the west, following a comparative study into both faiths. "I know some emphases in Islamic teaching come closer to the teaching of Christ and the Bible than some teaching in Western churches," Steve Chalke, pastor and founder of the Oasis charity, told Christian Today. "Ultimately the full interpretation of who Allah/God is can be seen through Jesus," he added, confirming that both faiths worship the same God or Allah. "Islam and Christianity are two very different faiths and there are huge…
Tue 16 February 2016 - 16:58
AboutIslam & News Agencies
Middlesex Muslims Set to Join Xmas Midnight Mass
UK Pastor to AboutIslam: 'Muslims & Christians Worship Same God'
Turkey to Showcase Bible Predicting Prophet Coming
LONDON – A Christian pastor has confirmed that Islamic teachings are closer to the Christ than many churches in the west, following a comparative study into both faiths.
"I know some emphases in Islamic teaching come closer to the teaching of Christ and the Bible than some teaching in Western churches," Steve Chalke, pastor and founder of the Oasis charity, told Christian Today.
"Ultimately the full interpretation of who Allah/God is can be seen through Jesus," he added, confirming that both faiths worship the same God or Allah.
"Islam and Christianity are two very different faiths and there are huge differences between the two."
Chalke comments followed the release of his new book, Radical, in which he explained how he had come to the conclusion "Muslims and Christians worship the same God".
He explained how Christians interpret god in different ways which vary greatly.
"As individuals we all worship different shades of the same God," he said.
"There are Christians who worship a militant, violent God. There are Christians who worship a God who doesn't want women in leadership. There are Christians who worship a God who says if you are gay you will burn in hell. There are Christians who worship a God who does not believe in global warming.
"I don't separate from them even though they have a very different take on God's character from me," he added.
He cited the theologian Miroslav Volf, who took a similar line in his book Allah: A Christian Response.
Describing Islamic beliefs as "very attractive", Chalke insisted there was significant common ground that must be explored.
"If we say Islam is an evil religion and they worship a different God and Christianity is the only way to heaven then we are heading for World War Three," he said.
He added that "tabloid" representations of Islam were permeating the Church.
"If we went into a pub tonight and asked people what Christians believe they would say six-day creationists, anti-gay, anti-abortion, boring, if you die before you're baptised you will go to hell. The tabloid media have led people to misunderstand Christianity and pastors now have to spend half their time de-mythologising Christianity," he said.
"What we don't realise is the media are selling us the same lie about Muslims," he said.
He added: "The problem is we don't know any Muslims. Everyone is scared of Muslims except the one who sits next to them at work".
Muslims believe in Jesus as one of the great Prophets of God and that he is the son of Mary but not the Son of God. He was conceived and born miraculously.
In the Noble Qur'an, Jesus is called "Isa". He is also known as Al-Masih (the Christ) and Ibn Maryam (Son of Mary).
As for his crucifixion, Muslims believe that Jesus was not crucified but was lifted up to heaven.
Muslims believe that Jesus will come back to earth before the end of time to restore peace and order, fight the Anti-Christ (Al-Masih Al-Dajjal) and bring victory for truth and righteousness.
The true followers of Jesus will prevail over those who deny him, misrepresent him and reject him.
MuslimJesus in IslamChristProphet IsaOasis Charity
About AboutIslam & News Agencies
UK Criminalizes Boycotting Israel
UK Ad Urges People to Counter Islamophobia


text:
Mysticism in Modern Times
Curious about Jewish mysticism? Learn about some of the famous thinkers who started the movement and how it has evolved throughout history.
From: My Jewish Learning
By MJL
Today, Jewish mysticism is in many ways integrated into normative Judaism. The Zohar, the classic mystical
commentary, would be included in any post-biblical Jewish canon, 16th century mystic Isaac Luria's concept of tikkun olam (repairing the world) is a hallmark of Jewish theology, and Hasidism—once a controversial movement—is now considered one of Judaism's most traditional factions. Recent developments in academic Jewish studies and contemporary spirituality have brought Jewish mysticism to a position of further prominence.
Academic analysis of Judaism and Jewish history began in earnest in the 19th century. However, the scholars who pioneered this field largely ignored mysticism because it embarrassed them. They embraced academic study because they lived in a culture that privileged the intellect and reason. They believed that mysticism represented the opposite: magic and superstition.
One man changed all of this. Gershom Scholem(1897-1982) ignored these biases and single-handedly established Jewish mysticism as an academic discourse. Scholem unearthed a range of manuscripts on mysticism and established the authorship of the Zohar. His landmark collection of essays, Major Trends in Jewish Mysticism, is the starting point for all scholarship on Jewish mysticism.
In recent years, contemporary scholars have begun to question some of Scholem's theories and findings. Chief among them is Moshe Idel, a professor at the Hebrew University in Jerusalem. In 1988, Idel published: New Perspectives, in which he presents a narrative of kabbalistic history that differs from Scholem's. Idel believes that Scholem ignores the centrality of ecstatic mysticism—including, for example, Abraham Abulafia's attempts at prophecy—in tracing the history of Jewish mysticism. In addition, Idel challenges Scholem's view that the Spanish expulsion was the inspiration for Isaac Luria's kabbalah and that this, in turn, laid the groundwork for the tragic messianic movement of Shabbetai Zevi, which in the middle of the 17th century whipped much of world Jewry into an apocalyptic frenzy.
Aside from historical scholarship, mystical inclinations have permeated the thought of many of the great modern Jewish thinkers. Martin Buber's (1878-1965) philosophy was greatly influenced by Hasidism, and he also wrote a number of books about
figures, philosophy, and folktales. The writings of Abraham Joshua Heschel (1907-1972)—himself a descendant of a Hasidic master, the Apter Rav—is also filled with mystical insight. The philosophies of both Buber and Heschel focus on human relationships with the divine.
Since the 1960s, there has been an increased interest in experiential religion and many people have turned to Jewish mysticism for guidance. Jewish Renewal, a self-described "transdenominational movement grounded in Judaism's prophetic and mystical traditions," merges a concern for social justice with an interest in personal spiritual experience. The movement is based largely on the teachings of Zalman Schachter-Shalomi.
Schachter-Shalomi received his rabbinic ordination from a Lubavitch Hasidic yeshiva, but later became interested in general spirituality. Like those attracted to Eastern religious practice, Schachter-Shalomi and the many rabbis and teachers who consider themselves his students are especially interested in the experiential aspects of religion. Jewish Renewal has embraced many practices associated with the New Age movement, such as meditation and yoga, and put them in a Jewish context.
More traditional Jews have also sought out mystical teachings. Aryeh Kaplan (1934-1983), a physicist and Orthodox rabbi steeped in normative Judaism, played a key role in popularizing the study of Jewish mysticism in the Orthodox community. He wrote commentaries on classic works of kabbalah, like Sefer ha-Bahir, and authored several introductions to practical Jewish mysticism. Kaplan's book Jewish Meditation shows how traditional Jewish prayers can be used for meditative purposes.
In recent years, popularized books about Jewish mysticism have been published by the score, and classes on kabbalah are popping up at community centers and New Age institutes all over the world. Even non-Jews have jumped on the kabbalah bandwagon–Madonna is among its most famous dabblers. The Kabbalah Center, a chain of teaching franchises, with more than 40 locations, describes itself as "the largest, leading educational organization on the wisdom of Kabbalah worldwide". The organization has been the object of a fair amount of criticism and controversy, for its recruitment and teaching methods, the accompanying paraphernalia it sells, and its presentation of kabbalah—which many Jewish leaders and scholars condemn as a distortion of kabbalistic teachings and concepts.


Stella Artois is the first brand to sign up to a new AI-powered mobile ad solution called "Blis Futures". Blis claims the new tool can predict where consumers will go and guarantees new customers in pubs for Stella Artois.
Blis Futures will group like data sets and identify patterns, such as time, in order to predict where consumers will be in the future. Working with Vizeum, Stella Artois is the first global brand to run a campaign using Blis Futures to drive customers into pubs, increase engagement and incite consumers to purchase.
Blis is also introducing a new performance metric, 'Cost Per Visit'. CPV charges advertisers using Blis Futures only if the consumer targeted actually visits the target location, representing a radical shift away from click through rates towards brand performance-based models. Stella Artois has also become the first brand to run a Cost Per Visit (CPV) campaign with Futures, buying successful conversions only.
One Response to "Stella Artois predicts future customers with AI tool from Blis"