text: /**
   * DevExtreme (core/devices.js)
   * Version: 18.2.3
   * Build date: Wed Nov 07 2018
   *
   * Copyright (c) 2012 - 2018 Developer Express Inc. ALL RIGHTS RESERVED
   * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
   */
  "use strict";
  var $ = require("../core/renderer"),
      windowUtils = require("./utils/window"),
      navigator = windowUtils.getNavigator(),
      window = windowUtils.getWindow(),
      extend = require("./utils/extend").extend,
      isPlainObject = require("./utils/type").isPlainObject,
      each = require("./utils/iterator").each,
      Class = require("./class"),
      errors = require("./errors"),
      Callbacks = require("./utils/callbacks"),
      resizeCallbacks = require("./utils/resize_callbacks"),
      EventsMixin = require("./events_mixin"),
      SessionStorage = require("./utils/storage").sessionStorage,
      viewPort = require("./utils/view_port"),
      Config = require("./config");
  var KNOWN_UA_TABLE = {
      iPhone: "iPhone",
      iPhone5: "iPhone",
      iPhone6: "iPhone",
      iPhone6plus: "iPhone",
      iPad: "iPad",
      iPadMini: "iPad Mini",
      androidPhone: "Android Mobile",
      androidTablet: "Android",
      win8: "MSAppHost",
      win8Phone: "Windows Phone 8.0",
      msSurface: "Windows ARM Tablet PC",
      desktop: "desktop",
      win10Phone: "Windows Phone 10.0",
      win10: "MSAppHost/3.0"
  };
  var DEFAULT_DEVICE = {
      deviceType: "desktop",
      platform: "generic",
      version: [],
      phone: false,
      tablet: false,
      android: false,
      ios: false,
      win: false,
      generic: true,
      grade: "A",
      mac: false
  };
  var uaParsers = {
      win: function(userAgent) {
          var isPhone = /windows phone/i.test(userAgent) || userAgent.match(/WPDesktop/),
              isTablet = !isPhone && /Windows(.*)arm(.*)Tablet PC/i.test(userAgent),
              isDesktop = !isPhone && !isTablet && /msapphost/i.test(userAgent);
          if (!(isPhone || isTablet || isDesktop)) {
              return
          }
          var matches = userAgent.match(/windows phone (\d+).(\d+)/i) || userAgent.match(/windows nt (\d+).(\d+)/i),
              version = [];
          if (matches) {
              version.push(parseInt(matches[1], 10), parseInt(matches[2], 10))
          } else {
              matches = userAgent.match(/msapphost(\/(\d+).(\d+))?/i);
              matches && version.push(3 === parseInt(matches[2], 10) ? 10 : 8)
          }
          return {
              deviceType: isPhone ? "phone" : isTablet ? "tablet" : "desktop",
              platform: "win",
              version: version,
              grade: "A"
          }
      },
      ios: function(userAgent) {
          if (!/ip(hone|od|ad)/i.test(userAgent)) {
              return
          }
          var isPhone = /ip(hone|od)/i.test(userAgent),
              matches = userAgent.match(/os (\d+)_(\d+)_?(\d+)?/i),
              version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3] || 0, 10)] : [],
              isIPhone4 = 480 === window.screen.height,
              grade = isIPhone4 ? "B" : "A";
          return {
              deviceType: isPhone ? "phone" : "tablet",
              platform: "ios",
              version: version,
              grade: grade
          }
      },
      android: function(userAgent) {
          if (!/android|htc_|silk/i.test(userAgent)) {
              return
          }
          var isPhone = /mobile/i.test(userAgent),
              matches = userAgent.match(/android (\d+)\.(\d+)\.?(\d+)?/i),
              version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3] || 0, 10)] : [],
              worseThan4_4 = version.length > 1 && (version[0] < 4 || 4 === version[0] && version[1] < 4),
              grade = worseThan4_4 ? "B" : "A";
          return {
              deviceType: isPhone ? "phone" : "tablet",
              platform: "android",
              version: version,
              grade: grade
          }
      }
  };
  var Devices = Class.inherit({
      ctor: function(options) {
          this._window = options && options.window || window;
          this._realDevice = this._getDevice();
          this._currentDevice = void 0;
          this._currentOrientation = void 0;
          this.changed = Callbacks();
          if (windowUtils.hasWindow()) {
              this._recalculateOrientation();
              resizeCallbacks.add(this._recalculateOrientation.bind(this))
          }
      },
      current: function(deviceOrName) {
          if (deviceOrName) {
              this._currentDevice = this._getDevice(deviceOrName);
              this._forced = true;
              this.changed.fire();
              return
          }
          if (!this._currentDevice) {
              deviceOrName = void 0;
              try {
                  deviceOrName = this._getDeviceOrNameFromWindowScope()
              } catch (e) {
                  deviceOrName = this._getDeviceNameFromSessionStorage()
              } finally {
                  if (!deviceOrName) {
                      deviceOrName = this._getDeviceNameFromSessionStorage()
                  }
                  if (deviceOrName) {
                      this._forced = true
                  }
              }
              this._currentDevice = this._getDevice(deviceOrName)
          }
          return this._currentDevice
      },
      real: function() {
          return extend({}, this._realDevice)
      },
      orientation: function() {
          return this._currentOrientation
      },
      isForced: function() {
          return this._forced
      },
      isRippleEmulator: function() {
          return !!this._window.tinyHippos
      },
      _getCssClasses: function(device) {
          var result = [];
          var realDevice = this._realDevice;
          device = device || this.current();
          if (device.deviceType) {
              result.push("dx-device-" + device.deviceType);
              if ("desktop" !== device.deviceType) {
                  result.push("dx-device-mobile")
              }
          }
          result.push("dx-device-" + realDevice.platform);
          if (realDevice.version && realDevice.version.length) {
              result.push("dx-device-" + realDevice.platform + "-" + realDevice.version[0])
          }
          if (devices.isSimulator()) {
              result.push("dx-simulator")
          }
          if (Config().rtlEnabled) {
              result.push("dx-rtl")
          }
          return result
      },
      attachCssClasses: function(element, device) {
          this._deviceClasses = this._getCssClasses(device).join(" ");
          $(element).addClass(this._deviceClasses)
      },
      detachCssClasses: function(element) {
          $(element).removeClass(this._deviceClasses)
      },
      isSimulator: function() {
          try {
              return this._isSimulator || windowUtils.hasWindow() && this._window.top !== this._window.self && this._window.top["dx-force-device"] || this.isRippleEmulator()
          } catch (e) {
              return false
          }
      },
      forceSimulator: function() {
          this._isSimulator = true
      },
      _getDevice: function(deviceName) {
          if ("genericPhone" === deviceName) {
              deviceName = {
                  deviceType: "phone",
                  platform: "generic",
                  generic: true
              }
          }
          if (isPlainObject(deviceName)) {
              return this._fromConfig(deviceName)
          } else {
              var ua;
              if (deviceName) {
                  ua = KNOWN_UA_TABLE[deviceName];
                  if (!ua) {
                      throw errors.Error("E0005")
                  }
              } else {
                  ua = navigator.userAgent
              }
              return this._fromUA(ua)
          }
      },
      _getDeviceOrNameFromWindowScope: function() {
          var result;
          if (windowUtils.hasWindow() && (this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"])) {
              result = this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"]
          }
          return result
      },
      _getDeviceNameFromSessionStorage: function() {
          var sessionStorage = SessionStorage();
          if (!sessionStorage) {
              return
          }
          var deviceOrName = sessionStorage.getItem("dx-force-device");
          try {
              return JSON.parse(deviceOrName)
          } catch (ex) {
              return deviceOrName
          }
      },
      _fromConfig: function(config) {
          var result = extend({}, DEFAULT_DEVICE, this._currentDevice, config),
              shortcuts = {
                  phone: "phone" === result.deviceType,
                  tablet: "tablet" === result.deviceType,
                  android: "android" === result.platform,
                  ios: "ios" === result.platform,
                  win: "win" === result.platform,
                  generic: "generic" === result.platform
              };
          return extend(result, shortcuts)
      },
      _fromUA: function(ua) {
          var config;
          each(uaParsers, function(platform, parser) {
              config = parser(ua);
              return !config
          });
          if (config) {
              return this._fromConfig(config)
          }
          var isMac = /(mac os)/.test(ua.toLowerCase()),
              deviceWithOS = DEFAULT_DEVICE;
          deviceWithOS.mac = isMac;
          return deviceWithOS
      },
      _changeOrientation: function() {
          var $window = $(this._window),
              orientation = $window.height() > $window.width() ? "portrait" : "landscape";
          if (this._currentOrientation === orientation) {
              return
          }
          this._currentOrientation = orientation;
          this.fireEvent("orientationChanged", [{
              orientation: orientation
          }])
      },
      _recalculateOrientation: function() {
          var windowWidth = $(this._window).width();
          if (this._currentWidth === windowWidth) {
              return
          }
          this._currentWidth = windowWidth;
          this._changeOrientation()
      }
  }).include(EventsMixin);
  var devices = new Devices;
  viewPort.changeCallback.add(function(viewPort, prevViewport) {
      devices.detachCssClasses(prevViewport);
      devices.attachCssClasses(viewPort)
  });
  if (!devices.isForced() && "win" === devices.current().platform) {
      devices.current({
          version: [10]
      })
  }
  module.exports = devices;
  module.exports.default = module.exports;
  