{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type DeviceType = 'mobile' | 'tablet' | 'desktop' | 'unknown'\nexport type DeviceOrientation = 'landscape' | 'portrait' | 'unknown'\nexport type DeviceOs =\n  | 'ios'\n  | 'iphone'\n  | 'ipad'\n  | 'ipod'\n  | 'android'\n  | 'blackberry'\n  | 'macos'\n  | 'windows'\n  | 'fxos'\n  | 'meego'\n  | 'television'\n  | 'unknown'\n\nexport type OrientationChangeCallback = (newOrientation: 'landscape' | 'portrait') => void\n\nexport interface Device {\n  macos(): boolean\n  ios(): boolean\n  iphone(): boolean\n  ipod(): boolean\n  ipad(): boolean\n  android(): boolean\n  androidPhone(): boolean\n  androidTablet(): boolean\n  blackberry(): boolean\n  blackberryPhone(): boolean\n  blackberryTablet(): boolean\n  windows(): boolean\n  windowsPhone(): boolean\n  windowsTablet(): boolean\n  fxos(): boolean\n  fxosPhone(): boolean\n  fxosTablet(): boolean\n  meego(): boolean\n  television(): boolean\n  cordova(): boolean\n  nodeWebkit(): boolean\n  mobile(): boolean\n  tablet(): boolean\n  desktop(): boolean\n  portrait(): boolean\n  landscape(): boolean\n  onChangeOrientation(cb: OrientationChangeCallback): void\n  noConflict(): Device\n  type: DeviceType\n  os: DeviceOs\n  orientation: DeviceOrientation\n}\n\ndeclare global {\n  interface Window {\n    device: Device\n  }\n}\n\n// Save the previous value of the device variable.\nconst previousDevice = window.device\n\nconst device = {} as Device\n\nconst changeOrientationList: OrientationChangeCallback[] = []\n\n// Add device as a global object.\nwindow.device = device\n\n// The <html> element.\nconst documentElement = window.document.documentElement\n\n// The client user agent string.\n// Lowercase, so we can use the more efficient indexOf(), instead of Regex\nconst userAgent = window.navigator.userAgent.toLowerCase()\n\n// Detectable television devices.\nconst televisionDevices: string[] = [\n  'googletv',\n  'viera',\n  'smarttv',\n  'internet.tv',\n  'netcast',\n  'nettv',\n  'appletv',\n  'boxee',\n  'kylo',\n  'roku',\n  'dlnadoc',\n  'pov_tv',\n  'hbbtv',\n  'ce-html'\n]\n\n// Private Utility Functions\n// -------------------------\n\n// Check if element exists\nfunction includes(haystack: string, needle: string): boolean {\n  return haystack.indexOf(needle) !== -1\n}\n\n// Simple UA string search\nfunction find(needle: string): boolean {\n  return includes(userAgent, needle)\n}\n\n// Check if documentElement already has a given class.\nfunction hasClass(className: string): RegExpMatchArray | null {\n  return documentElement.className.match(new RegExp(className, 'i'))\n}\n\n// Add one or more CSS classes to the <html> element.\nfunction addClass(className: string): void {\n  let currentClassNames: string | null = null\n  if (!hasClass(className)) {\n    currentClassNames = documentElement.className.replace(/^\\s+|\\s+$/g, '')\n    documentElement.className = `${currentClassNames} ${className}`\n  }\n}\n\n// Remove single CSS class from the <html> element.\nfunction removeClass(className: string): void {\n  if (hasClass(className)) {\n    documentElement.className = documentElement.className.replace(\n      ` ${className}`,\n      ''\n    )\n  }\n}\n\n// Main functions\n// --------------\n\ndevice.macos = function (): boolean {\n  return find('mac')\n}\n\ndevice.ios = function (): boolean {\n  return device.iphone() || device.ipod() || device.ipad()\n}\n\ndevice.iphone = function (): boolean {\n  return !device.windows() && find('iphone')\n}\n\ndevice.ipod = function (): boolean {\n  return find('ipod')\n}\n\ndevice.ipad = function (): boolean {\n  const iPadOS13Up =\n    navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1\n  return find('ipad') || iPadOS13Up\n}\n\ndevice.android = function (): boolean {\n  return !device.windows() && find('android')\n}\n\ndevice.androidPhone = function (): boolean {\n  return device.android() && find('mobile')\n}\n\ndevice.androidTablet = function (): boolean {\n  return device.android() && !find('mobile')\n}\n\ndevice.blackberry = function (): boolean {\n  return find('blackberry') || find('bb10')\n}\n\ndevice.blackberryPhone = function (): boolean {\n  return device.blackberry() && !find('tablet')\n}\n\ndevice.blackberryTablet = function (): boolean {\n  return device.blackberry() && find('tablet')\n}\n\ndevice.windows = function (): boolean {\n  return find('windows')\n}\n\ndevice.windowsPhone = function (): boolean {\n  return device.windows() && find('phone')\n}\n\ndevice.windowsTablet = function (): boolean {\n  return device.windows() && (find('touch') && !device.windowsPhone())\n}\n\ndevice.fxos = function (): boolean {\n  return (find('(mobile') || find('(tablet')) && find(' rv:')\n}\n\ndevice.fxosPhone = function (): boolean {\n  return device.fxos() && find('mobile')\n}\n\ndevice.fxosTablet = function (): boolean {\n  return device.fxos() && find('tablet')\n}\n\ndevice.meego = function (): boolean {\n  return find('meego')\n}\n\ndevice.cordova = function (): boolean {\n  return !!(window as Window & { cordova?: unknown }).cordova && location.protocol === 'file:'\n}\n\ndevice.nodeWebkit = function (): boolean {\n  return typeof (window as Window & { process?: unknown }).process === 'object'\n}\n\ndevice.mobile = function (): boolean {\n  return (\n    device.androidPhone() ||\n    device.iphone() ||\n    device.ipod() ||\n    device.windowsPhone() ||\n    device.blackberryPhone() ||\n    device.fxosPhone() ||\n    device.meego()\n  )\n}\n\ndevice.tablet = function (): boolean {\n  return (\n    device.ipad() ||\n    device.androidTablet() ||\n    device.blackberryTablet() ||\n    device.windowsTablet() ||\n    device.fxosTablet()\n  )\n}\n\ndevice.desktop = function (): boolean {\n  return !device.tablet() && !device.mobile()\n}\n\ndevice.television = function (): boolean {\n  let i = 0\n  while (i < televisionDevices.length) {\n    if (find(televisionDevices[i])) {\n      return true\n    }\n    i++\n  }\n  return false\n}\n\ndevice.portrait = function (): boolean {\n  if (\n    screen.orientation &&\n    Object.prototype.hasOwnProperty.call(window, 'onorientationchange')\n  ) {\n    return includes(screen.orientation.type, 'portrait')\n  }\n  if (\n    device.ios() &&\n    Object.prototype.hasOwnProperty.call(window, 'orientation')\n  ) {\n    return Math.abs(window.orientation as number) !== 90\n  }\n  return window.innerHeight / window.innerWidth > 1\n}\n\ndevice.landscape = function (): boolean {\n  if (\n    screen.orientation &&\n    Object.prototype.hasOwnProperty.call(window, 'onorientationchange')\n  ) {\n    return includes(screen.orientation.type, 'landscape')\n  }\n  if (\n    device.ios() &&\n    Object.prototype.hasOwnProperty.call(window, 'orientation')\n  ) {\n    return Math.abs(window.orientation as number) === 90\n  }\n  return window.innerHeight / window.innerWidth < 1\n}\n\n// Public Utility Functions\n// ------------------------\n\n// Run device.js in noConflict mode,\n// returning the device variable to its previous owner.\ndevice.noConflict = function (): Device {\n  window.device = previousDevice\n  return this\n}\n\n// HTML Element Handling\n// ---------------------\n\n// Insert the appropriate CSS class based on the user agent.\n\nif (device.ios()) {\n  if (device.ipad()) {\n    addClass('ios ipad tablet')\n  } else if (device.iphone()) {\n    addClass('ios iphone mobile')\n  } else if (device.ipod()) {\n    addClass('ios ipod mobile')\n  }\n} else if (device.macos()) {\n  addClass('macos desktop')\n} else if (device.android()) {\n  if (device.androidTablet()) {\n    addClass('android tablet')\n  } else {\n    addClass('android mobile')\n  }\n} else if (device.blackberry()) {\n  if (device.blackberryTablet()) {\n    addClass('blackberry tablet')\n  } else {\n    addClass('blackberry mobile')\n  }\n} else if (device.windows()) {\n  if (device.windowsTablet()) {\n    addClass('windows tablet')\n  } else if (device.windowsPhone()) {\n    addClass('windows mobile')\n  } else {\n    addClass('windows desktop')\n  }\n} else if (device.fxos()) {\n  if (device.fxosTablet()) {\n    addClass('fxos tablet')\n  } else {\n    addClass('fxos mobile')\n  }\n} else if (device.meego()) {\n  addClass('meego mobile')\n} else if (device.nodeWebkit()) {\n  addClass('node-webkit')\n} else if (device.television()) {\n  addClass('television')\n} else if (device.desktop()) {\n  addClass('desktop')\n}\n\nif (device.cordova()) {\n  addClass('cordova')\n}\n\n// Orientation Handling\n// --------------------\n\n// Handle device orientation changes.\nfunction handleOrientation(): void {\n  if (device.landscape()) {\n    removeClass('portrait')\n    addClass('landscape')\n    walkOnChangeOrientationList('landscape')\n  } else {\n    removeClass('landscape')\n    addClass('portrait')\n    walkOnChangeOrientationList('portrait')\n  }\n  setOrientationCache()\n}\n\nfunction walkOnChangeOrientationList(newOrientation: 'landscape' | 'portrait'): void {\n  for (let index = 0; index < changeOrientationList.length; index++) {\n    changeOrientationList[index](newOrientation)\n  }\n}\n\ndevice.onChangeOrientation = function (cb: OrientationChangeCallback): void {\n  if (typeof cb === 'function') {\n    changeOrientationList.push(cb)\n  }\n}\n\n// Detect whether device supports orientationchange event,\n// otherwise fall back to the resize event.\nlet orientationEvent = 'resize'\nif (Object.prototype.hasOwnProperty.call(window, 'onorientationchange')) {\n  orientationEvent = 'orientationchange'\n}\n\n// Listen for changes in orientation.\nwindow.addEventListener(orientationEvent, handleOrientation, false)\n\nhandleOrientation()\n\n// Public functions to get the current value of type, os, or orientation\n// ---------------------------------------------------------------------\n\nfunction findMatch<T extends string>(arr: T[]): T | 'unknown' {\n  for (let i = 0; i < arr.length; i++) {\n    if (device[arr[i] as keyof Device] && typeof device[arr[i] as keyof Device] === 'function' && (device[arr[i] as keyof Device] as () => boolean)()) {\n      return arr[i]\n    }\n  }\n  return 'unknown'\n}\n\ndevice.type = findMatch(['mobile', 'tablet', 'desktop']) as DeviceType\ndevice.os = findMatch([\n  'ios',\n  'iphone',\n  'ipad',\n  'ipod',\n  'android',\n  'blackberry',\n  'macos',\n  'windows',\n  'fxos',\n  'meego',\n  'television'\n]) as DeviceOs\n\nfunction setOrientationCache(): void {\n  device.orientation = findMatch(['portrait', 'landscape']) as DeviceOrientation\n}\n\nsetOrientationCache()\n\nexport default device\n"],"mappings":"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","names":[]}