text: /**
   * Copyright (c) 2015-present, Facebook, Inc.
   * All rights reserved.
   *
   * This source code is licensed under the BSD-style license found in the
   * LICENSE file in the root directory of this source tree. An additional grant
   * of patent rights can be found in the PATENTS file in the same directory.
   *
   * @providesModule resolveAssetSource
   * @flow
   *
   * Resolves an asset into a `source` for `Image`.
   */
  'use strict';
  
  export type ResolvedAssetSource = {
    __packager_asset: boolean,
    width: number,
    height: number,
    uri: string,
    scale: number,
  };
  
  var AssetRegistry = require('AssetRegistry');
  var PixelRatio = require('PixelRatio');
  var Platform = require('Platform');
  var SourceCode = require('NativeModules').SourceCode;
  
  var _serverURL, _offlinePath;
  
  function getDevServerURL() {
    if (_serverURL === undefined) {
      var scriptURL = SourceCode.scriptURL;
      var match = scriptURL && scriptURL.match(/^https?:\/\/.*?\//);
      if (match) {
        // Bundle was loaded from network
        _serverURL = match[0];
      } else {
        // Bundle was loaded from file
        _serverURL = null;
      }
    }
  
    return _serverURL;
  }
  
  function getOfflinePath() {
    if (_offlinePath === undefined) {
      var scriptURL = SourceCode.scriptURL;
      var match = scriptURL && scriptURL.match(/^file:\/\/(\/.*\/)/);
      if (match) {
        _offlinePath = match[1];
      } else {
        _offlinePath = '';
      }
    }
  
    return _offlinePath;
  }
  
  /**
   * Returns the path at which the asset can be found in the archive
   */
  function getPathInArchive(asset) {
    if (Platform.OS === 'android') {
      var assetDir = getBasePath(asset);
      // E.g. 'assets_awesomemodule_icon'
      // The Android resource system picks the correct scale.
      return (assetDir + '/' + asset.name)
        .toLowerCase()
        .replace(/\//g, '_')           // Encode folder structure in file name
        .replace(/([^a-z0-9_])/g, '')  // Remove illegal chars
        .replace(/^assets_/, '');      // Remove "assets_" prefix
    } else {
      // E.g. 'assets/AwesomeModule/icon@2x.png'
      return getOfflinePath() + getScaledAssetPath(asset);
    }
  }
  
  /**
   * Returns an absolute URL which can be used to fetch the asset
   * from the devserver
   */
  function getPathOnDevserver(devServerUrl, asset) {
    return devServerUrl + getScaledAssetPath(asset) + '?platform=' + Platform.OS +
      '&hash=' + asset.hash;
  }
  
  /**
   * Returns a path like 'assets/AwesomeModule'
   */
  function getBasePath(asset) {
    // TODO(frantic): currently httpServerLocation is used both as
    // path in http URL and path within IPA. Should we have zipArchiveLocation?
    var path = asset.httpServerLocation;
    if (path[0] === '/') {
      path = path.substr(1);
    }
    return path;
  }
  
  /**
   * Returns a path like 'assets/AwesomeModule/icon@2x.png'
   */
  function getScaledAssetPath(asset) {
    var scale = pickScale(asset.scales, PixelRatio.get());
    var scaleSuffix = scale === 1 ? '' : '@' + scale + 'x';
    var assetDir = getBasePath(asset);
    return assetDir + '/' + asset.name + scaleSuffix + '.' + asset.type;
  }
  
  function pickScale(scales: Array<number>, deviceScale: number): number {
    // Packager guarantees that `scales` array is sorted
    for (var i = 0; i < scales.length; i++) {
      if (scales[i] >= deviceScale) {
        return scales[i];
      }
    }
  
    // If nothing matches, device scale is larger than any available
    // scales, so we return the biggest one. Unless the array is empty,
    // in which case we default to 1
    return scales[scales.length - 1] || 1;
  }
  
  function resolveAssetSource(source: any): ?ResolvedAssetSource {
    if (typeof source === 'object') {
      return source;
    }
  
    var asset = AssetRegistry.getAssetByID(source);
    if (asset) {
      return assetToImageSource(asset);
    }
  
    return null;
  }
  
  function assetToImageSource(asset): ResolvedAssetSource {
    var devServerURL = getDevServerURL();
    return {
      __packager_asset: true,
      width: asset.width,
      height: asset.height,
      uri: devServerURL ? getPathOnDevserver(devServerURL, asset) : getPathInArchive(asset),
      scale: pickScale(asset.scales, PixelRatio.get()),
    };
  }
  
  module.exports = resolveAssetSource;
  module.exports.pickScale = pickScale;
  