{"version":3,"file":"277057e0a01bbc57430fd181.js?3.6.10.39095fcb9.1720035904389","mappings":"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","sources":["webpack://mono-repo/./packages/core-asset/src/models/asset.js","webpack://mono-repo/./packages/core-asset/src/properties/asset.js"],"sourcesContent":["/**\n * Asset model.\n *\n * @classdesc This model is the client-side representation of the DAM 'assetBean' object, containing all DAM info on an asset.\n * It has a variety of RPC methods for operating on a single asset. The object is quite complete, and not all fields\n * are used for all assets.\n *\n * @class\n * @extends Netx.Model\n */\nimport Base from '@netx/core/lib/netx-model';\nimport {i18n} from '@netx/core/i18n';\nimport {getPrefixedLogger} from '@netx/core-next/instance/logger';\nimport AssetConstituentsCollection from '../collections/assetConstituents';\nimport AssetVersionModel from './assetVersion';\nimport AssetSetModel from './assetSet';\nimport ProgressModel from '@netx/core-app/models/progress';\n\nimport {userInputToExpirationTime} from '@netx/core-asset-expiration/utils/userInputToExpirationTime';\nimport {matrixNames} from '@netx/core-permissions/properties/assetPermissions';\nimport {importTasks} from '../properties/asset';\nimport {types as assetSetTypes} from '../properties/assetSets';\n\nimport {dispatcher} from '@netx/core-next/instance';\nimport {getPreference} from '@netx/core-user-next/utils/getPreference';\n\nimport {checksumEnabled} from '@netx/core-asset-next/enablers';\nimport {getAttribute, getAttributeId} from '@netx/core-attribute/singletons';\nimport {session} from '@netx/core-auth/collections/singleton/session';\nimport {URL} from '@netx/core-next/url';\n\nconst logger = getPrefixedLogger('models/asset');\n\nexport default class Asset extends Base {\n\t/**\n\t * @type {Netx.Rpc}\n\t * @private\n\t */\n\tget rpc() {\n\t\treturn true;\n\t}\n\n\t/** @type {string} */\n\tget idAttribute() {\n\t\treturn 'assetId';\n\t}\n\n\tget titleAttribute() {\n\t\treturn 'name';\n\t}\n\n\t/** @type {boolean} */\n\tget xhrTrackProgress() {\n\t\treturn true;\n\t}\n\n\t/** @type {array} */\n\tget xhrExcludeProgress() {\n\t\treturn ['recordViewed'];\n\t}\n\n\t/**\n\t * @property {object} defaults - The default attribute values\n\t * @property {number} defaults.assetId - ID\n\t * @property {string} defaults.alphsChannel - Alpha channel\n\t * @property {array} defaults.attributeIds - Attribute IDs\n\t * @property {array} defaults.attributeNames - Attribute names\n\t * @property {array} defaults.attributeValues - Attribute values\n\t * @property {number} defaults.bitDepth - Bit depth\n\t * @property {array} defaults.categories - Category IDs\n\t * @property {number} defaults.categoryid - Primary category ID\n\t * @property {array} defaults.categoryPaths - Category paths\n\t * @property {number} defaults.checkout - If checked out, ID of user who checked it out\n\t * @property {string} defaults.checkoutUserLabel - Name of user that has this asset currently checked out\n\t * @property {string} defaults.colorProfile - Color profile\n\t * @property {array} defaults.constituentIds - Array of ids for all of the assets constituents\n\t * @property {string} defaults.constituentType - Type of constituent the asset has (keyframes, pages, layers)\n\t * @property {string} defaults.creationDate - Creation date (YYYY-MM-DD hh:mm:ss)\n\t * @property {string} defaults.description - Description\n\t * @property {number} defaults.dpi - DPI\n\t * @property {number} defaults.duration - Audio/video duration (seconds)\n\t * @property {number} defaults.expirationDate - Expiration date (Unix timestamp)\n\t * @property {string} defaults.file - Filename\n\t * @property {array} defaults.fileFormatFamily - File format families (types)\n\t * @property {number} defaults.fileheight - File height (pixels)\n\t * @property {number} defaults.filesize - Deprecated. See `fileSize2`\n\t * @property {number} defaults.fileSize2 - File size in bytes\n\t * @property {number} defaults.fileType - ID of file format type\n\t * @property {string} defaults.fileTypeLabel - File type name (usually the file extension)\n\t * @property {number} defaults.filewidth - File width (pixels)\n\t * @property {boolean} defaults.flvAvailable - FLV preview is available\n\t * @property {string} defaults.geoLocationLabel - Geo location label\n\t * @property {boolean} defaults.hasChildren - Deprecated\n\t * @property {number} defaults.hidden - Controls visibility of assets in search results if the asset is part of a group of related assets (this is a way to only show one asset from a group of related assets in search results)\n\t * @property {string} defaults.importDate - Import date (YYYY-MM-DD hh:mm:ss)\n\t * @property {string} defaults.importUserLabel - Name of user that imported this asset\n\t * @property {boolean} defaults.inCurrentCart - In current cart (selection)\n\t * @property {number} defaults.latitude - Latitude (gelocation)\n\t * @property {number} defaults.locationid - Storage location ID\n\t * @property {string} defaults.locationContext - Description of storage location\n\t * @property {number} defaults.longitude - Longitude (gelocation)\n\t * @property {string} defaults.moddate - Modification date (YYYY-MM-DD hh:mm:ss)\n\t * @property {number} defaults.moduserid - ID of last user to modify the asset\n\t * @property {string} defaults.moduserlabel - Name of last user to modify the asset\n\t * @property {string} defaults.name - Name\n\t * @property {string} defaults.path - Path and filename of the asset in the repository\n\t * @property {number} defaults.parentId - Deprecated\n\t * @property {array} defaults.permissionMatrix - Assets permission matrix -- see {module:permissions/properties/assetPermissions#matrixNames} for the 6 permission types\n\t * @property {number} defaults.previewHeight - Preview height (pixels)\n\t * @property {string} defaults.previewUrl - Relative URL of preview image\n\t * @property {number} defaults.previewWidth - Preview width (pixels)\n\t * @property {boolean} defaults.proofAvailable - Proofs available for the asset\n\t * @property {number} defaults.rating - Rating (range is 1 - 100)\n\t * @property {boolean} defaults.readOnly - Flag indicating whether the asset is read only\n\t * @property {boolean} defaults.relatedAvailable - Related assets are available\n\t * @property {number} defaults.repurposeAvailability - Repurpose availability flag\n\t * @property {boolean} defaults.reviewAvailable - Reviews available for the asset\n\t * @property {number} defaults.statDeliveries - Number of times asset has been downloaded (as defined in Statistics Module)\n\t * @property {number} defaults.statPreviews - Number of times asset has been viewed (as defined in Statistics Module)\n\t * @property {number} defaults.status - Indicates availability of asset file\n\t * @property {string} defaults.thumbUrl - Relative URL of thumbnail image\n\t * @property {number} defaults.timeScale - Frames per second\n\t * @property {array} defaults.versionIds - An array of version ids, for any/all versions of the asset\n\t * @property {array} defaults.viewIds - Array of ids for all of the views belonging to the asset\n\t * @property {array} defaults.viewNames - Array of names of all of the views belonging to the asset\n\t * @property {number} defaults.visible - Visibility flag (1 indicates visible). If set to 0, the asset will only be seen by admins, regardless of permissions\n\t * @property {boolean} defaults.zoomAvailable - Zoom image is available\n\t *\n\t * @property {boolean} defaults.activatingTemplate - Activating template (adBuilder)\n\t * @property {string} defaults.audioUrl - If asset is of type audio, this is the url to the audio (client only)\n\t * @property {boolean} defaults.deactivatingTemplate - Deactivating template (adBuilder)\n\t * @property {boolean} defaults.templatable\t\t\t\t\t\t - Indicates whether asset can be activated as a template\n\t * @property {boolean} defaults.template - adBuilder template\n\t * @property {boolean} defaults.templateCustomizable - adBuilder template customizable\n\t * @property {string} defaults.videoUrl - Video URL (client only)\n\t * @property {string} defaults.zoomUrl - Zoom image (not to be mistaken for zoom tiles) (client only)\n\t */\n\tget defaults() {\n\t\treturn {\n\t\t\t// assetId: 0,\n\t\t\talphaChannel: '',\n\t\t\t// metadata is stored in these three parallel arrays\n\t\t\tattributeIds: [],\n\t\t\tattributeNames: [],\n\t\t\tattributeValues: [],\n\t\t\tbitDepth: 0,\n\t\t\tcategories: [],\n\t\t\tcategoryid: 0,\n\t\t\tcategoryPaths: [],\n\t\t\tcheckout: 0,\n\t\t\tcheckoutUserLabel: '',\n\t\t\tcolorProfile: '',\n\t\t\tconstituentIds: [],\n\t\t\tconstituentType: '',\n\t\t\tcreationdate: '',\n\t\t\tdescription: '',\n\t\t\tdpi: 0,\n\t\t\tduration: 0,\n\t\t\texpirationDate: 0,\n\t\t\tfile: '',\n\t\t\tfileFormatFamily: [],\n\t\t\tfileheight: 0,\n\t\t\tfileSize2: 0,\n\t\t\tfiletype: 0,\n\t\t\tfiletypelabel: '',\n\t\t\tfilewidth: 0,\n\t\t\tflvPreview: false,\n\t\t\tgeoLocationLabel: '',\n\t\t\timportDate: '',\n\t\t\timportUserLabel: '',\n\t\t\tinCurrentCart: false,\n\t\t\tlatitude: 0.0,\n\t\t\tlocationContext: '',\n\t\t\tlocationid: 0,\n\t\t\tlongitude: 0.0,\n\t\t\tmoddate: '',\n\t\t\tmoduserid: 0,\n\t\t\tmoduserlabel: '',\n\t\t\tname: '',\n\t\t\tpath: '',\n\t\t\tpermissionMatrix: [1, 1, 1, 1, 1, 1],\n\t\t\tpreviewHeight: 0,\n\t\t\tpreviewUrl: '',\n\t\t\tpreviewWidth: 0,\n\t\t\tproofAvailable: false,\n\t\t\trating: 0,\n\t\t\treadOnly: 0,\n\t\t\trelatedAvailable: false,\n\t\t\trepurposeAvailability: 0,\n\t\t\treviewAvailable: false,\n\t\t\tstatDeliveries: 0,\n\t\t\tstatPreviews: 0,\n\t\t\tstatus: 0,\n\t\t\ttemplatable: false,\n\t\t\ttemplateCustomizable: false,\n\t\t\tthumbUrl: '',\n\t\t\tversionIds: [],\n\t\t\tviewIds: [],\n\t\t\tviewNames: [],\n\t\t\tvisible: 1,\n\t\t\txmpPacketStatus: 300,\n\t\t\tzoomAvailable: false,\n\n\t\t\t// Deprecated fields -- do not use!\n\t\t\timageid: 0,\n\t\t\tmetadata: '',\n\t\t\tattribute1: '',\n\t\t\tattribute2: '',\n\t\t\tattribute3: '',\n\t\t\tattribute4: '',\n\t\t\tattribute5: '',\n\t\t\tattribute6: '',\n\t\t\tattribute7: '',\n\t\t\tattribute8: '',\n\t\t\tattribute9: '',\n\t\t\tattribute10: '',\n\t\t\tattribute11: '',\n\t\t\tattribute12: '',\n\t\t\tattribute13: '',\n\t\t\tattribute14: '',\n\t\t\tattribute15: '',\n\t\t\tattribute16: '',\n\t\t\thasChildren: false,\n\t\t\tparentId: 0,\n\n\t\t\t// Client attributes\n\t\t\tactivatingTemplate: false,\n\t\t\tdeactivatingTemplate: false,\n\t\t\taudioUrl: '',\n\t\t\tvideoUrl: '',\n\t\t\tzoomUrl: '',\n\t\t};\n\t}\n\t/**\n\t * @type {array}\n\t */\n\tget clientAttrs() {\n\t\treturn [\n\t\t\t'activatingTemplate',\n\t\t\t'audioUrl',\n\t\t\t'customThumbnailFile',\n\t\t\t'progress',\n\t\t\t'thumbnailUpdating',\n\t\t\t'videoUrl',\n\t\t\t'zoomUrl',\n\t\t];\n\t}\n\n\t/**\n\t * The following RPC methods cause the DAM to operate on the asset described in the model.\n\t * All manipulation takes place in the DAM; the browser does not directly manipulate image\n\t * data, files or the database.\n\t * @rpcs\n\t */\n\tget methods() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * fetch(): load the asset described by 'assetId' from the DAM\n\t\t\t * api method: getAssetBean\n\t\t\t * @method fetch\n\t\t\t */\n\t\t\tread: ['getAssetBean', 'assetId'],\n\t\t\t/**\n\t\t\t * @method\n\t\t\t * @param {Object} opts Backbone options object, passed to the internal persistence methods.\n\t\t\t */\n\t\t\tupdate(opts) {\n\t\t\t\treturn ['setAsset', this.self()];\n\t\t\t},\n\t\t\t/**\n\t\t\t * destroy(): delete this asset from the DAM.\n\t\t\t * api method: deleteAsset\n\t\t\t * @method destroy\n\t\t\t */\n\t\t\tremove: ['deleteAsset', 'assetId', 'deleteWait'],\n\t\t\t/**\n\t\t\t * This works for both expiring and unexpiring\n\t\t\t * Unexpireing just means setting 0 on expirationDate\n\t\t\t * @method\n\t\t\t */\n\t\t\texpireAsset: ['expireAsset', 'assetId', 'expirationDate'],\n\t\t\t/**\n\t\t\t * Import a previously uploaded asset to the DAM\n\t\t\t * @method\n\t\t\t */\n\t\t\timportAsset: [\n\t\t\t\t'importAsset2',\n\t\t\t\t'file',\n\t\t\t\t'categoryid',\n\t\t\t\t'locationid',\n\t\t\t\t'importAttributes',\n\t\t\t],\n\t\t\t/*\n\t\t\t * reserve: reserve an asset ID from the DAM for an asset to be imported.\n\t\t\t * api method: reserveAssetIds\n\t\t\t * NOTE: not tested. Use Netx.Collections.Assets.reserve() instead, to reserve N asset IDs at a time.\n\t\t\t * @private\n\t\t\t * @method\n\t\t\t */\n\t\t\treserve: ['reserveAssetIds', 1],\n\t\t\t/**\n\t\t\t * addCategory: add this asset to a DAM category.\n\t\t\t * api method: setAssetCategoryLink\n\t\t\t * @method\n\t\t\t * @todo We do not get back an error response, just a boolean\n\t\t\t */\n\t\t\taddCategory(opts) {\n\t\t\t\tconst d = new $.Deferred();\n\t\t\t\tthis.setAssetCategoryLink(_.extend({}, opts, {link: true})).then(\n\t\t\t\t\t(response) => {\n\t\t\t\t\t\tresponse\n\t\t\t\t\t\t\t? d.resolveWith(this, [response])\n\t\t\t\t\t\t\t: d.reject(new Error(i18n.t('assetAddToCategoryError')));\n\t\t\t\t\t},\n\t\t\t\t\td.reject,\n\t\t\t\t);\n\t\t\t\treturn d.promise();\n\t\t\t},\n\t\t\t/**\n\t\t\t * removeCategory: remove this asset from a DAM category.\n\t\t\t * api method: setAssetCategoryLink\n\t\t\t * @method\n\t\t\t * @todo We do not get back an error response, just a boolean\n\t\t\t */\n\t\t\tremoveCategory(opts) {\n\t\t\t\tconst d = new $.Deferred();\n\t\t\t\tthis.setAssetCategoryLink(_.extend({}, opts, {link: false})).then(\n\t\t\t\t\t(response) => {\n\t\t\t\t\t\tresponse\n\t\t\t\t\t\t\t? d.resolveWith(this, [response])\n\t\t\t\t\t\t\t: d.reject(new Error(i18n.t('assetRemoveFromCategoryError')));\n\t\t\t\t\t},\n\t\t\t\t\td.reject,\n\t\t\t\t);\n\t\t\t\treturn d.promise();\n\t\t\t},\n\t\t\t/**\n\t\t\t * setAssetCategoryLink: add/remove this asset to/from a DAM category.\n\t\t\t * api method: setAssetCategoryLink\n\t\t\t * @method\n\t\t\t * @todo determine & describe the default collision strategy here.\n\t\t\t * @todo explain what happens when you remove the last category from an asset\n\t\t\t * @todo We do not get back an error response, just a boolean\n\t\t\t */\n\t\t\tsetAssetCategoryLink(opts) {\n\t\t\t\treturn [\n\t\t\t\t\t'setAssetCategoryLink',\n\t\t\t\t\tthis.id,\n\t\t\t\t\tthis.linkCategory,\n\t\t\t\t\topts.link || false,\n\t\t\t\t];\n\t\t\t},\n\t\t\t/**\n\t\t\t * setCategory: place the asset in exactly one (specified) category, removing it from all others. (Alias of setCategories())\n\t\t\t * api method: setAssetCategories\n\t\t\t * @method\n\t\t\t */\n\t\t\tsetCategory(opts) {\n\t\t\t\treturn [\n\t\t\t\t\t'setAssetCategories',\n\t\t\t\t\tthis.id,\n\t\t\t\t\t[this.linkCategory],\n\t\t\t\t\t'collisionStrategy.rename',\n\t\t\t\t];\n\t\t\t},\n\t\t\t/**\n\t\t\t * setCategories: place the asset in exactly the specified list of categories, removing it from all others.\n\t\t\t * api method: setAssetCategories\n\t\t\t * @method\n\t\t\t */\n\t\t\tsetCategories: [\n\t\t\t\t'setAssetCategories',\n\t\t\t\t'assetId',\n\t\t\t\t'linkCategories',\n\t\t\t\t'collisionStrategy.rename',\n\t\t\t],\n\t\t\t/**\n\t\t\t * repurpose: run a preset repurposing algorithm on this asset. (When finished, use the Sharing architecture to get the result.)\n\t\t\t * api method: repurposeAssetsWithPresetProcess\n\t\t\t * @method\n\t\t\t */\n\t\t\trepurpose(opts) {\n\t\t\t\treturn [\n\t\t\t\t\t'repurposeAssetsWithPresetProcess',\n\t\t\t\t\t[this.id],\n\t\t\t\t\t'repurposeOtherIds',\n\t\t\t\t\t'repurposeId',\n\t\t\t\t\t'repurposeDownloadOverride',\n\t\t\t\t];\n\t\t\t},\n\t\t\t/**\n\t\t\t * @method\n\t\t\t */\n\t\t\tmanualRepurpose(opts) {\n\t\t\t\treturn [\n\t\t\t\t\t'repurposeAssets',\n\t\t\t\t\t[this.id],\n\t\t\t\t\tthis.repurposeOtherIds,\n\t\t\t\t\tthis.repurposeMethods,\n\t\t\t\t\tthis.repurposeValues,\n\t\t\t\t];\n\t\t\t},\n\t\t\t/**\n\t\t\t * resync: resync this asset in the DAM\n\t\t\t * DAM-5726\n\t\t\t * api method: batchResyncAssets\n\t\t\t * @method resync\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tresync(opts) {\n\t\t\t\t//rpc needs an *array* of ids (single in this case)\n\t\t\t\treturn ['batchResyncAssets', [this.id], 'all'];\n\t\t\t},\n\t\t\t/*\n\t\t\t * @deprecated\n\t\t\t * assetInCurrentCart: tests if this asset is in the current cart.\n\t\t\t * api method: assetsInCurrentCart\n\t\t\t * @method\n\t\t\t * @private\n\t\t\t *\n\t\t\t * @todo this method has no parser and appears unused, perhaps untested ... deprecate?\n\t\t\t * miniAssets have an inCurrentCart attribute from the DAM, which we use instead of this method.\n\t\t\t * We also flip it manually when adding items to the cart (or we should).\n\t\t\t * This method might actually have some purpose on a miniAsset, but it's here instead ... my bad, I'm sure ...\n\t\t\t */\n\t\t\tassetInCurrentCart(opts) {\n\t\t\t\treturn ['assetsInCurrentCart', [this.id]];\n\t\t\t},\n\t\t\t/**\n\t\t\t * getCarts: returns a set of savedCart objects representing the saved carts in the DAM which\n\t\t\t * contain this asset.\n\t\t\t * api method: getCartsForAsset\n\t\t\t * @deprecated\n\t\t\t * @method\n\t\t\t */\n\t\t\t_getCarts: ['getCartsForAsset', 'assetId'],\n\t\t\t/**\n\t\t\t * checkout: 'checks out' the asset, manipulating its state in various ways, and prepares a download of the asset file.\n\t\t\t * api method: checkoutAsset\n\t\t\t * @method\n\t\t\t */\n\t\t\tcheckout: ['checkoutAsset', 'assetId'],\n\t\t\t/**\n\t\t\t * cancelCheckout: checks-in without file\n\t\t\t * api method: checkinAsset\n\t\t\t * @method\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tcancelCheckout(opts) {\n\t\t\t\treturn ['checkinAsset', this.id, this.get('file'), '', true];\n\t\t\t},\n\t\t\t/**\n\t\t\t * checkPendingTasks: track the DAM tasks that fire on asset import\n\t\t\t * @method\n\t\t\t */\n\t\t\tcheckPendingTasks: ['getImportPendingTasks', 'assetId'],\n\t\t\t/**\n\t\t\t * checkStatus: check the status of various import tasks.\n\t\t\t */\n\t\t\tcheckStatus: ['getMessage', 'messageType', 'assetId', 'objectContext'],\n\n\t\t\t/** @todo this method does nothing, because it has no parser. Remove? The constituents are normally fetched by Netx.asset.current.constituents ... */\n\t\t\tgetConstituents: ['getConstituentObjectsForAsset', 'assetId'],\n\t\t\t/**\n\t\t\t * Gets the process list (repurpose) for this asset\n\t\t\t */\n\t\t\tgetProcessListForUser: ['getProcessListForUser', 'assetId'],\n\t\t\t/**\n\t\t\t * recordViewed: tell the DAM statistics package that this asset was viewed once.\n\t\t\t * api method: recordAssetView\n\t\t\t * @method\n\t\t\t */\n\t\t\trecordViewed: ['recordAssetView', 'assetId'],\n\t\t\t/**\n\t\t\t * makeZoomTiles: tell the DAM to begin making the set of image tiles needed by the asset zoom view.\n\t\t\t * Once begun, progress on the tile generation is reported by getProgressReport().\n\t\t\t * api method: generateZoomifyTiles\n\t\t\t * @method\n\t\t\t */\n\t\t\tmakeZoomTiles: ['generateZoomifyTiles', 'assetId'],\n\n\t\t\t/**\n\t\t\t * adBuilder template methods:\n\t\t\t * ingest a 'template' asset (an .indd file with specific script labels configured)\n\t\t\t * to become the framework of an adBuilder template.\n\t\t\t * @method\n\t\t\t */\n\t\t\tactivateAdBuilderTemplate: ['activateAdBuilderTemplate', 'id'],\n\t\t\tdeactivateAdBuilderTemplate: ['deactivateAdBuilderTemplate', 'id'],\n\t\t};\n\t}\n\t/** @type {object} */\n\tget parsers() {\n\t\treturn {\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @deprecated\n\t\t\t * @param {boolean} response Response\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tassetInCurrentCart(response, opts) {\n\t\t\t\tif (this.inCurrentCart !== response[0]) {\n\t\t\t\t\tthis.inCurrentCart = response[0];\n\t\t\t\t\tthis.set('inCurrentCart', this.inCurrentCart, opts);\n\t\t\t\t\t!opts.silent && this.trigger('sync', this, opts);\n\t\t\t\t}\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {string} uuid UUID\n\t\t\t * @param {object} opts Request options\n\t\t\t * @todo We get back a UUID because technically we call checkinAsset and pass `true` to\n\t\t\t * checkin without a file. The checkin is immediate in this case and we should probably get\n\t\t\t * a call specifically for cancelling checkout so that we get back the updated bean instead\n\t\t\t * of tracking a UUID that is finished immediately.\n\t\t\t * Also, the fact we have to pass more than just our asset id to cancel a checkout is messy\n\t\t\t */\n\t\t\tcancelCheckout(uuid, opts) {\n\t\t\t\tif (!uuid) return false;\n\n\t\t\t\t// Custom events for resyncing\n\t\t\t\tthis.trigger('cancellingCheckOut', this);\n\n\t\t\t\t// Poll\n\t\t\t\tconst batchJob = this.trackBatchJob(uuid, undefined, 500);\n\n\t\t\t\t// When completed\n\t\t\t\tbatchJob.completed.then(() => {\n\t\t\t\t\tthis.trigger('cancelledCheckedOut', this);\n\t\t\t\t\tthis.fetch();\n\t\t\t\t});\n\n\t\t\t\treturn batchJob;\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {string} uuid Response (we need to get full beans back as we refactor things)\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tcheckout(uuid, opts) {\n\t\t\t\tif (!uuid) return false;\n\n\t\t\t\t// Custom events for resyncing\n\t\t\t\tthis.trigger('checkingOut', this);\n\n\t\t\t\t// Poll\n\t\t\t\tconst batchJob = this.trackBatchJob(uuid, undefined, 500);\n\n\t\t\t\t// When completed\n\t\t\t\tbatchJob.completed.then(() => {\n\t\t\t\t\tthis.trigger('checkedOut', this);\n\t\t\t\t\tthis.fetch();\n\t\t\t\t});\n\n\t\t\t\treturn batchJob;\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {number} assetId Asset id\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\timportAsset(assetId, opts) {\n\t\t\t\tif (!assetId) {\n\t\t\t\t\t// NOTE: there is an outstanding bug with this returning zero, which is never right.\n\t\t\t\t\tconsole.warn('importReservedAsset returned ' + assetId); // DEBUG;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.set({assetId: assetId});\n\t\t\t\t// Tell category system that we added an asset.\n\t\t\t\t// TODO: the category system could just as easily respond to an 'asset:imported' event, which would be more generic & meaningful.\n\t\t\t\tdispatcher.trigger(\n\t\t\t\t\t'asset:category:added',\n\t\t\t\t\tthis.id,\n\t\t\t\t\tthis.get('categoryid'),\n\t\t\t\t\tthis,\n\t\t\t\t\t'import',\n\t\t\t\t);\n\n\t\t\t\treturn assetId;\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {boolean} response Response\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tsetAssetCategoryLink(response, opts) {\n\t\t\t\tif (response != true) return;\n\n\t\t\t\tdispatcher.trigger(\n\t\t\t\t\t'asset:category:added',\n\t\t\t\t\tthis.id,\n\t\t\t\t\tthis.linkCategory,\n\t\t\t\t\tthis,\n\t\t\t\t\t'setLink',\n\t\t\t\t);\n\t\t\t\t// Track index tasks.\n\t\t\t\t// DAM-21440?: if just linking, no need to track (hopefully)\n\t\t\t\topts?.link == null && dispatcher.trigger('asset:tasks:track', this);\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {boolean} response Response\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tremoveCategory(response, opts) {\n\t\t\t\tconst cat = this.linkCategory;\n\t\t\t\tdispatcher.trigger('asset:category:removed', this.id, cat, this);\n\t\t\t\tdispatcher.trigger('asset:tasks:track', this);\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {array} cats Category IDs\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tsetCategories(cats, opts) {\n\t\t\t\t// server should have given us back the list of ids we gave it\n\t\t\t\tif (cats.join('') != this.linkCategories.join('')) {\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t'`setCategories` failed to set categories >',\n\t\t\t\t\t\tcats.join(', '),\n\t\t\t\t\t\tthis.linkCategories.join(', '),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {array} ids Asset IDs\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\treserve(ids, opts) {\n\t\t\t\tthis.set('assetId', ids[0]);\n\t\t\t},\n\t\t\t/**\n\t\t\t * @function\n\t\t\t * @param {string} uuid UUID\n\t\t\t * @param {object} opts Request options\n\t\t\t */\n\t\t\tresync(uuid, opts) {\n\t\t\t\tif (!uuid) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// Custom events for resyncing\n\t\t\t\tthis.trigger('resyncing', this);\n\n\t\t\t\t// Poll\n\t\t\t\tconst batchJob = this.trackBatchJob(uuid);\n\n\t\t\t\t// When completed\n\t\t\t\tbatchJob.completed.then(() => {\n\t\t\t\t\tthis.trigger('resynced', this);\n\t\t\t\t});\n\n\t\t\t\treturn batchJob;\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Internally, the Asset model uses another model, 'metadata', to store DAM metadata attributes.\n\t * (Backbone.Model uses the key 'attributes' in this object to store all other model data.)\n\t * We override the constructor to add that object when the model is created.\n\t * @override\n\t */\n\tconstructor(attr, opts = {}) {\n\t\tsuper(attr, opts);\n\n\t\t/**\n\t\t * Seperate from the asset model's attributes (which describe DAM data) are the following asset model properties\n\t\t * which inform the various RPC methods of this model.\n\t\t *\n\t\t * For remove():\n\t\t * deleteWait determines if deleteAsset() method will block until the DAM is done deleting.\n\t\t * @type {boolean}\n\t\t * @todo No we wont\n\t\t */\n\t\tthis.deleteWait = opts.deleteWait !== true;\n\n\t\t/**\n\t\t * importAttributes: an array of LabelValue objects to set as asset metadata attributes upon import\n\t\t * @type {Array}\n\t\t */\n\t\tthis.importAttributes = opts.importAttributes || [];\n\n\t\t/*\n\t\t * cache of our cart state; 'undefined' means we know nothing.\n\t\t *\n\t\t * @todo As of 7.6.0 assetBeans have inCurrentCart as a property\n\t\t * we need to deprecate all usage of the model property inCurrentCart\n\t\t * in favor of the model attribute inCurrentCart\n\t\t */\n\t\tthis.inCurrentCart = undefined;\n\n\t\t/**\n\t\t * For addCategory, removeCategory, setCategory:\n\t\t * linkCategory is the category ID these calls operate on.\n\t\t * @type {number}\n\t\t */\n\t\tthis.linkCategory = opts.linkCategory || 0;\n\n\t\t/**\n\t\t * for setAssetCategories:\n\t\t * linkCategories is a list of category Ids to set on the asset.\n\t\t * @type {array}\n\t\t */\n\t\tthis.linkCategories = opts.linkCategories || [];\n\t\t/*\n\t\t * collisionStrategy defines ways setAssetCategories can handle a filename collision.\n\t\t * Filenames must be unique within categories. A collision occurs when\n\t\t * we try to move an asset into a category where the asset's filename is already in use.\n\t\t * (Multiple uploads of the same asset are the most common example.) This integer argument to the\n\t\t * setCategoryAssets() API call specifies how to handle that. This object maps those\n\t\t * integers to meaningful labels, but we don't allow API users to change the default strategy,\n\t\t * which is collisionStrategy.rename .\n\t\t * @private\n\t\t */\n\t\tthis.collisionStrategy = _.extend(\n\t\t\t{\n\t\t\t\tfail: 0, // block the category change; leave the asset in its current category.\n\t\t\t\trename: 1, // rename the file we're recategorizing\n\t\t\t},\n\t\t\topts.collisionStrategy,\n\t\t);\n\n\t\t//\n\t\t// for getMessage, a nearly-but-not-quite-deprecated API call which we use to track reimports:\n\t\t// messageType: 4 = messages about asset reimport. Other values unknown.\n\t\t// objectContext: always null for us.\n\t\t// @private\n\t\t//\n\t\tthis.messageType = opts.messageType != null ? opts.messageType : 4;\n\t\t/** @type {string} */\n\t\tthis.objectContext = opts.objectContext || '';\n\n\t\t/**\n\t\t * for repurpose():\n\t\t * repurposeId is the ID of the preset repurposing process to apply with 'repurpose' method. (Netx.asset.processes contains the complete set of those processes, and is indexed by ID.)\n\t\t * @type {number}\n\t\t */\n\t\tthis.repurposeId = opts.repurposeId || 0;\n\n\t\t/**\n\t\t * repurposeOtherIds: meaning varies by process.\n\t\t * @type {array}\n\t\t */\n\t\tthis.repurposeOtherIds = opts.repurposeOtherIds || [];\n\t\tthis.repurposeMethods = opts.repurposeMethods || [];\n\t\tthis.repurposeValues = opts.repurposeValues || [];\n\n\t\t// according to FlexService.java, this field is 100% ignored.\n\t\tthis.repurposeDownloadOverride = opts.repurposeDownloadOverride || '';\n\n\t\t// Keep a model of the current version\n\t\tthis.version = new AssetVersionModel();\n\t\tthis.addSubModel(this.version);\n\n\t\tthis.setMediaUrls();\n\t\tthis.setChecksum();\n\n\t\t/**\n\t\t * @memberof module:asset/models/asset\n\t\t * @alias progress\n\t\t * @type {module:app/models/progress}\n\t\t */\n\t\tthis.progress = new ProgressModel();\n\t\tthis.addSubModel(this.progress);\n\n\t\t/**\n\t\t * @memberof module:asset/models/asset\n\t\t * @alias constituents\n\t\t * @type {module:asset/collections/assetConstituents}\n\t\t */\n\t\tthis.constituents = new AssetConstituentsCollection([]);\n\t\tthis.addSubCollection(this.constituents);\n\n\t\t// Hey, listen!\n\t\tthis\n\t\t\t// Make necessary updates when the id changes\n\t\t\t.listenTo(this, 'change:assetId', (model, assetId, options) => {\n\t\t\t\t// Update this.version when the asset changes id - sync doesn't work in most of our cases as the data is being\n\t\t\t\t// set by the cursor change in the controller with data from an asset collection\n\t\t\t\t// TODO: the asset mimics a sync now when we put it on the cursor - see if this is all still necessary\n\t\t\t\t// and if there may be a better place to put it\n\t\t\t\tthis.version.clear();\n\t\t\t\tif (this.id) {\n\t\t\t\t\tconst versions = this.get('versionIds');\n\t\t\t\t\tif (versions && versions.length > 1) {\n\t\t\t\t\t\tthis.version.set('versionId', versions[0]);\n\t\t\t\t\t\tthis.version.fetch();\n\t\t\t\t\t} else if (versions) {\n\t\t\t\t\t\t// Fake it 'til they make it\n\t\t\t\t\t\tthis.version.set({\n\t\t\t\t\t\t\tcreationDate: this.get('creationdate'),\n\t\t\t\t\t\t\tfileSize: this.get('fileSize2'),\n\t\t\t\t\t\t\tfileTypeId: this.get('filetype'),\n\t\t\t\t\t\t\tfileTypeLabel: this.get('filetypelabel'),\n\t\t\t\t\t\t\tassetId: this.get('imageid'),\n\t\t\t\t\t\t\tuserId: this.get('moduserid'),\n\t\t\t\t\t\t\tuserLabel: this.get('moduserlabel'),\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// Mimic a sync\n\t\t\t\t\t\tthis.version.trigger('sync', this.version);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Custom thumbnail progress listeners\n\t\t\t\tconst oldAssetId = this._previousAttributes.assetId;\n\t\t\t\tthis.setupCustomThumbnailListeners(oldAssetId);\n\t\t\t\tthis.setupAssetTaskListeners(oldAssetId);\n\t\t\t\tthis.setMediaUrls();\n\t\t\t\tthis.setChecksum();\n\t\t\t})\n\t\t\t////////////////////////////\n\t\t\t// ADBUILDER\n\t\t\t////////////////////////////\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'adBuilder:activate:asset:error',\n\t\t\t\t(error, asset) => {\n\t\t\t\t\tasset &&\n\t\t\t\t\t\tasset.id === this.id &&\n\t\t\t\t\t\tthis.set({\n\t\t\t\t\t\t\tactivatingTemplate: false,\n\t\t\t\t\t\t\ttemplate: false,\n\t\t\t\t\t\t\ttemplateCustomizable: false,\n\t\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t)\n\t\t\t.listenTo(dispatcher, 'adBuilder:activate:asset:start', (asset) => {\n\t\t\t\tasset &&\n\t\t\t\t\tasset.id === this.id &&\n\t\t\t\t\tthis.set({\n\t\t\t\t\t\tactivatingTemplate: true,\n\t\t\t\t\t\tdeactivatingTemplate: false,\n\t\t\t\t\t});\n\t\t\t})\n\t\t\t.listenTo(dispatcher, 'adBuilder:activate:asset:succeeded', (asset) => {\n\t\t\t\tasset &&\n\t\t\t\t\tasset.id === this.id &&\n\t\t\t\t\tthis.set({\n\t\t\t\t\t\tactivatingTemplate: false,\n\t\t\t\t\t\ttemplate: true,\n\t\t\t\t\t});\n\t\t\t})\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'adBuilder:deactivate:asset:error',\n\t\t\t\t(error, asset) => {\n\t\t\t\t\tasset &&\n\t\t\t\t\t\tasset.id === this.id &&\n\t\t\t\t\t\tthis.set({\n\t\t\t\t\t\t\tdeactivatingTemplate: false,\n\t\t\t\t\t\t\ttemplate: true,\n\t\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t)\n\t\t\t.listenTo(dispatcher, 'adBuilder:deactivate:asset:start', (asset) => {\n\t\t\t\tasset &&\n\t\t\t\t\tasset.id === this.id &&\n\t\t\t\t\tthis.set({\n\t\t\t\t\t\tactivatingTemplate: false,\n\t\t\t\t\t\tdeactivatingTemplate: true,\n\t\t\t\t\t});\n\t\t\t})\n\t\t\t.listenTo(dispatcher, 'adBuilder:deactivate:asset:succeeded', (asset) => {\n\t\t\t\tasset &&\n\t\t\t\t\tasset.id === this.id &&\n\t\t\t\t\tthis.set({\n\t\t\t\t\t\tdeactivatingTemplate: false,\n\t\t\t\t\t\ttemplate: false,\n\t\t\t\t\t\ttemplateCustomizable: false,\n\t\t\t\t\t});\n\t\t\t})\n\t\t\t////////////////////////////\n\t\t\t// !ADBUILDER\n\t\t\t////////////////////////////\n\n\t\t\t////////////////////////////\n\t\t\t// ATTRIBUTES (METADATA)\n\t\t\t////////////////////////////\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'asset:submit:save asset:info:edit:success asset:attributes:submit:success',\n\t\t\t\t(m) => {\n\t\t\t\t\tif (m.cid !== this.cid && m.id === this.id) {\n\t\t\t\t\t\tthis.set(m.attributes);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t)\n\t\t\t////////////////////////////\n\t\t\t// !ATTRIBUTES (METADATA)\n\t\t\t////////////////////////////\n\n\t\t\t////////////////////////////////\n\t\t\t// CART STATUS\n\t\t\t////////////////////////////////\n\t\t\t// Tracking whether we're in the current cart:\n\t\t\t// If we are added to the cart, we know we're in it\n\t\t\t.listenTo(dispatcher, 'cart:added', (ids) => {\n\t\t\t\tif (ids.indexOf(this.id) < 0) return;\n\n\t\t\t\tif (this.has('inCurrentCart')) {\n\t\t\t\t\tthis.set('inCurrentCart', true);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.inCurrentCart = true;\n\t\t\t\tthis.trigger('change');\n\t\t\t})\n\t\t\t// If we are removed, we know we're not in it\n\t\t\t.listenTo(dispatcher, 'cart:removed', (ids) => {\n\t\t\t\tif (ids.indexOf(this.id) < 0) return;\n\n\t\t\t\tif (this.has('inCurrentCart')) {\n\t\t\t\t\tthis.set('inCurrentCart', false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.inCurrentCart = false;\n\t\t\t\tthis.trigger('change');\n\t\t\t})\n\t\t\t// If the cart is cleared, we know we're not in it.\n\t\t\t.listenTo(dispatcher, 'cart:cleared', () => {\n\t\t\t\tif (this.has('inCurrentCart')) {\n\t\t\t\t\tthis.set('inCurrentCart', false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.inCurrentCart = false;\n\t\t\t\tthis.trigger('change');\n\t\t\t})\n\t\t\t////////////////////////////////\n\t\t\t// !CART STATUS\n\t\t\t////////////////////////////////\n\n\t\t\t// When a checkout & checkin happens, update our status & checked-out-ness\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'asset:checkout:success asset:checkout:cancel:success',\n\t\t\t\t(asset) => {\n\t\t\t\t\t// we are us!\n\t\t\t\t\t// we are not a duplicate model for the same DAM asset\n\t\t\t\t\tif (asset === this || asset.id !== this.id) return;\n\n\t\t\t\t\tthis.set({\n\t\t\t\t\t\tstatus: asset.get('status'),\n\t\t\t\t\t\tcheckout: asset.get('checkout'),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t)\n\t\t\t// Batch jobs\n\t\t\t.listenTo(this, 'progress', (model, batchJob, progress) => {\n\t\t\t\tconst progressMessage = (batchJob && batchJob.get('details')) || '';\n\t\t\t\tthis.progress.update(progress, progressMessage);\n\t\t\t})\n\t\t\t.listenTo(this, 'complete', (model, batchJob) => {\n\t\t\t\tthis.progress.complete();\n\t\t\t})\n\t\t\t// When asset sybcs\n\t\t\t.listenTo(this, 'sync', (model) => {\n\t\t\t\tif (model !== this) return;\n\t\t\t\tthis.progress.reset();\n\t\t\t})\n\t\t\t// When a clip is created/updated\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'asset:constituent:clip:edit:success',\n\t\t\t\t(asset, clip, isNew) => {\n\t\t\t\t\tif (asset.id !== this.id) return;\n\n\t\t\t\t\tthis.constituents.clips.add(clip);\n\t\t\t\t},\n\t\t\t);\n\n\t\t// Custom thumbnail progress listeners\n\t\tthis.setupCustomThumbnailListeners();\n\t\tthis.setupAssetTaskListeners();\n\t\tthis.setupAssetCheckinListeners();\n\t}\n\n\t/**\n\t * The parse() method converts the contents of the AssetBean's attributeNames & attributeValues arrays\n\t * into the internal metadata model.\n\t * @override\n\t * @param {object} resp Asset bean\n\t * @param {object} opts Request options\n\t * @return {object} the unmodified attributes. (The internal attribute* arrays will still be updated from this data.)\n\t */\n\tparse(resp, opts) {\n\t\t// Set media urls\n\t\treturn _.extend(_.omit(resp, 'validationData', 'id'), {\n\t\t\taudioUrl: this.hasAudio(resp) || '',\n\t\t\tvideoUrl: this.hasVideo(resp) || '',\n\t\t\tzoomUrl: this.hasZoom(resp) || '',\n\t\t});\n\t}\n\n\t/**\n\t * the self() method translates the metadata object back into arrays,\n\t * being careful to preserve the same order as the attributeNames array.\n\t * @override\n\t * @return {object}\n\t */\n\tself() {\n\t\treturn _.omit.apply(\n\t\t\t_,\n\t\t\t[\n\t\t\t\tthis.attributes,\n\t\t\t\t'attributeValues',\n\t\t\t\t'attributeNames',\n\t\t\t\t'attributeIds',\n\t\t\t].concat(this.clientAttrs),\n\t\t);\n\t}\n\n\t/** @method */\n\tvalidate(attrs) {\n\t\tif (!_.isNumber(attrs.assetId)) {\n\t\t\treturn 'Must pass a number';\n\t\t}\n\t}\n\n\t/**\n\t * @method\n\t * @return {boolean} Can zoom\n\t */\n\tcanZoom() {\n\t\treturn (\n\t\t\tthis.isImage() &&\n\t\t\tthis.get('filewidth') > 0 &&\n\t\t\tthis.get('fileheight') > 0 &&\n\t\t\tthis.get('zoomAvailable') &&\n\t\t\t(getPreference('zoom.tiles.enabled', true) ||\n\t\t\t\t(getPreference('equilibrium.enabled', true) &&\n\t\t\t\t\tgetPreference('equilibrium.zoomEnabled', true)))\n\t\t);\n\t}\n\n\t/**\n\t * @method\n\t * @param {string} dateStr Date (yyyy-mm-dd)\n\t */\n\texpire(dateStr) {\n\t\ttry {\n\t\t\tconst expirationTime = userInputToExpirationTime(dateStr);\n\t\t\treturn this.set('expirationDate', expirationTime).expireAsset();\n\t\t} catch (ex) {\n\t\t\treturn new $.Deferred().reject(ex);\n\t\t}\n\t}\n\n\t/**\n\t * @method\n\t * @param {object} opts Request options\n\t */\n\tfetchConstituents(opts) {\n\t\tvar constituents = this.constituents;\n\n\t\tif (constituents.assetId === this.id) {\n\t\t\treturn new $.Deferred().resolveWith(constituents);\n\t\t}\n\n\t\tconstituents.assetId = this.id;\n\t\treturn constituents.fetch(\n\t\t\t_.extend(\n\t\t\t\t{\n\t\t\t\t\tduplicateQueryPolicy: 'abort',\n\t\t\t\t\treset: true,\n\t\t\t\t},\n\t\t\t\topts,\n\t\t\t),\n\t\t);\n\t}\n\n\tgarbageCollect() {\n\t\tsuper.garbageCollect();\n\t\tdelete this.progress;\n\t\tdelete this.version;\n\t\tdelete this.constituents;\n\t}\n\n\t/**\n\t * getAttribute() and setAttribute() are the preferred interface to the DAM's internal representation of asset attributes.\n\t * @method\n\t * @param {number} templateId Template id\n\t * @param {string} name Template name\n\t * @param {object} opts Options\n\t * @return {mixed}\n\t */\n\tgetAttribute(templateId, name, opts = {}) {\n\t\tconst attrModel = getAttribute(templateId, name);\n\t\tlet value;\n\n\t\tif (attrModel) {\n\t\t\tvalue =\n\t\t\t\tattrModel.get('system') &&\n\t\t\t\tattrModel.id !== -119 && // Smart labels\n\t\t\t\tattrModel.id !== -120 // dimensions\n\t\t\t\t\t? this.getSystemAttribute(attrModel.id)\n\t\t\t\t\t: this.get('attributeValues')[\n\t\t\t\t\t\t\t_.indexOf(this.get('attributeIds'), attrModel.id)\n\t\t\t\t\t ];\n\n\t\t\tvalue = opts.format\n\t\t\t\t? attrModel.format(value, opts)\n\t\t\t\t: attrModel.parseInValue(value);\n\t\t}\n\n\t\treturn value != null ? value : '';\n\t}\n\n\t/**\n\t * Get attribute template id by name\n\t * @param {string} name Attribute name\n\t * @return {number}\n\t */\n\tgetAttributeId(name) {\n\t\treturn getAttributeId(name);\n\t}\n\n\t/**\n\t * @method\n\t * @param {number} templateId Template id\n\t * @param {object} opts Options\n\t * @return {mixed}\n\t * @deprecated see `this.getAttribute`\n\t */\n\tgetAttributeValue(templateId, opts) {\n\t\treturn this.getAttribute(templateId, null, opts);\n\t}\n\n\t/**\n\t * @method\n\t * @param {number} templateId Attribute template id\n\t * @return {mixed}\n\t */\n\tgetSystemAttribute(templateId, name) {\n\t\tconst attrModel = getAttribute(templateId, name);\n\t\tlet value;\n\t\tif (attrModel) {\n\t\t\tvar attrName = attrModel.get('name');\n\t\t\t// Normalize\n\t\t\tswitch (attrModel.get('name')) {\n\t\t\t\tcase 'creationDate':\n\t\t\t\t\tattrName = 'creationdate';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'expireDate':\n\t\t\t\t\tattrName = 'expirationDate';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'fileSize':\n\t\t\t\t\tattrName = 'fileSize2';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'fileType':\n\t\t\t\t\tattrName = 'filetypelabel';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'folderPath':\n\t\t\t\t\tattrName = 'categoryPaths';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'height':\n\t\t\t\t\tattrName = 'fileheight';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'modDate':\n\t\t\t\t\tattrName = 'moddate';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'width':\n\t\t\t\t\tattrName = 'filewidth';\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tvalue = this.get(attrName);\n\t\t\tif (_.isArray(value)) {\n\t\t\t\tvalue.join(', ');\n\t\t\t}\n\t\t}\n\n\t\treturn value != null ? value : '';\n\t}\n\n\t/**\n\t * @method\n\t * @return {string} Token string if it exists\n\t */\n\tgetTokenString() {\n\t\tconst token = session.getToken();\n\t\treturn token ? '?token=' + token : '';\n\t}\n\n\t/**\n\t * @method\n\t * @return {array} Waveform JSON\n\t */\n\tgetWaveformJSON() {\n\t\treturn $.getJSON(\n\t\t\t`/file/asset/${this.id}/view/previewWaveformJSON${this.getTokenString()}`,\n\t\t).then((json) => {\n\t\t\treturn json.data;\n\t\t});\n\t}\n\n\t/**\n\t * Does asset have audio, get the audio url\n\t * @method\n\t * @param {object} attrs Attributes to use (rather than `this.get`)\n\t * @return {boolean}\n\t */\n\thasAudio(attrs = {}) {\n\t\tconst id = attrs.assetId || this.id;\n\t\tif (\n\t\t\t_.indexOf(\n\t\t\t\tattrs.fileFormatFamily || this.get('fileFormatFamily'),\n\t\t\t\t'audio',\n\t\t\t) < 0\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\tlet url = false;\n\t\tconst tokenStr = this.getTokenString();\n\t\t// Check in view names\n\t\tif (\n\t\t\t_.indexOf(attrs.viewNames || this.get('viewNames'), 'previewMp3') > -1\n\t\t) {\n\t\t\turl = [\n\t\t\t\t'/file/asset/',\n\t\t\t\tid,\n\t\t\t\t'/view/previewMp3/a_',\n\t\t\t\tid,\n\t\t\t\t'.mp3',\n\t\t\t\ttokenStr,\n\t\t\t].join('');\n\t\t}\n\t\t// Check in file type label\n\t\telse if ((attrs.filetypelabel || this.get('filetypelabel')) === 'mp3') {\n\t\t\turl = ['/file/asset/', id, '/original/a_', id, '.mp3', tokenStr].join('');\n\t\t}\n\n\t\treturn url;\n\t}\n\n\t/**\n\t * @method\n\t * @param {string} format Format\n\t * @return {boolean} Has format family\n\t */\n\thasFormatFamily(format) {\n\t\treturn _.contains(this.get('fileFormatFamily'), format);\n\t}\n\n\t/**\n\t * Does asset have any multimedia (audio/video)\n\t * @method\n\t * @return {boolean|string} Audio url or false\n\t */\n\thasMultimedia() {\n\t\treturn this.hasAudio() || this.hasVideo();\n\t}\n\n\t/**\n\t * Does asset have video, get the video url\n\t * @method\n\t * @param {object} attrs Attributes to use (rather than `this.get`)\n\t * @return {boolean|string} Video url or false\n\t */\n\thasVideo(attrs = {}) {\n\t\tconst id = attrs.assetId || this.id;\n\t\tconst tokenStr = this.getTokenString();\n\n\t\tif (\n\t\t\t_.indexOf(\n\t\t\t\tattrs.fileFormatFamily || this.get('fileFormatFamily'),\n\t\t\t\t'video',\n\t\t\t) < 0\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\tlet url = false;\n\t\tif (\n\t\t\t_.indexOf(attrs.viewNames || this.get('viewNames'), 'previewH264') !== -1\n\t\t) {\n\t\t\turl = [\n\t\t\t\t'/file/asset/',\n\t\t\t\tid,\n\t\t\t\t'/view/previewH264/v_',\n\t\t\t\tid,\n\t\t\t\t'.mp4',\n\t\t\t\ttokenStr,\n\t\t\t].join('');\n\t\t}\n\t\t// Check in file type label\n\t\telse if ((attrs.filetypelabel || this.get('filetypelabel')) === 'mp4') {\n\t\t\turl = ['/file/asset/', id, '/original/v_', id, '.mp4', tokenStr].join('');\n\t\t}\n\n\t\treturn url;\n\t}\n\n\t/**\n\t * Does asset have a zoom view (Longest side is 1000), get the zoom url\n\t * @method\n\t * @param {object} attrs Attributes to use (rather than `this.get`)\n\t * @return {boolean|string} Zoom url or false\n\t */\n\thasZoom(attrs = {}) {\n\t\tconst id = attrs.assetId || this.id;\n\t\tconst filetypelabel = attrs.filetypelabel || this.get('filetypelabel');\n\t\treturn `/file/asset/${id}/zoom/${id}.${filetypelabel}`;\n\t}\n\n\t/**\n\t * Only for use in updating attribute values locally (like after a change from elsewhere)\n\t * Once we get websockets this will be deprecated\n\t * @method\n\t * @param {number|string} templateId Attribute template id\n\t * @param {string} val Value of the attribute to set\n\t */\n\tsetAttribute(templateId, val, opts) {\n\t\tconst id = _.isString(templateId) ? null : templateId;\n\t\tconst name = _.isString(templateId) ? templateId : null;\n\t\tconst attrModel = getAttribute(id, name);\n\n\t\tif (!attrModel) return this;\n\n\t\tconst idx = _.indexOf(this.get('attributeIds'), attrModel.id);\n\n\t\tif (attrModel.isCSV || attrModel.isTrueMultivalue()) {\n\t\t\tval = _.arrayToCsv(val);\n\t\t}\n\n\t\tif (idx > -1) {\n\t\t\tconst attributeValues = _.clone(this.get('attributeValues'));\n\t\t\tattributeValues[idx] = val;\n\t\t\treturn this.set(\n\t\t\t\t{\n\t\t\t\t\tattributeValues: attributeValues,\n\t\t\t\t},\n\t\t\t\topts,\n\t\t\t);\n\t\t}\n\n\t\treturn this.set(\n\t\t\t{\n\t\t\t\tattributeIds: this.get('attributeIds').concat([attrModel.id]),\n\t\t\t\tattributeNames: this.get('attributeNames').concat([attrModel.name]),\n\t\t\t\tattributePermissions: this.get('attributePermissions').concat(['r']),\n\t\t\t\tattributeValues: this.get('attributeValues').concat([val]),\n\t\t\t},\n\t\t\topts,\n\t\t);\n\t}\n\n\t/**\n\t * @method\n\t * @listens module:upload#upload:asset:checkin:complete\n\t * @listens module:upload#upload:asset:checkin:progress\n\t * @listens module:upload#upload:asset:checkin:error\n\t */\n\tsetupAssetCheckinListeners() {\n\t\tthis.stopListening(dispatcher, 'upload:asset:checkin:progress')\n\t\t\t.stopListening(dispatcher, 'upload:asset:checkin:complete')\n\t\t\t.stopListening(dispatcher, 'upload:asset:checkin:error')\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'upload:asset:checkin:progress',\n\t\t\t\t(assetId, progress, progressMessage, file) => {\n\t\t\t\t\tif (assetId !== this.id) return;\n\n\t\t\t\t\tthis.trigger('checkingIn', this, file);\n\t\t\t\t\tthis.progress.update(progress, progressMessage);\n\t\t\t\t},\n\t\t\t)\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'upload:asset:checkin:complete',\n\t\t\t\t(assetId, file) => {\n\t\t\t\t\tif (assetId !== this.id) return;\n\n\t\t\t\t\tthis.trigger('checkedIn', this, file);\n\t\t\t\t\tthis.progress.complete();\n\t\t\t\t\t// Delay slightly so the progress removal does not seem so abrupt\n\t\t\t\t\t_.delay(_.bind(this.fetch, this), 1000);\n\t\t\t\t},\n\t\t\t)\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'upload:asset:checkin:error',\n\t\t\t\t(error, assetId, file) => {\n\t\t\t\t\tthis.trigger('checkedIn', this, file);\n\t\t\t\t\tthis.progress.complete();\n\t\t\t\t},\n\t\t\t)\n\t\t\t.stopListening(dispatcher, 'asset:versions:reactivate:progress')\n\t\t\t.stopListening(dispatcher, 'asset:versions:reactivate:succeeded')\n\t\t\t.stopListening(dispatcher, 'asset:versions:reactivate:error')\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'asset:versions:reactivate:progress',\n\t\t\t\t(assetId, progress, progressMessage) => {\n\t\t\t\t\tif (assetId !== this.id) return;\n\t\t\t\t\tthis.progress.update(progress, progressMessage);\n\t\t\t\t},\n\t\t\t)\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'asset:versions:reactivate:succeeded',\n\t\t\t\t(newVersion) => {\n\t\t\t\t\tif (newVersion.get('assetId') !== this.id) return;\n\t\t\t\t\tthis.progress.complete();\n\t\t\t\t},\n\t\t\t)\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\t'asset:versions:reactivate:error',\n\t\t\t\t(error, newVersion) => {\n\t\t\t\t\tif (newVersion.get('assetId') !== this.id) return;\n\t\t\t\t\tthis.progress.complete();\n\t\t\t\t},\n\t\t\t);\n\t}\n\n\t/**\n\t * Setup asset task listeners (cleans up any old listeners as well)\n\t * @method\n\t * @param {number} oldAssetId Old asset id\n\t */\n\tsetupAssetTaskListeners(oldAssetId) {\n\t\tif (oldAssetId) {\n\t\t\t// asset:task:complete:\n\t\t\tthis.stopListening(dispatcher, 'asset:task:complete:' + oldAssetId);\n\t\t\tthis.stopListening(dispatcher, 'asset:task:' + oldAssetId + ':status');\n\t\t}\n\n\t\tif (!this.id) return;\n\n\t\t// Task completion\n\t\tthis.listenTo(dispatcher, 'asset:task:complete:' + this.id, (task) => {\n\t\t\t// HACKETY-HACK-SMACK-HACK for EIGHT-549:\n\t\t\tconst tempIconPattern = /\\/icons\\/.*\\.png$/;\n\t\t\tlet previewNow = this.get('previewUrl');\n\n\t\t\t// If we currently have no previewUrl, or a temporary icon preview ...\n\t\t\tif (!previewNow || previewNow.match(tempIconPattern)) {\n\t\t\t\t// ... then poll until the DAM generates a proper preview, or we run out of patience.\n\t\t\t\tconst patienceExhausted = 4; // only try this many times.\n\t\t\t\tlet timesPolled = 0;\n\t\t\t\tthis.pollUntil(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tpreviewNow = this.get('previewUrl'); // possibly updated?\n\t\t\t\t\t\ttimesPolled++;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t(previewNow && !previewNow.match(tempIconPattern)) ||\n\t\t\t\t\t\t\ttimesPolled >= patienceExhausted\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\tundefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\t2000,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.progress.complete();\n\t\t\tthis.trigger('taskComplete', this, task);\n\t\t})\n\t\t\t// Task status\n\t\t\t.listenTo(dispatcher, 'asset:task:' + this.id + ':status', (task) => {\n\t\t\t\t// Shows our import tasks percentage as the second half of our total import progress;\n\t\t\t\t// therefore, we divide by 2 and add 50.\n\t\t\t\tconst realProgress = task.get('percentComplete') / 2 + 50;\n\t\t\t\tconst tasks = task.get('tasks') || [];\n\t\t\t\tthis.progress.update(\n\t\t\t\t\trealProgress,\n\t\t\t\t\timportTasks[tasks[0]] || i18n.t('i18n.processing'),\n\t\t\t\t);\n\t\t\t\tthis.trigger('taskStatus', this, task);\n\t\t\t});\n\t}\n\n\t/**\n\t * Cleans up old listeners (if any) and adds new listeners for all your custom thumbnail needs\n\t * @method\n\t * @param {number} oldAssetId Old asset id\n\t */\n\tsetupCustomThumbnailListeners(oldAssetId) {\n\t\t// NOTE: normalized the 'error' event as we have many a use for a good 'ol lower cased error event\n\t\t// Its return will not be the same as pluploads - it will return an error message and an assetId (if it can get itoff the details)\n\t\tlet eventPrefix;\n\t\t// Clean up any old listeners (really only an issue with Netx.asset.current)\n\t\tif (oldAssetId) {\n\t\t\teventPrefix = 'upload:asset:customThumbnail:' + oldAssetId;\n\t\t\t// asset:customThumbnail:upload::error\n\t\t\t// asset:customThumbnail:upload::FilesAdded\n\t\t\t// asset:customThumbnail:upload::UploadProgress\n\t\t\t// asset:customThumbnail:upload::polling\n\t\t\t// asset:customThumbnail:upload::success\n\t\t\tthis.stopListening(dispatcher, eventPrefix + ':error');\n\t\t\tthis.stopListening(dispatcher, eventPrefix + ':FilesAdded');\n\t\t\tthis.stopListening(dispatcher, eventPrefix + ':UploadProgress');\n\t\t\tthis.stopListening(dispatcher, eventPrefix + ':progress');\n\t\t\tthis.stopListening(dispatcher, eventPrefix + ':success');\n\t\t}\n\n\t\tif (!this.id) return;\n\n\t\t// Events for custom thumbnail\n\t\teventPrefix = 'upload:asset:customThumbnail:' + this.id;\n\n\t\tthis\n\t\t\t// Listen for error\n\t\t\t// asset:customThumbnail:upload::error\n\t\t\t.listenTo(dispatcher, eventPrefix + ':error', (error) => {\n\t\t\t\tthis.set({\n\t\t\t\t\tprogress: 0,\n\t\t\t\t\tupdating: false,\n\t\t\t\t});\n\t\t\t})\n\t\t\t// Listen for FilesAdded\n\t\t\t// This basically means that a new custom thumbnail is being uploaded\n\t\t\t// asset:customThumbnail:upload::FilesAdded\n\t\t\t.listenTo(dispatcher, eventPrefix + ':FilesAdded', (pluploader, file) => {\n\t\t\t\tthis.progress.update(0, i18n.t('i18n.addingCustomThumbnail'));\n\t\t\t})\n\t\t\t// Listen for UploadProgress\n\t\t\t// Half the progress since this is a two part process\n\t\t\t// asset:customThumbnail:upload::UploadProgress\n\t\t\t.listenTo(\n\t\t\t\tdispatcher,\n\t\t\t\teventPrefix + ':UploadProgress',\n\t\t\t\t(pluploader, file) => {\n\t\t\t\t\tthis.progress.update(\n\t\t\t\t\t\tparseInt(file.percent / 2),\n\t\t\t\t\t\ti18n.t('i18n.uploadingCustumThumbnail'),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t)\n\t\t\t// Listen for polling\n\t\t\t// Thumbnail has been uploaded and the job is running on the server\n\t\t\t// Half the progress and add 50 (two part process and we are the second part)\n\t\t\t// asset:customThumbnail:upload::polling\n\t\t\t.listenTo(dispatcher, eventPrefix + ':progress', (batchJob, progress) => {\n\t\t\t\tthis.progress.update(\n\t\t\t\t\t50 + parseInt(progress / 2),\n\t\t\t\t\ti18n.t('i18n.settingCustomThumbnail'),\n\t\t\t\t);\n\t\t\t})\n\t\t\t// Listen for suceess\n\t\t\t// Thumbnail uploaded and job complete\n\t\t\t// asset:customThumbnail:upload::success\n\t\t\t.listenTo(dispatcher, eventPrefix + ':success', (file) => {\n\t\t\t\tthis.progress.complete();\n\t\t\t\t// If we did not have a thumbUrl at all, just ignore as we are some sort of dummy asset model\n\t\t\t\tif (!this.get('thumbUrl')) return;\n\n\t\t\t\t// Delay slightly since this could have gone way too fast (avoid janky progress)\n\t\t\t\t_.delay(() => {\n\t\t\t\t\tthis.fetch().then(() => {\n\t\t\t\t\t\t// TODO: Need to discuss the DAM updating the moddate when a custom thumbnail is selected\n\t\t\t\t\t\tthis.trigger('thumbnailUpdated', file);\n\t\t\t\t\t});\n\t\t\t\t}, 1000);\n\t\t\t});\n\t}\n\n\t/**\n\t * Deduces the url required to access asset media (video, audio, zoom)\n\t * You know, so we are not repeating this logic all over the place in views etc\n\t * This makes the change silently as nothing abotu the asset has actually changed or needed to come from the server\n\t * These attributes are defined in clientAttrs and cleaned up when this.self is called\n\t * @method\n\t */\n\tsetMediaUrls(attrs) {\n\t\tif (!this.id) return;\n\n\t\t// Check and see if we are video, audio etc and set proper urls\n\t\tthis.set('audioUrl', this.hasAudio(attrs) || '');\n\t\tthis.set('videoUrl', this.hasVideo(attrs) || '');\n\t\tthis.set('zoomUrl', this.hasZoom(attrs) || '');\n\t}\n\n\t/**\n\t * Pretend this is a thing\n\t * @method\n\t */\n\tsetChecksum() {\n\t\tif (checksumEnabled()) {\n\t\t\tthis.set('checksum', this.get('attribute4'));\n\t\t}\n\t}\n\n\t/**\n\t * @method\n\t */\n\tunexpire() {\n\t\treturn this.set('expirationDate', 0).expireAsset();\n\t}\n\n\t/**\n\t * @deprecated\n\t * setCombo() and getCombo() interface with the DAM's internal representation of a choice list, aka a Pulldown,\n\t * as used for attributes of type 'select', 'multiselect' and 'tags'.\n\t *\n\t * setCombo: Encode a combo attribute as CSV before setting. A subsequent save() will write changes to the DAM.\n\t * @method\n\t * @param {String} name Name of the attribute to set choices for.\n\t * @param {Array} vals An array of strings: new values for the attribute. This can be empty, to clear the list.\n\t */\n\tsetCombo(name, vals) {\n\t\tthis.setAttribute(name, _.arrayToCsv(vals));\n\t}\n\n\t/**\n\t * @deprecated\n\t * Decode a combo attribute from CSV before getting\n\t * @method\n\t * @param {String} name Name of the attribute to get choices for.\n\t * @return {Array} a list of strings.\n\t */\n\tgetCombo(name) {\n\t\treturn _.csvToArray(this.getAttribute(null, name));\n\t}\n\n\t/**\n\t * moveCategory: Move an asset from one category to another, triggering events 'asset:category:removed', 'asset:category:added' and 'asset:category:moved'.\n\t * This method calls setAssetCategories(), so other categories may be removed in the process.\n\t * @param {number} from ID of category to leave (if not provided, will remove from all other categories)\n\t * @param {number} to ID of category to enter\n\t *\n\t * @todo this is too sloppy. We need these events in order to do proper UI feedback for recategorization.\n\t * Both 'from' and 'to' should be arrays ... but really 'from' should go away & we should look at asset.categories instead.\n\t * We should then trigger asset:category:removed for every one of those that's not in 'to' .\n\t */\n\tmoveCategory(from, to) {\n\t\tif (from == to) {\n\t\t\t// no-op!\n\t\t\treturn new $.Deferred().resolve();\n\t\t}\n\n\t\tif (from == null || isNaN(from)) from = this.get('categories');\n\t\tif (!Array.isArray(from)) from = [from];\n\t\tthis.linkCategories = _.without\n\t\t\t.apply(_, [this.get('categories')].concat(from))\n\t\t\t.concat([to]);\n\n\t\treturn this.setCategories().then(() => {\n\t\t\treturn this.fetch().then(() => {\n\t\t\t\t// Success\n\t\t\t\tfrom.forEach((catId) => {\n\t\t\t\t\tdispatcher.trigger('asset:category:removed', this.id, catId, this);\n\t\t\t\t\tdispatcher.trigger('asset:category:moved', this.id, catId, to, this);\n\t\t\t\t});\n\t\t\t\tdispatcher.trigger('asset:category:added', this.id, to, this);\n\n\t\t\t\t// DAM-21440: What tasks are there to track on a single asset move?\n\t\t\t\t// this _defer is a hack around a DAM bug ...\n\t\t\t\t// but which one?\n\t\t\t\t// _.defer(() => {\n\t\t\t\t// \tdispatcher.trigger('asset:tasks:track', this.id);\n\t\t\t\t// });\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * @method\n\t * @return {boolean} Is document\n\t */\n\tisDocument() {\n\t\treturn (\n\t\t\t(this.get('constituentIds').length > 0 && this.isPDF()) ||\n\t\t\tthis.get('fileFormatFamily').includes('document')\n\t\t);\n\t}\n\t/**\n\t * Check if we are an image\n\t * @method\n\t * @return {boolean}\n\t */\n\tisImage() {\n\t\tconst fileFormatFamily = this.get('fileFormatFamily');\n\t\treturn (\n\t\t\tfileFormatFamily.includes('image') ||\n\t\t\tfileFormatFamily.includes('raw') ||\n\t\t\tfileFormatFamily.includes('cameraRaw')\n\t\t);\n\t}\n\n\t/**\n\t * @method\n\t * @return {boolean} Is locked\n\t */\n\tisLocked() {\n\t\treturn this.get('readOnly') === 1;\n\t}\n\n\t/**\n\t * Check if we are a PDF\n\t * @method\n\t * @return {boolean}\n\t */\n\tisPDF() {\n\t\treturn (\n\t\t\t_.indexOf(this.get('viewNames'), 'previewPDF') !== -1 ||\n\t\t\tthis.get('filetypelabel') === 'pdf'\n\t\t);\n\t}\n\n\t/**\n\t * Lock an asset (previously set asset to \"read-only\")\n\t * @method\n\t */\n\tlock(opts) {\n\t\t// Why we need the bean returned on updates\n\t\t// Fetching to get the appropriate permission matrix\n\t\treturn this.save({readOnly: 1}, {wait: true, ...opts}).then(() => {\n\t\t\treturn this.fetch(opts);\n\t\t});\n\t}\n\n\t/**\n\t * Return an assetSet object defining the set that contains just this asset.\n\t * @method\n\t * @return {module:asset/models/assetSet} AssetSet model\n\t */\n\ttoAssetSet() {\n\t\treturn new AssetSetModel({\n\t\t\ttype: assetSetTypes.asset,\n\t\t\tids: [this.id],\n\t\t\tmodels: [this],\n\t\t\tlabel: this.get('name'),\n\t\t});\n\t}\n\n\t/**\n\t * Unlock an asset (previously unset asset from \"read-only\")\n\t * @method\n\t */\n\tunlock(opts) {\n\t\t// Why we need the bean returned on updates\n\t\t// Fetching to get the appropriate permission matrix\n\t\treturn this.save({readOnly: 0}, {wait: true, ...opts}).then(() => {\n\t\t\treturn this.fetch(opts);\n\t\t});\n\t}\n\n\t/**\n\t * return a cache-busting string for the asset preview; this string should change every time the asset preview changes.\n\t * @method\n\t * @return string\n\t */\n\tcacheBuster(prefix) {\n\t\t// If this model doesn't have moddate set, use the current time.\n\t\tconst timeStr = this.get('moddate')\n\t\t\t? _.dateFromAsset(this.get('moddate')).getTime()\n\t\t\t: new Date().getTime();\n\n\t\t// A new checkin will change the preview image without modifying the moddate.\n\t\t// Therefore, encode both versionIds and moddate in the buster-string\n\t\treturn (\n\t\t\t'?' +\n\t\t\t(prefix ? prefix + '&' : '') +\n\t\t\t't=' +\n\t\t\ttimeStr +\n\t\t\t'&v=' +\n\t\t\tthis.get('versionIds')\n\t\t);\n\t}\n\n\t/**\n\t * @deprecated\n\t * Force a local update of the asset's moddate property, so that this.cacheBuster() will return a new string,\n\t * and so that any change listeners for moddate will be jingled.\n\t * Moddate is a read-only property, so any future fetch will reset it to the DAM's value.\n\t * But this method is useful in situations where the client already knows a change has happened,\n\t * and doesn't want to re-fetch.\n\t *\n\t * @method\n\t * @param {Date} date A date object specifying the time to stamp (if undefined, we use the current moment)\n\t */\n\tbumpModdate(date) {\n\t\tdate = date || new Date();\n\t\tthis.set({moddate: _.dateToAsset(date)});\n\t}\n\n\t/**\n\t * Check our permissionMatrix for whether a particular named bit is set.\n\t * @param {string} perm One of the permissions in {module:permissions/properties/assetPermissions#matrixNames}\n\t * @returns {mixed} returns true or false, or undefined (which is falsy) if the argument is undefined.\n\t * @method\n\t */\n\t// DEVNOTE: module:asset/models/asset & Netx.Models.Category use the same method. Change it here, change it there.\n\t// Until we have a better include/export scheme we won't know whether asset or category module inits first,\n\t// so we can't define one of these in terms of the other.\n\t//\n\t//allows: module:asset/models/asset.prototype.allows\n\tallows(perm) {\n\t\tif (perm == null) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst matrixIndex = matrixNames.indexOf(perm);\n\n\t\tif (matrixIndex < 0) {\n\t\t\tthrow new Error(\"Unknown permission '\" + perm + \"'\");\n\t\t}\n\n\t\t// We need the DAM to return appropriate permissions for readOnly assets (even for admins)\n\t\tif (this.get('readOnly') === 1) {\n\t\t\tswitch (perm) {\n\t\t\t\tcase 'delete':\n\t\t\t\tcase 'modify':\n\t\t\t\tcase 'all':\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// The actual test of the actual value in the actual matrix (cast to bool):\n\t\treturn this.get('permissionMatrix')[matrixIndex] ? true : false;\n\t}\n\n\t/**\n\t * Methods for MediaRich zoom feature (if enabled):\n\t *\n\t * This non-standard API call is proxied from the DAM to a connected MediaRich server,\n\t * and tells the MR server to cache the asset from the DAM.\n\t *\n\t * @method\n\t * @returns {promise} resolves/rejects when complete.\n\t */\n\tcacheInMediaRich() {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst mediarichCacheUrl =\n\t\t\t\t// server target (proxied to MS server):\n\t\t\t\t'/mgen/NetX.ms?f=LoadAndCache&assetPath=' +\n\t\t\t\t// URL to original asset, with sessionKey added for authentication:\n\t\t\t\tencodeURIComponent(\n\t\t\t\t\tURL.asset +\n\t\t\t\t\t\t'/' +\n\t\t\t\t\t\tthis.id +\n\t\t\t\t\t\t'/original/' +\n\t\t\t\t\t\tthis.get('file') +\n\t\t\t\t\t\t'?sessionKey=' +\n\t\t\t\t\t\tsession.get('sessionKey'),\n\t\t\t\t) +\n\t\t\t\t// Session key again, because sessions are key:\n\t\t\t\t'&sessionKey=' +\n\t\t\t\tsession.get('sessionKey');\n\n\t\t\t$.ajax(mediarichCacheUrl).then((responseJSON, responseText, jqXHR) => {\n\t\t\t\t// response must be 200 (ok)\n\t\t\t\tif (jqXHR && jqXHR.status != 200) {\n\t\t\t\t\treturn reject(`Bad response from MediaRich server: ${responseText}`);\n\t\t\t\t} else if (\n\t\t\t\t\ttypeof responseJSON === 'string' &&\n\t\t\t\t\tresponseJSON.includes('not found on NetX')\n\t\t\t\t) {\n\t\t\t\t\treturn reject(responseJSON);\n\t\t\t\t}\n\t\t\t\tresolve(responseJSON);\n\t\t\t}, reject);\n\t\t});\n\t}\n\n\t/** @type {string} */\n\tstatic get __name__() {\n\t\treturn 'Asset';\n\t}\n}\n","import {i18n} from '@netx/core/i18n';\nimport {notMobile} from '@netx/core/lib/netx-enablers';\n\nexport let constituents = {\n\ttypes: {\n\t\t1: 'keyframe',\n\t\t2: 'layer',\n\t\t3: 'page',\n\t\t4: 'clip',\n\t},\n\ttypeNames: {\n\t\t1: 'i18n.consituentsKeyframes',\n\t\t2: 'i18n.consituentsLayers',\n\t\t3: 'i18n.consituentsPages',\n\t\t4: 'i18n.consituentsClips',\n\t},\n};\n\nexport let dragUserLevel = 8;\n\n// Tasks that run on assets at import\nexport let importTasks = {\n\tAudioTask: i18n.t('i18n.performingTaskAudio'),\n\tFFFViewTask: i18n.t('i18n.performingTaskFFFView'),\n\tINDDPageTask: i18n.t('i18n.performingTaskINDDPage'),\n\tIWorkPageTask: i18n.t('i18n.performingTaskIWorkPage'),\n\tKeyframesTask: i18n.t('i18n.performingTaskKeyframes'),\n\tMetadataTask: i18n.t('i18n.performingTaskMetadata'),\n\tOfficePageTask: i18n.t('i18n.performingTaskOfficePage'),\n\tPDFPageTask: i18n.t('i18n.performingTaskPDFPage'),\n\tPostImportTask: i18n.t('i18n.performingTaskPostImport'),\n\tPreviewTask: i18n.t('i18n.performingTaskPreview'),\n\tRelatedAssetTask: i18n.t('i18n.performingTaskRelatedAssets'),\n\tSWFTask: i18n.t('i18n.performingTaskSWF'),\n\tThumbnailTask: i18n.t('i18n.performingTaskThumbnail'),\n\tVideoPreviewTask: i18n.t('i18n.performingTaskVideoPeview'),\n\tWatermarkTask: i18n.t('i18n.performingTaskWatermark'),\n\tZoomTask: i18n.t('i18n.performingTaskZoom'),\n};\n\nexport let renderableChanges = [\n\t'attributeIds',\n\t'attributeNames',\n\t'attributeValues',\n\t'checkout',\n\t'creationdate',\n\t'expirationDate',\n\t'file',\n\t'fileSize2',\n\t'fileheight',\n\t'filesize',\n\t'filetype',\n\t'filetypelabel',\n\t'filewidth',\n\t'geoLocationLabel',\n\t'imageid',\n\t'importDate',\n\t'locationContext',\n\t'locationid',\n\t'moddate',\n\t'moduserid',\n\t'moduserlabel',\n\t'name',\n\t'path',\n\t'permissionMatrix',\n\t'previewHeight',\n\t'previewUrl',\n\t'previewWidth',\n\t'readOnly',\n\t'repurposeAvailability',\n\t'status',\n\t'thumb',\n\t'thumbUrl',\n\t'versionIds',\n\t'viewIds',\n\t'viewNames',\n\t'zoomAvailable',\n];\n\nexport let status = {\n\tUNKNOWN: 0,\n\tONLINE: 1,\n\tNEARLINE: 2,\n\tOFFLINE: 3,\n\tTEMP: 4,\n\tCHECKOUT: 5,\n\tIMPORT_IN_PROGRESS: 6,\n};\n\nexport let things = {\n\tattributeHistory: {\n\t\tlabel: i18n.t('i18n.attributeHistory'),\n\t\tuserLevel: 4,\n\t\tenableTest: notMobile,\n\t},\n\tattributes: {\n\t\tlabel: i18n.t('i18n.attributes'),\n\t\tuserLevel: 1,\n\t},\n\tcategories: {\n\t\tlabel: i18n.t('i18n.categories'),\n\t\tuserLevel: 2,\n\t},\n\tclips: {\n\t\tlabel: i18n.t('i18n.constituentsClips'),\n\t\tuserLevel: 2,\n\t},\n\tconstituents_keyframes: {\n\t\tlabel: i18n.t('i18n.constituentsKeyframes'),\n\t\tuserLevel: 7,\n\t},\n\tconstituents_layers: {\n\t\tlabel: i18n.t('i18n.constituentsLayers'),\n\t\tuserLevel: 7,\n\t},\n\tconstituents_pages: {\n\t\tlabel: i18n.t('i18n.constituentsPages'),\n\t\tuserLevel: 7,\n\t},\n\tdetail: {\n\t\tlabel: i18n.t('i18n.detail'),\n\t\tmatrix: 'read',\n\t\tuserLevel: 2,\n\t},\n\tfileinfo: {\n\t\tlabel: i18n.t('i18n.fileinfo'),\n\t\tuserLevel: 1,\n\t},\n\tindex: {\n\t\tlabel: i18n.t('i18n.index'),\n\t\tuserLevel: 9,\n\t},\n\tlinks: {\n\t\tlabel: i18n.t('i18n.links'),\n\t\tuserLevel: 2,\n\t},\n\tmetadata: {\n\t\tlabel: i18n.t('i18n.metadata'),\n\t\tuserLevel: 2,\n\t},\n\toverview: {\n\t\tlabel: i18n.t('i18n.overview'),\n\t\tuserLevel: 2,\n\t},\n\tpermissions: {\n\t\tlabel: i18n.t('i18n.permissions'),\n\t\tuserLevel: 8,\n\t},\n\tpreview: {\n\t\tlabel: i18n.t('i18n.preview'),\n\t\tuserLevel: 1,\n\t},\n\tprojects: {\n\t\tlabel: i18n.t('i18n.projects'),\n\t\tuserLevel: 1,\n\t\tenableTest: notMobile,\n\t},\n\tpublicLinks: {\n\t\tlabel: i18n.t('i18n.publicLinks'),\n\t\tuserLevel: 7,\n\t},\n\treviews: {\n\t\tlabel: i18n.t('i18n.reviews'),\n\t\tuserLevel: 1,\n\t\tenableTest: notMobile,\n\t},\n\tusage: {\n\t\tlabel: i18n.t('i18n.usage'),\n\t\tuserLevel: 7,\n\t},\n\tversions: {\n\t\tlabel: i18n.t('i18n.versions'),\n\t\tuserLevel: 4,\n\t},\n\tviews: {\n\t\tlabel: i18n.t('i18n.views'),\n\t\tuserLevel: 2,\n\t},\n};\n\nexport default {\n\tconstituents,\n\tdragUserLevel,\n\timportTasks,\n\trenderableChanges,\n\tstatus,\n\tthings,\n};\n"],"names":["logger","getPrefixedLogger","Asset","Base","rpc","idAttribute","titleAttribute","xhrTrackProgress","xhrExcludeProgress","defaults","alphaChannel","attributeIds","attributeNames","attributeValues","bitDepth","categories","categoryid","categoryPaths","checkout","checkoutUserLabel","colorProfile","constituentIds","constituentType","creationdate","description","dpi","duration","expirationDate","file","fileFormatFamily","fileheight","fileSize2","filetype","filetypelabel","filewidth","flvPreview","geoLocationLabel","importDate","importUserLabel","inCurrentCart","latitude","locationContext","locationid","longitude","moddate","moduserid","moduserlabel","name","path","permissionMatrix","previewHeight","previewUrl","previewWidth","proofAvailable","rating","readOnly","relatedAvailable","repurposeAvailability","reviewAvailable","statDeliveries","statPreviews","status","templatable","templateCustomizable","thumbUrl","versionIds","viewIds","viewNames","visible","xmpPacketStatus","zoomAvailable","imageid","metadata","attribute1","attribute2","attribute3","attribute4","attribute5","attribute6","attribute7","attribute8","attribute9","attribute10","attribute11","attribute12","attribute13","attribute14","attribute15","attribute16","hasChildren","parentId","activatingTemplate","deactivatingTemplate","audioUrl","videoUrl","zoomUrl","clientAttrs","methods","read","update","opts","this","self","remove","expireAsset","importAsset","reserve","addCategory","d","$","Deferred","setAssetCategoryLink","_","extend","link","then","response","resolveWith","reject","Error","i18n","promise","removeCategory","id","linkCategory","setCategory","setCategories","repurpose","manualRepurpose","repurposeOtherIds","repurposeMethods","repurposeValues","resync","assetInCurrentCart","_getCarts","cancelCheckout","get","checkPendingTasks","checkStatus","getConstituents","getProcessListForUser","recordViewed","makeZoomTiles","activateAdBuilderTemplate","deactivateAdBuilderTemplate","parsers","set","silent","trigger","uuid","batchJob","trackBatchJob","undefined","completed","fetch","assetId","dispatcher","console","warn","cat","cats","join","linkCategories","ids","constructor","attr","super","deleteWait","importAttributes","collisionStrategy","fail","rename","messageType","objectContext","repurposeId","repurposeDownloadOverride","version","AssetVersionModel","addSubModel","setMediaUrls","setChecksum","progress","ProgressModel","constituents","AssetConstituentsCollection","addSubCollection","listenTo","model","options","clear","versions","length","creationDate","fileSize","fileTypeId","fileTypeLabel","userId","userLabel","oldAssetId","_previousAttributes","setupCustomThumbnailListeners","setupAssetTaskListeners","error","asset","template","m","cid","attributes","indexOf","has","progressMessage","complete","reset","clip","isNew","clips","add","setupAssetCheckinListeners","parse","resp","omit","hasAudio","hasVideo","hasZoom","apply","concat","validate","attrs","isNumber","canZoom","isImage","getPreference","expire","dateStr","expirationTime","userInputToExpirationTime","ex","fetchConstituents","duplicateQueryPolicy","garbageCollect","getAttribute","templateId","attrModel","value","getSystemAttribute","format","parseInValue","getAttributeId","getAttributeValue","attrName","isArray","getTokenString","token","session","getWaveformJSON","getJSON","json","data","url","tokenStr","hasFormatFamily","contains","hasMultimedia","setAttribute","val","isString","idx","isCSV","isTrueMultivalue","arrayToCsv","clone","attributePermissions","stopListening","delay","bind","newVersion","task","tempIconPattern","previewNow","match","patienceExhausted","timesPolled","pollUntil","realProgress","tasks","importTasks","eventPrefix","updating","pluploader","parseInt","percent","checksumEnabled","unexpire","setCombo","vals","getCombo","csvToArray","moveCategory","from","to","resolve","isNaN","Array","without","forEach","catId","isDocument","isPDF","includes","isLocked","lock","save","_objectSpread","wait","toAssetSet","AssetSetModel","type","assetSetTypes","models","label","unlock","cacheBuster","prefix","dateFromAsset","getTime","Date","bumpModdate","date","dateToAsset","allows","perm","matrixIndex","matrixNames","cacheInMediaRich","Promise","mediarichCacheUrl","encodeURIComponent","URL","ajax","responseJSON","responseText","jqXHR","__name__","types","typeNames","AudioTask","FFFViewTask","INDDPageTask","IWorkPageTask","KeyframesTask","MetadataTask","OfficePageTask","PDFPageTask","PostImportTask","PreviewTask","RelatedAssetTask","SWFTask","ThumbnailTask","VideoPreviewTask","WatermarkTask","ZoomTask","renderableChanges","UNKNOWN","ONLINE","NEARLINE","OFFLINE","TEMP","CHECKOUT","IMPORT_IN_PROGRESS","things","attributeHistory","userLevel","enableTest","notMobile","constituents_keyframes","constituents_layers","constituents_pages","detail","matrix","fileinfo","index","links","overview","permissions","preview","projects","publicLinks","reviews","usage","views"],"sourceRoot":""}