<commit_before>'use strict';

const SEGMENT_TYPE = {
  PORT: 0x00,
  LOGICAL: 0x20,
  NETWORK: 0x40,
  SYMBOLIC: 0x60,
  DATA: 0x80,
  DATA_TYPE_CONSTRUCTED: 0xA0,
  DATA_TYPE_ELEMENTARY: 0xC0,
  RESERVED: 0xE0
};

// const kSEGMENT_TYPE = {
//   PORT: 1,
//   LOGICAL: 2,
//   NETWORK: 3,
//   SYMBOLIC: 4,
//   DATA: 5,
//   DATA_TYPE_CONSTRUCTED: 6,
//   DATA_TYPE_ELEMENTARY: 7,
//   RESERVED: 8
// };
//
// const mSEGMENT_TYPE = {
//   kSEGMENT_TYPE.PORT: SEGMENT_TYPE.PORT,
//   kSEGMENT_TYPE.LOGICAL: SEGMENT_TYPE.LOGICAL,
//   kSEGMENT_TYPE.SYMBOLIC: SEGMENT_TYPE.SYMBOLIC,
//   kSEGMENT_TYPE.DATA: SEGMENT_TYPE.DATA,
//   kSEGMENT_TYPE.DATA_TYPE_CONSTRUCTED: SEGMENT_TYPE.DATA_TYPE_CONSTRUCTED,
//   kSEGMENT_TYPE.DATA_TYPE_ELEMENTARY: SEGMENT_TYPE.DATA_TYPE_ELEMENTARY,
//   kSEGMENT_TYPE.RESERVED: RESERVED
// }

const SEGMENT_TYPE_DESCRIPTION = {
  0x00: 'Port',
  0x20: 'Logical',
  0x40: 'Network',
  0x60: 'Symbolic',
  0x80: 'Data',
  0xA0: 'Data type constructed',
  0xC0: 'Data type elementary',
  0xE0: 'Reserved'
};

const SEGMENT_TYPE_DESCRIPTION = {
  SEGMENT_TYPE.PORT: 'Port',
  SEGMENT_TYPE.LOGICAL: 'Logical',
  SEGMENT_TYPE.NETWORK: 'Network',
  SEGMENT_TYPE.SYMBOLIC: 'Symbolic',
  SEGMENT_TYPE.DATA: 'Data',
  SEGMENT_TYPE.DATA_TYPE_CONSTRUCTED: 'Data type constructed',
  SEGMENT_TYPE.DATA_TYPE_ELEMENTARY: 'Data type elementary',
  SEGMENT_TYPE.RESERVED: 'Reserved'
};

const LOGICAL_SEGMENT_TYPE = {
  CLASS_ID: 0x00,
  INSTANCE_ID: 0x04,
  MEMBER_ID: 0x08,
  CONNECTION_POINT: 0x0C,
  ATTRIBUTE_ID: 0x10,
  SPECIAL: 0x14,
  SERVICE_ID: 0x18,
  EXTENDED_LOGICAL: 0x1C
};

const LOGICAL_SEGMENT_FORMAT = {
  EIGHT_BIT: 0x00,
  SIXTEEN_BIT: 0x01,
  THIRTY_TWO_BIT: 0x02
};

const LOGICAL_SEGMENT_EXTENDED_TYPE = {
  RESERVED: 0x00,
  ARRAY_INDEX: 0x01,
  INDIRECT_ARRAY_INDEX: 0x02,
  BIT_INDEX: 0x03,
  INDIRECT_BIT_INDEX: 0x04,
  STRUCTURE_MEMBER_NUMBER: 0x05,
  STRUCTURE_MEMBER_HANDLE: 0x06
};

const NETWORK_SEGMENT = {
  SCHEDULE: 0x01,
  FIXED_TAG: 0x02,
  PRODUCTION_INHIBIT_TIME_IN_MILLISECONDS: 0x03,
  SAFETY: 0x04,
  PRODUCTION_INHIBIT_TIME_IN_MICROSECONDS: 0x10,
  EXTENDED_NETWORK: 0x1F
};

// CIP Vol1 Appendix C-1.4.4
const SYMBOLIC_SEGMENT_EXTENDED_FORMAT = {
  DOUBLE_BYTE_CHARS: 0x20,
  TRIPLE_BYTE_CHARS: 0x40,
  NUMERIC: 0xC0
};

const SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC = {
  USINT: 0x06,
  UINT: 0x07,
  UDINT: 0x08
};

const SYMBOLIC_SEGMENT_EXTENDED_FORMAT_DESCRIPTION = {
  SYMBOLIC_SEGMENT_EXTENDED_FORMAT.DOUBLE_BYTE_CHARS: 'Double-byte characters',
  SYMBOLIC_SEGMENT_EXTENDED_FORMAT.TRIPLE_BYTE_CHARS: 'Triple-byte characters'
  SYMBOLIC_SEGMENT_EXTENDED_FORMAT.NUMERIC: 'Numeric'
};

const SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC_DESCRIPTIONS = {
  SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC.USINT: 'USINT',
  SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC.UINT: 'UINT',
  SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC: 'UDINT'
};

const kSYMBOLIC_SEGMENT_FORMAT = {
  ASCII: 1,
  EXTENDED_STRING: 2
};
const kSYMBOLIC_SEGMENT_FORMAT_DESCRIPTIONS = {
  SYMBOLIC_SEGMENT_FORMAT.ASCII: 'ASCII',
  SYMBOLIC_SEGMENT_FORMAT.EXTENDED_STRING: 'Extended string'
};

// CIP Vol1 Appendix C-1.4.5
const DATA_SEGMENT_SUBTYPE = {
  SIMPLE_DATA: 0x00,
  ANSI_EXTENDED_SYMBOL: 0x11
};

const DATA_SEGMENT_SUBTYPE_DESCRIPTIONS = {
  DATA_SEGMENT_SUBTYPE.SIMPLE_DATA: 'Simple data',
  DATA_SEGMENT_SUBTYPE.ANSI_EXTENDED_SYMBOL: 'ANSI extended symbol'
};

// const __SYMBOLIC_SEGMENT_FORMAT = {
//   EXTENDED_STRING: 0x00
// };

// // Segment type enum
// const kSEGMENT_TYPE = {
//   PORT: 1,
//   LOGICAL: 2,
//   NETWORK: 3,
//   SYMBOLIC: 4,
//   DATA: 5,
//   DATA_TYPE_CONSTRUCTED: 6,
//   DATA_TYPE_ELEMENTARY: 7,
//   RESERVED: 8
// };
//
// const kLOGICAL_SEGMENT_TYPE = {
//   CLASS_ID: 1,
//   INSTANCE_ID: 2,
//   MEMBER_ID: 3,
//   CONNECTION_POINT: 4,
//   ATTRIBUTE_ID: 5,
//   SPECIAL: 6,
//   SERVICE_ID: 7,
//   EXTENDED_LOGICAL: 8
// };
//
// const kEXTENDED_LOGICAL_TYPE = {
//   RESERVED: 1,
//   ARRAY_INDEX: 2,
//   INDIRECT_ARRAY_INDEX: 3,
//   BIT_INDEX: 4,
//   INDIRECT_BIT_INDEX: 5,
//   STRUCTURE_MEMBER_NUMBER: 6,
//   STRUCTURE_MEMBER_HANDLE: 7
// };
//
// const kNETWORK_SEGMENT = {
//   RESERVED: 1,
//   SCHEDULE: 2,
//   FIXED_TAG: 3,
//   PRODUCTION_INHIBIT_TIME_IN_MILLISECONDS: 4,
//   SAFETY: 5,
//   PRODUCTION_INHIBIT_TIME_IN_MICROSECONDS: 6,
//   EXTENDED_NETWORK: 7
// };
//
// const kDATA_SEGMENT_SUBTYPE = {
//   RESERVED: 1,
//   SIMPLE_DATA: 2,
//   ANSI_EXTENDED_SYMBOL: 3
// };
//
// const kSYMBOLIC_SEGMENT_EXTENDED_FORMAT = {
//   DOUBLE_BYTE_CHARS: 1,
//   TRIPLE_BYTE_CHARS: 2,
//   NUMERIC_SYMBOL_USINT: 3,
//   NUMERIC_SYMBOL_UINT: 4,
//   NUMERIC_SYMBOL_UDINT: 5,
//   RESERVED: 6
// };

function __ASSERT(expression, errorDescription) {
  if (!expression) {
    throw new Error(errorDescription);
  }
}

function __getDescription(descriptions, code, unknown) {
  let description = descriptions[code];
  if (!description) description = unknown || 'Unknown';
  return unknown;
}

function getSegmentType(path, offset) {
  const SEGMENT_TYPE_MASK = 0xE0;
  return path[offset] & SEGMENT_TYPE_MASK;
}

function setSegmentType(path, offset, type) {
  path[offset] |= type;
}

function getSegmentTypeDescription(segmentType) {
  return __getDescription(SEGMENT_TYPE_DESCRIPTION, segmentType);
}

function getPortSegmentExtendedLinkAddressSizeBit(path, offset) {
  const EXTENDED_LINK_ADDRESS_SIZE_MASK = 0x10;
  return EXTENDED_LINK_ADDRESS_SIZE_MASK === (path[offset] & EXTENDED_LINK_ADDRESS_SIZE_MASK);
}

function getPortSegmentPortIdentifier(path, offset) {
  const PORT_IDENTIFIER_MASK = 0x0F;
  // __ASSERT(getPathPortSegmentPortIdentifier(path, offset) === SEGMENT_TYPE.PORT, 'Segment type is not Port');
  // __ASSER(path[offset] & PORT_IDENTIFIER_MASK === 0, 'Port cannot be 0');
  return path[offset] & PORT_IDENTIFIER_MASK;
}

function setPortSegmentPortIdentifier(path, offset, identifier) {
  path[offset] |= identifier;
}

function getPortSegmentLinkAddressSize(path, offset) {
  return path[offset + 1];
}

function getPortSegmentExtendedPortNumber(path, offset) {
  // __ASSERT(getPathPortSegmentPortIdentifier(path, offset) === SEGMENT_TYPE.PORT, 'Segment type is not Port');
  let position = getPathPortSegmentExtendedLinkAddressSizeBit(path, offset) === true ? 2 : 1;
  // return path[offset + position] + (path[offset + possition + 1] << 8);
  return path.readUInt16LE(offset + position);
}

function setPortSegmentExtendedPortIdentifier(path, offset, identifier) {
  setPathPortSegmentPortIdentifier(path, offset, identifier);
  let position = getPathPortSegmentExtendedLinkAddressSizeBit(path, offset) === true ? 2 : 1;
  // path[offset + position] = identifier & 0x00FF;
  // path[offset + position + 1] = identifier & 0xFF00 >> 8;
  path.writeUInt16LE(offset + position, identifier);
}

function getLogicalSegmentLogicalType(path, offset) {
  const LOGICAL_TYPE_MASK = 0x1C;
  return path[offset] & LOGICAL_TYPE_MASK;
}

function getLogicalSegmentLogicalFormat(path, offset) {
  const LOGICAL_FORMAT_MASK = 0x03;
  return path[offset] & LOGICAL_FORMAT_MASK;
}

function getLogicalSegmentExtendedLogicalType(path, offset) {
  return path[offset + 1];
}

function getLogicalSegmentSpecialTypeLogicalType(path, offset) {
  const LOGICAL_FORMAT_MASK = 0x03;
  return path[offset] & LOGICAL_FORMAT_MASK;
}

function getLogicalSegmentElectronicKeyFormat(path, offset) {
  return path[offset + 1];
}

function getLogicalSegmentElectronicKeyFormat4(path, offset) {
  offset += 2;
  let key = {};
  key.vendorId = path.readUInt16LE(offset); offset += 2;
  key.deviceType = path.readUInt16LE(offset); offset += 2;
  key.productCode = path.readUInt16LE(offset); offset += 2;
  key.majorRevision = path.readUInt8(offset); offset += 1;
  key.minorRevision = path.readUInt8(offset);
  return key;
}

function getNextorkSegmentSubtype(path, offset) {
  const NETWORK_SUBTYPE_MASK = 0x1F;
  return path[offset] & NETWORK_SUBTYPE_MASK;
}

function getNetworkSegmentProductionInhibitTimeInMilliseconds(path, offset) {
  return path.readUInt8(offset + 1);
}

function getNetworkSegmentProductionInhibitTimeInMicroseconds(path, offset) {
  return path.readUInt32LE(offset + 2);
}

function getSymbolicSegmentFormat(path, offset) {
  const SYMBOLIC_FORMAT_MASK = 0x1F;
  // if (path[offset] & SYMBOLIC_FORMAT_MASK === __SYMBOLIC_SEGMENT_FORMAT.EXTENDED_STRING) {
  if (path[offset] & SYMBOLIC_FORMAT_MASK === 0x00) {
    return kSYMBOLIC_SEGMENT_FORMAT.EXTENDED_STRING;
  }
  return kSYMBOLIC_SEGMENT_FORMAT.ASCII;
}

function getSymbolicSegmentFormatDescription(path, offset) {
  return kSYMBOLIC_SEGMENT_FORMAT_DESCRIPTIONS[getSymbolicSegmentFormat(path, offset)];
}

function getSymbolicSegmentASCIIFormatLength(path, offset) {
  const ASCII_FORMAT_LENGTH_MASK = 0x1F;
  return path[offset] & ASCII_FORMAT_LENGTH_MASK;
}

function getSymbolicSegmentNumericType(path, offset) {
  const EXTENDED_FORMAT_NUMERIC_TYPE_MASK = 0x1F;
  return path.readUInt8(offset + 1) & EXTENDED_FORMAT_NUMERIC_TYPE_MASK;
}

function getSymbolicSegmentExtendedFormat(path, offset) {
  const SYMBOLIC_SEGMENT_EXTENDED_FORMAT_MASK = 0xE0;
  return path.readUInt8(offset + 1) & SYMBOLIC_SEGMENT_EXTENDED_FORMAT_MASK;
}

function getDataSegmentSubType(path, offset) {
  return path.readUInt8(offset) & 0x1F;
}

function getDataSegmentSimpleDataWordLength(path, offset) {
  return path.readUInt8(offset + 1);
}

function getDataSegmentSubTypeDescription(subtype) {
  return __getDescription(DATA_SEGMENT_SUBTYPE_DESCRIPTIONS, subtype);
}
<commit_msg>Added more descriptions<commit_after>'use strict';

const SEGMENT_TYPE = {
  PORT: 0x00,
  LOGICAL: 0x20,
  NETWORK: 0x40,
  SYMBOLIC: 0x60,
  DATA: 0x80,
  DATA_TYPE_CONSTRUCTED: 0xA0,
  DATA_TYPE_ELEMENTARY: 0xC0,
  RESERVED: 0xE0
};

// const kSEGMENT_TYPE = {
//   PORT: 1,
//   LOGICAL: 2,
//   NETWORK: 3,
//   SYMBOLIC: 4,
//   DATA: 5,
//   DATA_TYPE_CONSTRUCTED: 6,
//   DATA_TYPE_ELEMENTARY: 7,
//   RESERVED: 8
// };
//
// const mSEGMENT_TYPE = {
//   kSEGMENT_TYPE.PORT: SEGMENT_TYPE.PORT,
//   kSEGMENT_TYPE.LOGICAL: SEGMENT_TYPE.LOGICAL,
//   kSEGMENT_TYPE.SYMBOLIC: SEGMENT_TYPE.SYMBOLIC,
//   kSEGMENT_TYPE.DATA: SEGMENT_TYPE.DATA,
//   kSEGMENT_TYPE.DATA_TYPE_CONSTRUCTED: SEGMENT_TYPE.DATA_TYPE_CONSTRUCTED,
//   kSEGMENT_TYPE.DATA_TYPE_ELEMENTARY: SEGMENT_TYPE.DATA_TYPE_ELEMENTARY,
//   kSEGMENT_TYPE.RESERVED: RESERVED
// }

const SEGMENT_TYPE_DESCRIPTIONS = {
  SEGMENT_TYPE.PORT: 'Port',
  SEGMENT_TYPE.LOGICAL: 'Logical',
  SEGMENT_TYPE.NETWORK: 'Network',
  SEGMENT_TYPE.SYMBOLIC: 'Symbolic',
  SEGMENT_TYPE.DATA: 'Data',
  SEGMENT_TYPE.DATA_TYPE_CONSTRUCTED: 'Data type constructed',
  SEGMENT_TYPE.DATA_TYPE_ELEMENTARY: 'Data type elementary',
  SEGMENT_TYPE.RESERVED: 'Reserved'
};

const LOGICAL_SEGMENT_TYPE = {
  CLASS_ID: 0x00,
  INSTANCE_ID: 0x04,
  MEMBER_ID: 0x08,
  CONNECTION_POINT: 0x0C,
  ATTRIBUTE_ID: 0x10,
  SPECIAL: 0x14,
  SERVICE_ID: 0x18,
  EXTENDED_LOGICAL: 0x1C
};
const LOGICAL_SEGMENT_TYPE_DESCRIPTIONS = {
  LOGICAL_SEGMENT_TYPE.CLASS_ID: 'Class Id',
  LOGICAL_SEGMENT_TYPE.INSTANCE_ID: 'Instance Id',
  LOGICAL_SEGMENT_TYPE.MEMBER_ID: 'Member Id',
  LOGICAL_SEGMENT_TYPE.CONNECTION_POINT: 'Connection point',
  LOGICAL_SEGMENT_TYPE.ATTRIBUTE_ID: 'Attribute Id',
  LOGICAL_SEGMENT_TYPE.SPECIAL: 'Special',
  LOGICAL_SEGMENT_TYPE.SERVICE_ID: 'Service Id',
  LOGICAL_SEGMENT_TYPE.EXTENDED_LOGICAL: 'Extended logical'
}

const LOGICAL_SEGMENT_FORMAT = {
  EIGHT_BIT: 0x00,
  SIXTEEN_BIT: 0x01,
  THIRTY_TWO_BIT: 0x02
};
const LOGICAL_SEGMENT_FORMAT_DESCRIPTIONS = {
  LOGICAL_SEGMENT_FORMAT.EIGHT_BIT: 'Eight bit',
  LOGICAL_SEGMENT_FORMAT.SIXTEEN_BIT: 'Sixteen bit',
  LOGICAL_SEGMENT_FORMAT.THIRTY_TWO_BIT: 'Thirty two bit'
};

const LOGICAL_SEGMENT_EXTENDED_TYPE = {
  RESERVED: 0x00,
  ARRAY_INDEX: 0x01,
  INDIRECT_ARRAY_INDEX: 0x02,
  BIT_INDEX: 0x03,
  INDIRECT_BIT_INDEX: 0x04,
  STRUCTURE_MEMBER_NUMBER: 0x05,
  STRUCTURE_MEMBER_HANDLE: 0x06
};
const LOGICAL_SEGMENT_EXTENDED_TYPE_DESCRIPTIONS = {
  LOGICAL_SEGMENT_EXTENDED_TYPE.RESERVED: 'Reserved',
  LOGICAL_SEGMENT_EXTENDED_TYPE.ARRAY_INDEX: 'Array index',
  LOGICAL_SEGMENT_EXTENDED_TYPE.INDIRECT_ARRAY_INDEX: 'Indirect array index',
  LOGICAL_SEGMENT_EXTENDED_TYPE.BIT_INDEX: 'Bit index',
  LOGICAL_SEGMENT_EXTENDED_TYPE.INDIRECT_BIT_INDEX: 'Indirect bit index',
  LOGICAL_SEGMENT_EXTENDED_TYPE.STRUCTURE_MEMBER_NUMBER: 'Structure member number',
  LOGICAL_SEGMENT_EXTENDED_TYPE.STRUCTURE_MEMBER_HANDLE: 'Structure member handle'
};

const LOGICAL_SEGMENT_SPECIAL_TYPE_FORMAT = {
  ELECTRONIC_KEY: 0x00
};
const LOGICAL_SEGMENT_SPECIAL_TYPE_FORMAT_DESCRIPTIONS = {
  LOGICAL_SEGMENT_SPECIAL_TYPE_FORMAT.ELECTRONIC_KEY: 'Electronic key'
}

const NETWORK_SEGMENT_SUBTYPE = {
  SCHEDULE: 0x01,
  FIXED_TAG: 0x02,
  PRODUCTION_INHIBIT_TIME_IN_MILLISECONDS: 0x03,
  SAFETY: 0x04,
  PRODUCTION_INHIBIT_TIME_IN_MICROSECONDS: 0x10,
  EXTENDED_NETWORK: 0x1F
};
const NETWORK_SEGMENT_SUBTYPE_DESCRIPTIONS = {
  NETWORK_SEGMENT_SUBTYPE.SCHEDULE: 'Schedule',
  NETWORK_SEGMENT_SUBTYPE.FIXED_TAG: 'Fixed tag',
  NETWORK_SEGMENT_SUBTYPE.PRODUCTION_INHIBIT_TIME_IN_MILLISECONDS: 'Production inhibit time in milliseconds',
  NETWORK_SEGMENT_SUBTYPE.SAFETY: 'Safety',
  NETWORK_SEGMENT_SUBTYPE.PRODUCTION_INHIBIT_TIME_IN_MICROSECONDS: 'Production inhibit time in microseconds',
  NETWORK_SEGMENT_SUBTYPE.EXTENDED_NETWORK: 'Extended network'
};

// CIP Vol1 Appendix C-1.4.4
const SYMBOLIC_SEGMENT_EXTENDED_FORMAT = {
  DOUBLE_BYTE_CHARS: 0x20,
  TRIPLE_BYTE_CHARS: 0x40,
  NUMERIC: 0xC0
};

const SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC = {
  USINT: 0x06,
  UINT: 0x07,
  UDINT: 0x08
};

const SYMBOLIC_SEGMENT_EXTENDED_FORMAT_DESCRIPTIONS = {
  SYMBOLIC_SEGMENT_EXTENDED_FORMAT.DOUBLE_BYTE_CHARS: 'Double-byte characters',
  SYMBOLIC_SEGMENT_EXTENDED_FORMAT.TRIPLE_BYTE_CHARS: 'Triple-byte characters'
  SYMBOLIC_SEGMENT_EXTENDED_FORMAT.NUMERIC: 'Numeric'
};

const SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC_DESCRIPTIONS = {
  SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC.USINT: 'USINT',
  SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC.UINT: 'UINT',
  SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC: 'UDINT'
};

const kSYMBOLIC_SEGMENT_FORMAT = {
  ASCII: 1,
  EXTENDED_STRING: 2
};
const kSYMBOLIC_SEGMENT_FORMAT_DESCRIPTIONS = {
  SYMBOLIC_SEGMENT_FORMAT.ASCII: 'ASCII',
  SYMBOLIC_SEGMENT_FORMAT.EXTENDED_STRING: 'Extended string'
};

// CIP Vol1 Appendix C-1.4.5
const DATA_SEGMENT_SUBTYPE = {
  SIMPLE_DATA: 0x00,
  ANSI_EXTENDED_SYMBOL: 0x11
};
const DATA_SEGMENT_SUBTYPE_DESCRIPTIONS = {
  DATA_SEGMENT_SUBTYPE.SIMPLE_DATA: 'Simple data',
  DATA_SEGMENT_SUBTYPE.ANSI_EXTENDED_SYMBOL: 'ANSI extended symbol'
};

// const __SYMBOLIC_SEGMENT_FORMAT = {
//   EXTENDED_STRING: 0x00
// };

// // Segment type enum
// const kSEGMENT_TYPE = {
//   PORT: 1,
//   LOGICAL: 2,
//   NETWORK: 3,
//   SYMBOLIC: 4,
//   DATA: 5,
//   DATA_TYPE_CONSTRUCTED: 6,
//   DATA_TYPE_ELEMENTARY: 7,
//   RESERVED: 8
// };
//
// const kLOGICAL_SEGMENT_TYPE = {
//   CLASS_ID: 1,
//   INSTANCE_ID: 2,
//   MEMBER_ID: 3,
//   CONNECTION_POINT: 4,
//   ATTRIBUTE_ID: 5,
//   SPECIAL: 6,
//   SERVICE_ID: 7,
//   EXTENDED_LOGICAL: 8
// };
//
// const kEXTENDED_LOGICAL_TYPE = {
//   RESERVED: 1,
//   ARRAY_INDEX: 2,
//   INDIRECT_ARRAY_INDEX: 3,
//   BIT_INDEX: 4,
//   INDIRECT_BIT_INDEX: 5,
//   STRUCTURE_MEMBER_NUMBER: 6,
//   STRUCTURE_MEMBER_HANDLE: 7
// };
//
// const kNETWORK_SEGMENT = {
//   RESERVED: 1,
//   SCHEDULE: 2,
//   FIXED_TAG: 3,
//   PRODUCTION_INHIBIT_TIME_IN_MILLISECONDS: 4,
//   SAFETY: 5,
//   PRODUCTION_INHIBIT_TIME_IN_MICROSECONDS: 6,
//   EXTENDED_NETWORK: 7
// };
//
// const kDATA_SEGMENT_SUBTYPE = {
//   RESERVED: 1,
//   SIMPLE_DATA: 2,
//   ANSI_EXTENDED_SYMBOL: 3
// };
//
// const kSYMBOLIC_SEGMENT_EXTENDED_FORMAT = {
//   DOUBLE_BYTE_CHARS: 1,
//   TRIPLE_BYTE_CHARS: 2,
//   NUMERIC_SYMBOL_USINT: 3,
//   NUMERIC_SYMBOL_UINT: 4,
//   NUMERIC_SYMBOL_UDINT: 5,
//   RESERVED: 6
// };

function __ASSERT(expression, errorDescription) {
  if (!expression) {
    throw new Error(errorDescription);
  }
}

function __getDescription(descriptions, code, unknown) {
  let description = descriptions[code];
  if (!description) description = unknown || 'Unknown';
  return unknown;
}

function getSegmentType(path, offset) {
  const SEGMENT_TYPE_MASK = 0xE0;
  return path[offset] & SEGMENT_TYPE_MASK;
}

function setSegmentType(path, offset, type) {
  path[offset] |= type;
}

function getSegmentTypeDescription(segmentType) {
  return __getDescription(SEGMENT_TYPE_DESCRIPTIONS, segmentType);
}

function getPortSegmentExtendedLinkAddressSizeBit(path, offset) {
  const EXTENDED_LINK_ADDRESS_SIZE_MASK = 0x10;
  return EXTENDED_LINK_ADDRESS_SIZE_MASK === (path[offset] & EXTENDED_LINK_ADDRESS_SIZE_MASK);
}

function getPortSegmentPortIdentifier(path, offset) {
  const PORT_IDENTIFIER_MASK = 0x0F;
  // __ASSERT(getPathPortSegmentPortIdentifier(path, offset) === SEGMENT_TYPE.PORT, 'Segment type is not Port');
  // __ASSER(path[offset] & PORT_IDENTIFIER_MASK === 0, 'Port cannot be 0');
  return path[offset] & PORT_IDENTIFIER_MASK;
}

function setPortSegmentPortIdentifier(path, offset, identifier) {
  path[offset] |= identifier;
}

function getPortSegmentLinkAddressSize(path, offset) {
  return path[offset + 1];
}

function getPortSegmentExtendedPortNumber(path, offset) {
  // __ASSERT(getPathPortSegmentPortIdentifier(path, offset) === SEGMENT_TYPE.PORT, 'Segment type is not Port');
  let position = getPathPortSegmentExtendedLinkAddressSizeBit(path, offset) === true ? 2 : 1;
  // return path[offset + position] + (path[offset + possition + 1] << 8);
  return path.readUInt16LE(offset + position);
}

function setPortSegmentExtendedPortIdentifier(path, offset, identifier) {
  setPathPortSegmentPortIdentifier(path, offset, identifier);
  let position = getPathPortSegmentExtendedLinkAddressSizeBit(path, offset) === true ? 2 : 1;
  // path[offset + position] = identifier & 0x00FF;
  // path[offset + position + 1] = identifier & 0xFF00 >> 8;
  path.writeUInt16LE(offset + position, identifier);
}

function getLogicalSegmentLogicalType(path, offset) {
  const LOGICAL_TYPE_MASK = 0x1C;
  return path[offset] & LOGICAL_TYPE_MASK;
}
function getLogicalSegmentLogicalTypeDescription(type) {
  return __getDescription(LOGICAL_SEGMENT_TYPE_DESCRIPTIONS, type);
}

function getLogicalSegmentLogicalFormat(path, offset) {
  const LOGICAL_FORMAT_MASK = 0x03;
  return path[offset] & LOGICAL_FORMAT_MASK;
}
function getLogicalSegmentLogicalFormatDescription(format) {
  return __getDescription(LOGICAL_SEGMENT_FORMAT_DESCRIPTIONS, format);
}

function getLogicalSegmentExtendedLogicalType(path, offset) {
  return path[offset + 1];
}
function getLogicalSegmentExtendedLogicalTypeDescription(type) {
  return __getDescription(LOGICAL_SEGMENT_EXTENDED_TYPE_DESCRIPTIONS, type);
}

function getLogicalSegmentSpecialTypeLogicalType(path, offset) {
  const LOGICAL_FORMAT_MASK = 0x03;
  return path[offset] & LOGICAL_FORMAT_MASK;
}
function getLogicalSegmentSpecialTypeLogicalTypeDescription(type) {
  return __getDescription(LOGICAL_SEGMENT_SPECIAL_TYPE_FORMAT_DESCRIPTIONS, type);
}

function getLogicalSegmentElectronicKeyFormat(path, offset) {
  return path[offset + 1];
}

function getLogicalSegmentElectronicKeyFormat4(path, offset) {
  offset += 2;
  let key = {};
  key.vendorId = path.readUInt16LE(offset); offset += 2;
  key.deviceType = path.readUInt16LE(offset); offset += 2;
  key.productCode = path.readUInt16LE(offset); offset += 2;
  key.majorRevision = path.readUInt8(offset); offset += 1;
  key.minorRevision = path.readUInt8(offset);
  return key;
}

function getNetworkSegmentSubtype(path, offset) {
  const NETWORK_SUBTYPE_MASK = 0x1F;
  return path[offset] & NETWORK_SUBTYPE_MASK;
}
function getNetworkSegmentSubtypeDescription(subtype) {
  return __getDescription(NETWORK_SEGMENT_SUBTYPE_DESCRIPTIONS, subtype);
}

function getNetworkSegmentProductionInhibitTimeInMilliseconds(path, offset) {
  return path.readUInt8(offset + 1);
}

function getNetworkSegmentProductionInhibitTimeInMicroseconds(path, offset) {
  return path.readUInt32LE(offset + 2);
}

function getSymbolicSegmentFormat(path, offset) {
  const SYMBOLIC_FORMAT_MASK = 0x1F;
  // if (path[offset] & SYMBOLIC_FORMAT_MASK === __SYMBOLIC_SEGMENT_FORMAT.EXTENDED_STRING) {
  if (path[offset] & SYMBOLIC_FORMAT_MASK === 0x00) {
    return kSYMBOLIC_SEGMENT_FORMAT.EXTENDED_STRING;
  }
  return kSYMBOLIC_SEGMENT_FORMAT.ASCII;
}
function getSymbolicSegmentFormatDescription(format) {
  return __getDescription(kSYMBOLIC_SEGMENT_FORMAT_DESCRIPTIONS, format);
  // return kSYMBOLIC_SEGMENT_FORMAT_DESCRIPTIONS[format];
}

function getSymbolicSegmentASCIIFormatLength(path, offset) {
  const ASCII_FORMAT_LENGTH_MASK = 0x1F;
  return path[offset] & ASCII_FORMAT_LENGTH_MASK;
}

function getSymbolicSegmentNumericType(path, offset) {
  const EXTENDED_FORMAT_NUMERIC_TYPE_MASK = 0x1F;
  return path.readUInt8(offset + 1) & EXTENDED_FORMAT_NUMERIC_TYPE_MASK;
}
function getSymbolicSegmentNumericTypeDescription(type) {
  return __getDescription(SYMBOLIC_SEGMENT_EXTENDED_FORMAT_NUMERIC_DESCRIPTIONS, type);
}

function getSymbolicSegmentExtendedFormat(path, offset) {
  const SYMBOLIC_SEGMENT_EXTENDED_FORMAT_MASK = 0xE0;
  return path.readUInt8(offset + 1) & SYMBOLIC_SEGMENT_EXTENDED_FORMAT_MASK;
}
function getSymbolicSegmentExtendedFormatDescription(format) {
  return __getDescription(SYMBOLIC_SEGMENT_EXTENDED_FORMAT_DESCRIPTIONS, format);
}

function getDataSegmentSubType(path, offset) {
  return path.readUInt8(offset) & 0x1F;
}
function getDataSegmentSubTypeDescription(subtype) {
  return __getDescription(DATA_SEGMENT_SUBTYPE_DESCRIPTIONS, subtype);
}

function getDataSegmentSimpleDataWordLength(path, offset) {
  return path.readUInt8(offset + 1);
}
<|endoftext|>


<commit_before>/* global describe, it */

'use strict';

(function () {

  var expect = require('chai').expect;

  var collect = require('../src/collect');
  var Command = require('../src/command');
  var Arg = require('../src/arg');

  describe('collect.js', function () {

    it('should exist', function () {
      expect(collect).to.be.ok;
      expect(typeof collect).to.equal('function');
    });

    it('should return an arg tree when no schema provided', function () {
      var boundCollect = collect.bind(null, 'node', 'npm', ['install', 'jargs', '--save']);

      // Without tree
      var result = boundCollect();

      expect(result).to.eql({
        command: null,
        kwargs: {},
        flags: {},
        args: {}
      });

    });

    it('should return an arg tree for single command schema', function () {
      var boundCollect = collect.bind(null, 'node', 'npm', ['install', 'jargs', '--save']);

      // With single node
      var result = boundCollect(
        Command(
          'install'
        )
      );

      expect(result).to.eql({
        command: {
          name: 'install',
          command: null,
          kwargs: {},
          flags: {},
          args: {}
        },
        kwargs: {},
        flags: {},
        args: {}
      });

    });

    it('should return an arg tree with nested schema', function () {
      var boundCollect = collect.bind(null, 'node', 'npm', ['install', 'jargs', '--save']);

      // With nested nodes
      var result = boundCollect(
        Command(
          'install',
          null,
          Arg(
            'lib'
          )
        )
      );

      expect(result).to.eql({
        command: {
          name: 'install',
          command: null,
          kwargs: {},
          flags: {},
          args: {
            lib: {
              value: 'jargs',
              command: null,
              kwargs: {},
              flags: {},
              args: {}
            }
          }
        },
        kwargs: {},
        flags: {},
        args: {}
      });
    });

  });

})();
<commit_msg>Test tree when no args provided<commit_after>/* global describe, it */

'use strict';

(function () {

  var expect = require('chai').expect;

  var collect = require('../src/collect');
  var Command = require('../src/command');
  var Arg = require('../src/arg');

  describe('collect.js', function () {

    it('should exist', function () {
      expect(collect).to.be.ok;
      expect(typeof collect).to.equal('function');
    });

    it('should return an arg tree when no args provided', function () {
      var boundCollect = collect.bind(null, 'node', 'npm', []);

      // Without tree
      var result = boundCollect(
        Command(
          'install'
        )
      );

      expect(result).to.eql({
        command: null,
        kwargs: {},
        flags: {},
        args: {}
      });

    });

    it('should return an arg tree when no schema provided', function () {
      var boundCollect = collect.bind(null, 'node', 'npm', ['install', 'jargs', '--save']);

      // Without tree
      var result = boundCollect();

      expect(result).to.eql({
        command: null,
        kwargs: {},
        flags: {},
        args: {}
      });

    });

    it('should return an arg tree for single command schema', function () {
      var boundCollect = collect.bind(null, 'node', 'npm', ['install', 'jargs', '--save']);

      // With single node
      var result = boundCollect(
        Command(
          'install'
        )
      );

      expect(result).to.eql({
        command: {
          name: 'install',
          command: null,
          kwargs: {},
          flags: {},
          args: {}
        },
        kwargs: {},
        flags: {},
        args: {}
      });

    });

    it('should return an arg tree with nested schema', function () {
      var boundCollect = collect.bind(null, 'node', 'npm', ['install', 'jargs', '--save']);

      // With nested nodes
      var result = boundCollect(
        Command(
          'install',
          null,
          Arg(
            'lib'
          )
        )
      );

      expect(result).to.eql({
        command: {
          name: 'install',
          command: null,
          kwargs: {},
          flags: {},
          args: {
            lib: {
              value: 'jargs',
              command: null,
              kwargs: {},
              flags: {},
              args: {}
            }
          }
        },
        kwargs: {},
        flags: {},
        args: {}
      });
    });

  });

})();
<|endoftext|>


<commit_before>const { Markup, Extra } = require('telegraf');
const { Scene } = require('telegraf-flow');
const curryfm = require('curryfm');

const config = require('../../config');
const Format = require('../helpers/format');
const Keyboard = require('../helpers/keyboard');
const LastfmExtra = require('../helpers/lastfm-extra');

const lfm = curryfm.default(config.LFM_TOKEN);
const track = lfm('track');
const artist = lfm('artist');

const trackMenu = new Scene('trackMenu');

//Don't forget to change .hears handler after modifying this array
const trackKeyboardButtons = [
  ['❕ Info', '🎼 Similar tracks'],
  ['🎥 YouTube video', '🎲 Random track from this artist' ],
  [ '⬅ Back' ]
];

const trackKeyboard = Markup
  .keyboard(trackKeyboardButtons)
  .resize()
  .extra();

trackMenu.enter((ctx) => {
  ctx.replyWithHTML(
    `What would you like to find out about track ` +
      `<b>${ctx.session.artist}</b> - <b>${ctx.session.track}</b>?`,
    trackKeyboard
  )
})
trackMenu.hears('❕ Info', (ctx) => {
  track('getInfo', {
    artist: ctx.session.artist,
    track: ctx.session.track,
    autocorrect: config.LFM_AUTOCORRECT,
    format: 'json'
  }).then(res => {
    if (res.error) {
      return ctx.reply(res.message);
    };
    return ctx.replyWithHTML(Format.track(res.track), Extra.webPreview(false));
  })
})
trackMenu.hears('🎼 Similar tracks', (ctx) => {
  track('getSimilar', {
    artist: ctx.session.artist,
    track: ctx.session.track,
    autocorrect: config.LFM_AUTOCORRECT,
    limit: config.SIMILAR_LIMIT,
    format: 'json'
  }).then(res => {
    if (res.error) {
      return ctx.reply(res.message);
    }
    if (res.similartracks.track.length === 0) {
      return ctx.reply('No tracks found');
    }

    return ctx.reply('Similar tracks:',
      Keyboard.similarTracks(res.similartracks.track).extra());
  })
})
trackMenu.hears('🎥 YouTube video', (ctx) => {
  return LastfmExtra.youtube(ctx.session.artist, ctx.session.track)
    .then(youtubeLink => {
      if (youtubeLink === undefined) {
        return ctx.reply('Sorry, no YouTube video were found');
      }
      return ctx.reply(`Video can be incorrect. (Sorry!) \n ${youtubeLink}`);
    })
})
trackMenu.hears('🎲 Random track from this artist', (ctx) => {
  artist('getTopTracks', {
    artist: ctx.session.artist,
    autocorrect: config.LFM_AUTOCORRECT,
    limit: 1,
    format: 'json'
  }).then(res => {
    if (res.error) {
      return ctx.reply(res.message);
    };
    return res.toptracks['@attr'].totalPages
  }).then(totalPages => {
    return LastfmExtra.randomTrack(ctx.session.artist, totalPages)
  }).then(track => {
    ctx.session.artist = track.artist.name;
    ctx.session.track = track.name;
    ctx.flow.enter('trackMenu');
  })
})
trackMenu.hears('⬅ Back', (ctx) => {
  ctx.flow.enter('artistMenu');
})
module.exports = trackMenu;
<commit_msg>Remove button to get random track from track scene<commit_after>const { Markup, Extra } = require('telegraf');
const { Scene } = require('telegraf-flow');
const curryfm = require('curryfm');

const config = require('../../config');
const Format = require('../helpers/format');
const Keyboard = require('../helpers/keyboard');
const LastfmExtra = require('../helpers/lastfm-extra');

const lfm = curryfm.default(config.LFM_TOKEN);
const track = lfm('track');
const artist = lfm('artist');

const trackMenu = new Scene('trackMenu');

//Don't forget to change .hears handler after modifying this array
const trackKeyboardButtons = [
  ['❕ Info', '🎼 Similar tracks'],
  ['🎥 YouTube video', '⬅ Back' ],
];

const trackKeyboard = Markup
  .keyboard(trackKeyboardButtons)
  .resize()
  .extra();

trackMenu.enter((ctx) => {
  ctx.replyWithHTML(
    `What would you like to find out about track ` +
      `<b>${ctx.session.artist}</b> - <b>${ctx.session.track}</b>?`,
    trackKeyboard
  )
})
trackMenu.hears('❕ Info', (ctx) => {
  track('getInfo', {
    artist: ctx.session.artist,
    track: ctx.session.track,
    autocorrect: config.LFM_AUTOCORRECT,
    format: 'json'
  }).then(res => {
    if (res.error) {
      return ctx.reply(res.message);
    };
    return ctx.replyWithHTML(Format.track(res.track), Extra.webPreview(false));
  })
})
trackMenu.hears('🎼 Similar tracks', (ctx) => {
  track('getSimilar', {
    artist: ctx.session.artist,
    track: ctx.session.track,
    autocorrect: config.LFM_AUTOCORRECT,
    limit: config.SIMILAR_LIMIT,
    format: 'json'
  }).then(res => {
    if (res.error) {
      return ctx.reply(res.message);
    }
    if (res.similartracks.track.length === 0) {
      return ctx.reply('No tracks found');
    }

    return ctx.reply('Similar tracks:',
      Keyboard.similarTracks(res.similartracks.track).extra());
  })
})
trackMenu.hears('🎥 YouTube video', (ctx) => {
  return LastfmExtra.youtube(ctx.session.artist, ctx.session.track)
    .then(youtubeLink => {
      if (youtubeLink === undefined) {
        return ctx.reply('Sorry, no YouTube video were found');
      }
      return ctx.reply(`Video can be incorrect. (Sorry!) \n ${youtubeLink}`);
    })
})
trackMenu.hears('⬅ Back', (ctx) => {
  ctx.flow.enter('artistMenu');
})
module.exports = trackMenu;
<|endoftext|>


<commit_before>/*
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';
/**
 * Internal dependencies
 */
/**
 * External dependencies
 */
import React from 'react';
import styled from 'styled-components';
import { rgba } from 'polished';
import { ReactComponent as UnsplashLogoFull } from '../../../icons/unsplash_logo_full.svg';

const AttributionPill = styled.div`
  position: absolute;
  left: 24px;
  bottom: 10px;
  border-radius: 100px;
  padding: 5px 8px;
  line-height: 16px;
  display: flex;
  flex-wrap: nowrap;
  font-size: 12px;
  color: ${({ theme }) => theme.colors.fg.white};
  background-color: ${({ theme }) => rgba(theme.colors.bg.black, 0.7)};
  cursor: pointer;
`;

const UnsplashLogo = styled(UnsplashLogoFull)`
  fill: ${({ theme }) => theme.colors.fg.white};
  margin-left: 6px;
  height: 14px;
`;

const LOGO_STYLE = {};

const unsplashUrl =
  'https://unsplash.com?utm_source=web_stories_wordpress&utm_medium=referral';
const coverrUrl = 'https://coverr.co';

export function UnsplashAttribution() {
  return (

      <AttributionPill>
        {__('Powered by', 'web-stories')}
        <UnsplashLogo />
      </AttributionPill>

  );
}

export function CoverrAttribution() {
  return (

      <AttributionPill>
        {__('Powered by', 'web-stories')}
        {'COVERR'}
      </AttributionPill>

  );
}
<commit_msg>better css<commit_after>/*
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';
/**
 * Internal dependencies
 */
/**
 * External dependencies
 */
import React from 'react';
import styled, { css } from 'styled-components';
import { rgba } from 'polished';
import { ReactComponent as UnsplashLogoFull } from '../../../icons/unsplash_logo_full.svg';

const AttributionPill = styled.div`
  position: absolute;
  left: 24px;
  bottom: 10px;
  border-radius: 100px;
  padding: 5px 8px;
  line-height: 16px;
  display: flex;
  flex-wrap: nowrap;
  font-size: 12px;
  color: ${({ theme }) => theme.colors.fg.white};
  background-color: ${({ theme }) => rgba(theme.colors.bg.black, 0.7)};
  cursor: pointer;
`;

const logo = css`
  fill: ${({ theme }) => theme.colors.fg.white};
  margin-left: 6px;
  height: 14px;
`;

const UnsplashLogo = styled(UnsplashLogoFull)`
  ${logo}
`;

const CoverrLogoSpan = styled.span`
  ${logo}
`;

const unsplashUrl =
  'https://unsplash.com?utm_source=web_stories_wordpress&utm_medium=referral';
const coverrUrl = 'https://coverr.co';

export function UnsplashAttribution() {
  return (

      <AttributionPill>
        {__('Powered by', 'web-stories')}
        <UnsplashLogo />
      </AttributionPill>

  );
}

export function CoverrAttribution() {
  return (

      <AttributionPill>
        {__('Powered by', 'web-stories')}
        <CoverrLogoSpan>{'COVERR'}</CoverrLogoSpan>
      </AttributionPill>

  );
}
<|endoftext|>


<commit_before>'use strict'

const extendsConfig = require('./lib/extendsConfig')

module.exports = extendsConfig({
  extends: [
    'eslint-config-airbnb/base',
    'eslint-config-foray1010/rules/main',
    'eslint-config-foray1010/rules/react',
    'eslint-config-foray1010/rules/frontend',
    'eslint-config-foray1010/rules/es-modules',
    'eslint-config-foray1010/rules/unit-test',
    'eslint-config-foray1010/rules/babel',
    'eslint-config-foray1010/rules/ramda'
  ]
})
<commit_msg>feat: add flow to react preset<commit_after>'use strict'

const extendsConfig = require('./lib/extendsConfig')

module.exports = extendsConfig({
  extends: [
    'eslint-config-airbnb/base',
    'eslint-config-foray1010/rules/main',
    'eslint-config-foray1010/rules/frontend',
    'eslint-config-foray1010/rules/react',
    'eslint-config-foray1010/rules/es-modules',
    'eslint-config-foray1010/rules/unit-test',
    'eslint-config-foray1010/rules/babel',
    'eslint-config-foray1010/rules/flow',
    'eslint-config-foray1010/rules/ramda'
  ]
})
<|endoftext|>


<commit_before>'use strict';

var moment = require('moment'),
    angular = require('angular'),
    ngRoute = require('angular-route'),
    ngAnimate = require('angular-animate');

require('angular-loading-bar');

moment.locale('en', {
    calendar : {
        lastDay : '[Yesterday]',
        sameDay : '[Today]',
        nextDay : '[Tomorrow]',
        lastWeek : '[last] dddd',
        nextWeek : 'dddd',
        sameElse : 'L'
    }
});

//Dictionary to translate icon names to resurce names
iconDefinitions = {
    '01d' : 'wi wi-day-sunny',
    '01n' : 'wi wi-night-clear',
    '02d' : 'wi wi-day-sunny-overcast',
    '02n' : 'wi wi-night-cloudy',
    '03d' : 'wi wi-cloud',
    '03n' : 'wi wi-cloud',
    '04d' : 'wi wi-cloudy',
    '04n' : 'wi wi-cloudy',
    '09d' : 'wi wi-sprinkle',
    '09n' : 'wi wi-sprinkle',
    '10d' : 'wi wi-day-showers',
    '10n' : 'wi wi-night-showers'
}

module.exports = function init() {
    var app = angular.module('sunshine', [ngRoute, ngAnimate, 'angular-loading-bar']);

    app.controller('WeatherController', ['$window', 'WeatherService', function ($window, weatherService) {
        this.location = $window.localStorage.getItem('sunshine.settings.location');

        this.forecasts = [];
        this.selectedForecast = null;
        this.selectedForecastIdx = 0;

        weatherService
            .fetchWeeklyForecastFor(this.location)
            .then(response => {
                this.forecasts = response.data.list;
                this.selectedForecast = this.forecasts[0];
            });

        this.isLocationSet = () => !!$window.localStorage.getItem('sunshine.settings.location');
        this.selectForecast = (idx) => {
            this.selectedForecast = this.forecasts[idx];
            this.selectedForecastIdx = idx;
        };
        this.isForecastSelected = (idx) => {
            return this.selectedForecastIdx === idx;
        };

        this.sunshineIconFor = (icon) => {
            //var ret =
            return iconDefinitions[icon] || 'wi wi-umbrella';
        };
    }]);

    app.controller('SettingsController', function ($window) {
        this.location = '';

        this.updateLocation = () => {
            $window.localStorage.setItem('sunshine.settings.location', this.location);
        };

        this.isLocationSet = () => !!$window.localStorage.getItem('sunshine.settings.location');
    });

    app.service('WeatherService', function ($q, $http) {
        return {
            fetchWeeklyForecastFor: (location) => {
                return $q((resolve, reject) => {
                    var url = `http://api.openweathermap.org/data/2.5/forecast/daily?q=${location}&mode=json&units=metric&cnt=7`;

                    var request = $http.get(url);

                    request
                        .success((data, status, header, config) => {
                            resolve({data, status, header, config});
                        })
                        .error((data, status, header, config) => reject({data, status, header, config}));
                });
            }
        };
    });

    app.filter('fromNow', function () {
        return function (date) {
            return moment(date).calendar();
        };
    });

    app.config(['cfpLoadingBarProvider', function (LoadingBarProvider) {
        LoadingBarProvider.includeSpinner = false;
    }]);

    return app;
};
<commit_msg>fixed removal of horrible switch<commit_after>'use strict';

var moment = require('moment'),
    angular = require('angular'),
    ngRoute = require('angular-route'),
    ngAnimate = require('angular-animate');

require('angular-loading-bar');

moment.locale('en', {
    calendar : {
        lastDay : '[Yesterday]',
        sameDay : '[Today]',
        nextDay : '[Tomorrow]',
        lastWeek : '[last] dddd',
        nextWeek : 'dddd',
        sameElse : 'L'
    }
});

//Dictionary to translate icon names to resurce names
var iconDefinitions = {
    '01d' : 'wi wi-day-sunny',
    '01n' : 'wi wi-night-clear',
    '02d' : 'wi wi-day-sunny-overcast',
    '02n' : 'wi wi-night-cloudy',
    '03d' : 'wi wi-cloud',
    '03n' : 'wi wi-cloud',
    '04d' : 'wi wi-cloudy',
    '04n' : 'wi wi-cloudy',
    '09d' : 'wi wi-sprinkle',
    '09n' : 'wi wi-sprinkle',
    '10d' : 'wi wi-day-showers',
    '10n' : 'wi wi-night-showers'
}

module.exports = function init() {
    var app = angular.module('sunshine', [ngRoute, ngAnimate, 'angular-loading-bar']);

    app.controller('WeatherController', ['$window', 'WeatherService', function ($window, weatherService) {
        this.location = $window.localStorage.getItem('sunshine.settings.location');

        this.forecasts = [];
        this.selectedForecast = null;
        this.selectedForecastIdx = 0;

        weatherService
            .fetchWeeklyForecastFor(this.location)
            .then(response => {
                this.forecasts = response.data.list;
                this.selectedForecast = this.forecasts[0];
            });

        this.isLocationSet = () => !!$window.localStorage.getItem('sunshine.settings.location');
        this.selectForecast = (idx) => {
            this.selectedForecast = this.forecasts[idx];
            this.selectedForecastIdx = idx;
        };
        this.isForecastSelected = (idx) => {
            return this.selectedForecastIdx === idx;
        };

        this.sunshineIconFor = (icon) => {
            //If the icon is not in the dict, default to '' (no icon)
            return iconDefinitions[icon] || '';
        };
    }]);

    app.controller('SettingsController', function ($window) {
        this.location = '';

        this.updateLocation = () => {
            $window.localStorage.setItem('sunshine.settings.location', this.location);
        };

        this.isLocationSet = () => !!$window.localStorage.getItem('sunshine.settings.location');
    });

    app.service('WeatherService', function ($q, $http) {
        return {
            fetchWeeklyForecastFor: (location) => {
                return $q((resolve, reject) => {
                    var url = `http://api.openweathermap.org/data/2.5/forecast/daily?q=${location}&mode=json&units=metric&cnt=7`;

                    var request = $http.get(url);

                    request
                        .success((data, status, header, config) => {
                            resolve({data, status, header, config});
                        })
                        .error((data, status, header, config) => reject({data, status, header, config}));
                });
            }
        };
    });

    app.filter('fromNow', function () {
        return function (date) {
            return moment(date).calendar();
        };
    });

    app.config(['cfpLoadingBarProvider', function (LoadingBarProvider) {
        LoadingBarProvider.includeSpinner = false;
    }]);

    return app;
};
<|endoftext|>


<commit_before>'use-strict'

const dropdownCollapsLabel = '.dropdown-list__item--collapse .dropdown-list__label',
      dropdownItem = [ ...document.querySelectorAll(dropdownCollapsLabel) ],
      openClass    = 'dropdown-list__item--open',
      contentClass = 'dropdown-list__content',
      mqClass = 'dropdown-list\\@screen-m',
      mq = '(min-width: 768px)';

function setListHeight(item) {
  return Array.from(item.children)
    .map(elem => elem.clientHeight)
    .reduce((a, b) => a + b, 0);
}

function setAriaAttributes(label, content, expanded) {
  if (expanded) {
    label.setAttribute('aria-expanded', 'false');
    content.setAttribute('aria-hidden', 'true');
  }
  else {
    label.setAttribute('aria-expanded', 'true');
    content.setAttribute('aria-hidden', 'false');
  }
}

function isMediumOpen(dropdownBlock) {
  return (dropdownBlock.classList.contains(mqClass)) && window.matchMedia(mq).matches;
}

function resetMqMediumOpen(item) {
  const dropdownItem = item.parentNode,
        dropdownContent = dropdownItem.querySelector(`.${contentClass}`);

  if (window.matchMedia(mq).matches) {
    dropdownContent.style.height = 'auto';
    dropdownItem.classList.remove(openClass);
    setAriaAttributes(item, dropdownContent, true);
  }
  else {
    dropdownContent.style.height = 0;
    dropdownItem.classList.remove(openClass);
    setAriaAttributes(item, dropdownContent, false);
  }
}

function toggleContent(item) {
  const dropdownId      = item.dataset.dropdown,
        dropdownItem    = item.parentNode,
        dropdownContent = dropdownItem.querySelector(`.${contentClass}[data-content="${dropdownId}"]`),
        dropdownBlock   = item.closest('.dropdown-list');

  if (!isMediumOpen(dropdownBlock)) {
    if (dropdownContent.clientHeight > 0) {
      dropdownContent.style.height = 0;
      dropdownItem.classList.remove(openClass);
      setAriaAttributes(item, dropdownContent, true);
    }
    else {
      dropdownContent.style.height = `${setListHeight(dropdownContent)}px`;
      dropdownItem.classList.add(openClass);
      setAriaAttributes(item, dropdownContent, false);
    }
  }
  else {
    dropdownContent.style.height = 'auto';
    dropdownItem.classList.remove(openClass);
    setAriaAttributes(item, dropdownContent, false);
  }
}

dropdownItem.forEach(
  key => key.addEventListener('click', (e) => {
    e.preventDefault();
    toggleContent(key, false);
  }, false)
);

window.addEventListener('resize', () => {
  const dropdownMediumOpen = document.querySelector(`.${mqClass}`);
  if (dropdownMediumOpen) {
    const dropdownItems =  [ ...dropdownMediumOpen.querySelectorAll(dropdownCollapsLabel)];
    dropdownItems.forEach(key => resetMqMediumOpen(key));
  }
});
<commit_msg>#35474 formatting update - align variables<commit_after>'use-strict'

const dropdownCollapsLabel = '.dropdown-list__item--collapse .dropdown-list__label',
      dropdownItem         = [ ...document.querySelectorAll(dropdownCollapsLabel) ],
      openClass            = 'dropdown-list__item--open',
      contentClass         = 'dropdown-list__content',
      mqClass              = 'dropdown-list\\@screen-m',
      mq                   = '(min-width: 768px)';

function setListHeight(item) {
  return Array.from(item.children)
    .map(elem => elem.clientHeight)
    .reduce((a, b) => a + b, 0);
}

function setAriaAttributes(label, content, expanded) {
  if (expanded) {
    label.setAttribute('aria-expanded', 'false');
    content.setAttribute('aria-hidden', 'true');
  }
  else {
    label.setAttribute('aria-expanded', 'true');
    content.setAttribute('aria-hidden', 'false');
  }
}

function isMediumOpen(dropdownBlock) {
  return (dropdownBlock.classList.contains(mqClass)) && window.matchMedia(mq).matches;
}

function resetMqMediumOpen(item) {
  const dropdownItem = item.parentNode,
        dropdownContent = dropdownItem.querySelector(`.${contentClass}`);

  if (window.matchMedia(mq).matches) {
    dropdownContent.style.height = 'auto';
    dropdownItem.classList.remove(openClass);
    setAriaAttributes(item, dropdownContent, true);
  }
  else {
    dropdownContent.style.height = 0;
    dropdownItem.classList.remove(openClass);
    setAriaAttributes(item, dropdownContent, false);
  }
}

function toggleContent(item) {
  const dropdownId      = item.dataset.dropdown,
        dropdownItem    = item.parentNode,
        dropdownContent = dropdownItem.querySelector(`.${contentClass}[data-content="${dropdownId}"]`),
        dropdownBlock   = item.closest('.dropdown-list');

  if (!isMediumOpen(dropdownBlock)) {
    if (dropdownContent.clientHeight > 0) {
      dropdownContent.style.height = 0;
      dropdownItem.classList.remove(openClass);
      setAriaAttributes(item, dropdownContent, true);
    }
    else {
      dropdownContent.style.height = `${setListHeight(dropdownContent)}px`;
      dropdownItem.classList.add(openClass);
      setAriaAttributes(item, dropdownContent, false);
    }
  }
  else {
    dropdownContent.style.height = 'auto';
    dropdownItem.classList.remove(openClass);
    setAriaAttributes(item, dropdownContent, false);
  }
}

dropdownItem.forEach(
  key => key.addEventListener('click', (e) => {
    e.preventDefault();
    toggleContent(key, false);
  }, false)
);

window.addEventListener('resize', () => {
  const dropdownMediumOpen = document.querySelector(`.${mqClass}`);
  if (dropdownMediumOpen) {
    const dropdownItems =  [ ...dropdownMediumOpen.querySelectorAll(dropdownCollapsLabel)];
    dropdownItems.forEach(key => resetMqMediumOpen(key));
  }
});
<|endoftext|>


<commit_before>module.exports = {
  "plugins": ["react"],
  "ecmaFeatures": {
    "jsx": true
  },
  "rules": {
    "jsx-quotes": [2, "prefer-double"],
    "react/display-name": [1, { "ignoreTranspilerName": true }],
    "react/forbid-prop-types": 0,
    "react/no-danger": 2,
    "react/no-deprecated": [2, { "react": "15.0.0" }],
    "react/no-did-mount-set-state": [2, "allow-in-func"],
    "react/no-did-update-set-state": [2, "allow-in-func"],
    "react/no-direct-mutation-state": 2,
    "react/no-is-mounted": 2,
    "react/no-multi-comp": 0,
    "react/no-set-state": 0,
    "react/no-string-refs": 1,
    "react/no-unknown-property": 2,
    "react/prefer-es6-class": [1, "never"],
    "react/prefer-stateless-function": 1,
    "react/prop-types": 2,
    "react/react-in-jsx-scope": 1,
    "react/require-extension": 2,
    "react/require-render-return": 2,
    "react/self-closing-comp": 1,
    "react/sort-comp": 2,
    "react/jsx-sort-prop-types": 0,
    "react/wrap-multilines": 2,
    "react/jsx-boolean-value": [1, "always"],
    "react/jsx-closing-bracket-location": 2,
    "react/jsx-curly-spacing": [2, "always"],
    "react/jsx-equals-spacing": [2, "never"],
    "react/jsx-first-prop-new-line": [2, "multiline"],
    "react/jsx-handler-names": 1,
    "react/jsx-indent": [2, 2],
    "react/jsx-indent-props": [2, 2],
    "react/jsx-key": 2,
    "react/jsx-max-props-per-line": [1, { "maximum": 3 }],
    "react/jsx-no-bind": 0,
    "react/jsx-no-duplicate-props": 2,
    "react/jsx-no-literals": 0,
    "react/jsx-no-target-blank": 2,
    "react/jsx-no-undef": 2,
    "react/jsx-pascal-case": 2,
    "react/jsx-sort-props": 0,
    "react/jsx-space-before-closing": [2, "always"],
    "react/jsx-uses-react": 2,
    "react/jsx-uses-vars": 2,
  }
};
<commit_msg>Disable the following rules: - disable enforcing handler names begin with "handle" - disable enforcing strict method order - disable enforcing pure functions<commit_after>module.exports = {
  "plugins": ["react"],
  "ecmaFeatures": {
    "jsx": true
  },
  "rules": {
    "jsx-quotes": [2, "prefer-double"],
    "react/display-name": [1, { "ignoreTranspilerName": true }],
    "react/forbid-prop-types": 0,
    "react/no-danger": 2,
    "react/no-deprecated": [2, { "react": "15.0.0" }],
    "react/no-did-mount-set-state": [2, "allow-in-func"],
    "react/no-did-update-set-state": [2, "allow-in-func"],
    "react/no-direct-mutation-state": 2,
    "react/no-is-mounted": 2,
    "react/no-multi-comp": 0,
    "react/no-set-state": 0,
    "react/no-string-refs": 1,
    "react/no-unknown-property": 2,
    "react/prefer-es6-class": [1, "never"],
    "react/prefer-stateless-function": 0,
    "react/prop-types": 2,
    "react/react-in-jsx-scope": 1,
    "react/require-extension": 2,
    "react/require-render-return": 2,
    "react/self-closing-comp": 1,
    "react/sort-comp": 0,
    "react/jsx-sort-prop-types": 0,
    "react/wrap-multilines": 2,
    "react/jsx-boolean-value": [1, "always"],
    "react/jsx-closing-bracket-location": 2,
    "react/jsx-curly-spacing": [2, "always"],
    "react/jsx-equals-spacing": [2, "never"],
    "react/jsx-first-prop-new-line": [2, "multiline"],
    "react/jsx-handler-names": 0,
    "react/jsx-indent": [2, 2],
    "react/jsx-indent-props": [2, 2],
    "react/jsx-key": 2,
    "react/jsx-max-props-per-line": [1, { "maximum": 3 }],
    "react/jsx-no-bind": 0,
    "react/jsx-no-duplicate-props": 2,
    "react/jsx-no-literals": 0,
    "react/jsx-no-target-blank": 2,
    "react/jsx-no-undef": 2,
    "react/jsx-pascal-case": 2,
    "react/jsx-sort-props": 0,
    "react/jsx-space-before-closing": [2, "always"],
    "react/jsx-uses-react": 2,
    "react/jsx-uses-vars": 2,
  }
};
<|endoftext|>


<commit_before>var widgets = require('./widgets');

module.exports = require('./view').extend()
  .prop('types')

  .confprop('title')
  .set(d3.functor)
  .title(function(d) { return d.title; })

  .confprop('key')
  .set(d3.functor)
  .key(function(d, i) {
    return 'key' in d
      ? d.key
      : i;
  })

  .confprop('type')
  .set(d3.functor)
  .type(function(d) { return d.type; })

  .confprop('widgets')
  .set(d3.functor)
  .widgets(function(d) { return d.widgets; })

  .init(function() {
    var types = d3.map();

    d3.keys(widgets).forEach(function(k) {
      types.set(k, widgets[k].extend());
    });

    this.types(types);
  })

  .draw(function() {
    var self = this;

    var widgets = this.el()
      .html(null)
      .append('div')
        .datum(this.widgets())
        .attr('class', 'widgets');

    var widget = widgets.selectAll('.widget')
      .data(function(d) { return d; }, this.key());

    widget.enter().append('div')
      .attr('class', 'widget')
      .attr('data-key', this.key());

    widget.each(function(d, i) {
      var type = self.type().call(this, d, i);

      if (!self.types().has(type)) {
        throw new Error("Unrecognised dashboard widget type '" + type + "'");
      }

      self.types()
        .get(type)
        .new(this)
        .draw();
    });

    widget.exit().remove();
  });
<commit_msg>Avoid html clearing when drawing dashboard<commit_after>var widgets = require('./widgets');

module.exports = require('./view').extend()
  .prop('types')

  .confprop('title')
  .set(d3.functor)
  .title(function(d) { return d.title; })

  .confprop('key')
  .set(d3.functor)
  .key(function(d, i) {
    return 'key' in d
      ? d.key
      : i;
  })

  .confprop('type')
  .set(d3.functor)
  .type(function(d) { return d.type; })

  .confprop('widgets')
  .set(d3.functor)
  .widgets(function(d) { return d.widgets; })

  .init(function() {
    var types = d3.map();

    d3.keys(widgets).forEach(function(k) {
      types.set(k, widgets[k].extend());
    });

    this.types(types);
  })

  .draw(function() {
    var self = this;

    var widgets = this.el().selectAll('.widgets')
      .data(function(d, i) {
        return [self.widgets().call(this, d, i)];
      });

    widgets.enter().append('div')
      .attr('class', 'widgets');

    var widget = widgets.selectAll('.widget')
      .data(function(d) { return d; }, this.key());

    widget.enter().append('div')
      .attr('class', 'widget')
      .attr('data-key', this.key());

    widget.each(function(d, i) {
      var type = self.type().call(this, d, i);

      if (!self.types().has(type)) {
        throw new Error("Unrecognised dashboard widget type '" + type + "'");
      }

      self.types()
        .get(type)
        .new(this)
        .draw();
    });

    widget.exit().remove();
  });
<|endoftext|>


<commit_before>module.exports = {
  collated: true,
  preview: '@docs-only-styles',
  context: {
    heading: {
      text: 'Sing up to our twisted newsletter'
    },
    input: {
      class: 'newsletter__input',
      field: {
        placeholder: 'Enter your email address',
        id: 'newsletterEmail',
        name: 'newsletterEamil',
        class: 'newsletter__field'
      },
      label: {
        class: 'newsletter__label'
      }
    },
    button: {
      tag: 'button',
      text: 'Submit',
      class: 'newsletter__button'
    },
    checkbox: {
      class: 'newsletter__checkbox',
      id: 'newsletter',
      label: {
        text: 'I agree to Terms and conditions and I am happy to receive your newsletter with all your promotions.'
      }
    }
  }
};
<commit_msg>#36086 add label to newsletter input<commit_after>module.exports = {
  collated: true,
  preview: '@docs-only-styles',
  context: {
    heading: {
      text: 'Sing up to our twisted newsletter'
    },
    input: {
      class: 'newsletter__input',
      field: {
        placeholder: 'Enter your email address',
        id: 'newsletterEmail',
        name: 'newsletterEamil',
        class: 'newsletter__field'
      },
      label: {
        class: 'newsletter__label',
        hidden: true,
        text: 'Email for newsletter subscription'
      }
    },
    button: {
      tag: 'button',
      text: 'Submit',
      class: 'newsletter__button'
    },
    checkbox: {
      class: 'newsletter__checkbox',
      id: 'newsletter',
      label: {
        text: 'I agree to Terms and conditions and I am happy to receive your newsletter with all your promotions.'
      }
    }
  }
};
<|endoftext|>


<commit_before>/**
 * @license ng-notify v0.4.0
 * http://matowens.github.io/ng-notify
 * (c) 2014 MIT License, matowens.com
 */
(function() {
    'use strict';

    /**
     * @description
     *
     * This module provides any AngularJS application with a simple, lightweight
     * system for displaying notifications of varying degree to it's users.
     *
     */
     var module = angular.module('ngNotify', []);

     module.provider('ngNotify', function() {

        this.$get = ['$document', '$compile', '$rootScope', '$timeout', '$interval',

            function($document, $compile, $rootScope, $timeout, $interval) {

                // Defaults...

                var options = {
                    theme: 'pure',
                    position: 'bottom',
                    duration: 3000,
                    type: 'info',
                    sticky: false
                };

                // Options...
                var userOpts = {};

                var themes = {
                    pure: '',
                    prime: 'ngn-prime',
                    pastel: 'ngn-pastel',
                    pitchy: 'ngn-pitchy'
                };

                var types = {
                    infoClass: 'ngn-info',
                    errorClass: 'ngn-error',
                    successClass: 'ngn-success',
                    warnClass: 'ngn-warn',
                    grimaceClass: 'ngn-grimace'
                };

                var positions = {
                    bottom: 'ngn-bottom',
                    top: 'ngn-top'
                };

                // Fade params...

                var notifyTimeout;
                var notifyInterval;

                // Template and scope...

                var notifyScope = $rootScope.$new();
                var tpl = $compile(
                    '
' +
                        // '×' +
                        '{{ ngNotify.notifyMessage }}' +
                    '
'
                )(notifyScope);

                $document.find('body').append(tpl);

                // Private methods...

                /**
                 * Sets what type of notification do display, eg, error, warning, etc.
                 *
                 * @param  {String} providedType - optional user provided type that will override our default value.
                 * @return {String}              - the type that will be assigned to this notification.
                 */
                var setType = function(providedType) {
                    var type = (providedType || options.type) + 'Class';
                    return types[type] || types.infoClass;
                };

                /**
                 * Sets the theme for a notification, eg, pure, pastel, etc.
                 *
                 * @param  {String} providedTheme - optional user provided theme that will override our default value.
                 * @return {String}               - the theme that will be assigned to this notification.
                 */
                var setTheme = function(providedTheme) {
                    var theme = providedTheme || options.theme;
                    return themes[theme] || themes.pure;
                };

                /**
                 * Sets the position of the notification, eg, top or bottom.
                 *
                 * @param  {String} providedPosition - optional user provided position that will override our default value.
                 * @return {String}                  - the position that will be assigned to this notification.
                 */
                var setPosition = function(providedPosition) {
                    var position = providedPosition || options.position;
                    return positions[position] || positions.bottom;
                };

                /**
                 * Sets how long (in ms) to display the notification for.
                 *
                 * @param  {Integer} providedDuration - optional user provided number of ms a fade lasts.
                 * @return {Integer}                  - the number of ms a fade on this notification will last.
                 */
                var setDuration = function(providedDuration) {
                    var duration = providedDuration || options.duration;
                    return angular.isNumber(duration) ? duration : 3500;
                };

                /**
                 * Sets our notification's sticky state, forcing the user to dismiss it when enabled.
                 *
                 * @param {Bool} providedSticky - boolean on whether or not sticky state should be enabled.
                 */
                var setSticky = function(providedSticky) {
                    var sticky = providedSticky || options.sticky;
                    return sticky ? true : false;
                };

                /**
                 * Resets our notification classes and message.
                 */
                var notifyReset = function() {
                    notifyScope.ngNotify = {
                        notifyClass: '',
                        notifyMessage: ''
                    };
                };

                // Pure JS fade functionality, support for IE8 included...

                /**
                 * Triggers our constructor to add our fade prototypes to our element.
                 *
                 * @param  {Object} el - an element generated by our own template and bound to it's own scope.
                 * @return {Object}    - our element along with new fade prototype methods.
                 */
                var fadeLib = function(el) {
                    return new fadeLib.fn(el);
                };

                /**
                 * Our constructor that will allow us to invoke a fade on our element.
                 *
                 * @param {Object} el - an element generated by our own template and bound to it's own scope.
                 */
                fadeLib.fn = function(el) {
                    this.el = el;
                };

                /**
                 * Handles the fading functionality and the duration for each fade.
                 *
                 * @param {Integer}  mode     - used to trigger fade in or out, adds or subtracts opacity until visible or hidden.
                 * @param {Integer   opacity  - initial opacity for our element.
                 * @param {Integer}  duration - how long the fade should take to complete, in ms.
                 * @param {Function} callback - function to invoke once our fade is complete.
                 */
                fadeLib.fn.prototype._fade = function(mode, opacity, duration, callback) {

                    var interval = 25;
                    var gap = interval / duration;
                    var el = this.el;

                    el.css('opacity', opacity);

                    var func = function() {

                        opacity = opacity + mode * gap;

                        el.css('filter', 'progid:DXImageTransform.Microsoft.Alpha(Opacity=' + opacity * 100 + ')'); // IE8
                        el.css('opacity', opacity);

                        if (opacity <= 0 || opacity >= 1) {
                            $interval.cancel(notifyInterval);

                            if (opacity <= 0) {
                                el.css('display', 'none');
                            }

                            if (callback) {
                                callback();
                            }
                        }
                    };

                    notifyInterval = $interval(func, interval);
                };

                /**
                 * Triggers a fade in, opacity from 0 to 1.
                 *
                 * @param  {Integer}  duration - how long the fade should take to complete, in ms.
                 * @param  {Function} callback - function to invoke once fade has completed.
                 */
                fadeLib.fn.prototype.fadeIn = function(duration, callback) {
                    this.el.css('filter', 'progid:DXImageTransform.Microsoft.Alpha(Opacity=0)');
                    this.el.css('display', 'block');
                    this._fade(1, 0, duration, callback);
                };

                /**
                 * Triggers a fade out, opacity from 1 to 0.
                 *
                 * @param  {Integer}  duration - how long the fade should take to complete, in ms.
                 * @param  {Function} callback - function to invoke once fade has completed.
                 */
                fadeLib.fn.prototype.fadeOut = function(duration, callback) {
                    this._fade(-1, 1, duration, callback);
                };

                /**
                 * Dismisses our notification when called, attached to scope for ngCLick event to trigger.
                 *
                 */
                notifyScope.dismiss = function() {
                    el.fadeOut(500, function() {
                        notifyReset();
                    });
                };

                /**
                 * Our template bound to it's own personal scope and receiving our fade protoype functions.
                 *
                 * @type {Object}
                 */
                var el = fadeLib(tpl);

                /**
                 * Our primary object containing all public API methods and allows for all our functionality to be invoked.
                 *
                 * @type {Object}
                 */
                var notifyObject = {

                    /**
                     * Merges our user specified options with our default set of options.
                     *
                     * @param {Object} params - object of user provided options to configure notifications.
                     */
                    config: function(params) {
                        params = params || {};
                        angular.extend(options, params);
                    },

                    /**
                     * Sets, configures and displays each notification.
                     *
                     * @param {String}             message - the message our notification will display to the user.
                     * @param {String|Object|null} userOpt - optional parameter that contains the type or an object of options used to configure this notification.
                     */
                    set: function(message, userOpt) {

                        if (!message) {
                            return;
                        }

                        $interval.cancel(notifyInterval);
                        $timeout.cancel(notifyTimeout);

                        if (typeof userOpt === 'object') {
                            userOpts = {
                                type: userOpt.type || undefined,
                                theme: userOpt.theme || undefined,
                                position: userOpt.position || undefined,
                                duration: userOpt.duration || undefined,
                                sticky: userOpt.sticky || undefined
                            };
                        } else {
                            userOpts.type = userOpt;
                        }

                        var sticky = setSticky(userOpts.sticky);
                        var duration = setDuration(userOpts.duration);
                        var notifyClass = setType(userOpts.type) + ' ' +
                                          setTheme(userOpts.theme) + ' ' +
                                          setPosition(userOpts.position);

                        notifyClass += sticky ? ' ngn-sticky' : '';

                        notifyScope.ngNotify = {
                            notifyClass: notifyClass,
                            notifyMessage: message
                        };

                        el.fadeIn(200, function() {
                            if (!sticky) {
                                notifyTimeout = $timeout(function() {
                                    notifyScope.dismiss();
                                }, duration);
                            }
                        });
                    },

                    /**
                     * Allows a developer to manually dismiss a notification that may be
                     * set to sticky, when the message is no longer warranted.
                     */
                    dismiss: function() {
                        notifyScope.dismiss();
                    },

                    // User customizations...

                    /**
                     * Adds a new, user specified theme to our notification system
                     * that they can then use throughout their application.
                     *
                     * @param {String} themeName  - the name for this new theme that will be used when applying it via configuration.
                     * @param {String} themeClass - the class that this theme will use when applying it's styles.
                     */
                    addTheme: function(themeName, themeClass) {
                        if (!themeName || !themeClass) { return; }
                        themes[themeName] = themeClass;
                    },

                    /**
                     * Adds a new, user specified notification type that they
                     * can then use throoughout their application.
                     *
                     * @param {String} typeName  - the name for this new type that will be used when applying it via configuration.
                     * @param {String} typeClass - the class that this type will use when applying it's styles.
                     */
                    addType: function(typeName, typeClass) {
                        if (!typeName || !typeClass) { return; }
                        types[typeName + 'Class'] = typeClass;
                    }

                };

                return notifyObject;
            }
        ];
     });
})();
<commit_msg>Don't use fadeIn/Out, use CSS translate instead, by adding/removing classes<commit_after>/**
 * @license ng-notify v0.4.0
 * http://matowens.github.io/ng-notify
 * (c) 2014 MIT License, matowens.com
 */
(function() {
    'use strict';

    /**
     * @description
     *
     * This module provides any AngularJS application with a simple, lightweight
     * system for displaying notifications of varying degree to it's users.
     *
     */
     var module = angular.module('ngNotify', []);

     module.provider('ngNotify', function() {

        this.$get = ['$document', '$compile', '$rootScope', '$timeout', '$interval',

            function($document, $compile, $rootScope, $timeout, $interval) {

                // Defaults...

                var options = {
                    theme: 'pure',
                    position: 'bottom',
                    duration: 3000,
                    type: 'info',
                    sticky: false
                };

                // Options...
                var userOpts = {};

                var themes = {
                    pure: '',
                    prime: 'ngn-prime',
                    pastel: 'ngn-pastel',
                    pitchy: 'ngn-pitchy'
                };

                var types = {
                    infoClass: 'ngn-info',
                    errorClass: 'ngn-error',
                    successClass: 'ngn-success',
                    warnClass: 'ngn-warn',
                    grimaceClass: 'ngn-grimace'
                };

                var positions = {
                    bottom: 'ngn-bottom',
                    top: 'ngn-top'
                };

                // Fade params...

                var notifyTimeout;
                var notifyInterval;

                // Template and scope...

                var notifyScope = $rootScope.$new();
                var tpl = $compile(
                    '
' +
                        // '×' +
                        '{{ ngNotify.notifyMessage }}' +
                    '
'
                )(notifyScope);

                $document.find('body').append(tpl);

                // Private methods...

                /**
                 * Sets what type of notification do display, eg, error, warning, etc.
                 *
                 * @param  {String} providedType - optional user provided type that will override our default value.
                 * @return {String}              - the type that will be assigned to this notification.
                 */
                var setType = function(providedType) {
                    var type = (providedType || options.type) + 'Class';
                    return types[type] || types.infoClass;
                };

                /**
                 * Sets the theme for a notification, eg, pure, pastel, etc.
                 *
                 * @param  {String} providedTheme - optional user provided theme that will override our default value.
                 * @return {String}               - the theme that will be assigned to this notification.
                 */
                var setTheme = function(providedTheme) {
                    var theme = providedTheme || options.theme;
                    return themes[theme] || themes.pure;
                };

                /**
                 * Sets the position of the notification, eg, top or bottom.
                 *
                 * @param  {String} providedPosition - optional user provided position that will override our default value.
                 * @return {String}                  - the position that will be assigned to this notification.
                 */
                var setPosition = function(providedPosition) {
                    var position = providedPosition || options.position;
                    return positions[position] || positions.bottom;
                };

                /**
                 * Sets how long (in ms) to display the notification for.
                 *
                 * @param  {Integer} providedDuration - optional user provided number of ms a fade lasts.
                 * @return {Integer}                  - the number of ms a fade on this notification will last.
                 */
                var setDuration = function(providedDuration) {
                    var duration = providedDuration || options.duration;
                    return angular.isNumber(duration) ? duration : 3500;
                };

                /**
                 * Sets our notification's sticky state, forcing the user to dismiss it when enabled.
                 *
                 * @param {Bool} providedSticky - boolean on whether or not sticky state should be enabled.
                 */
                var setSticky = function(providedSticky) {
                    var sticky = providedSticky || options.sticky;
                    return sticky ? true : false;
                };

                /**
                 * Resets our notification classes and message.
                 */
                var notifyReset = function() {
                    notifyScope.ngNotify = {
                        notifyClass: '',
                        notifyMessage: ''
                    };
                };

                // Pure JS fade functionality, support for IE8 included...

                /**
                 * Triggers our constructor to add our fade prototypes to our element.
                 *
                 * @param  {Object} el - an element generated by our own template and bound to it's own scope.
                 * @return {Object}    - our element along with new fade prototype methods.
                 */
                var fadeLib = function(el) {
                    return new fadeLib.fn(el);
                };

                /**
                 * Our constructor that will allow us to invoke a fade on our element.
                 *
                 * @param {Object} el - an element generated by our own template and bound to it's own scope.
                 */
                fadeLib.fn = function(el) {
                    this.el = el;
                };

                /**
                 * Handles the fading functionality and the duration for each fade.
                 *
                 * @param {Integer}  mode     - used to trigger fade in or out, adds or subtracts opacity until visible or hidden.
                 * @param {Integer   opacity  - initial opacity for our element.
                 * @param {Integer}  duration - how long the fade should take to complete, in ms.
                 * @param {Function} callback - function to invoke once our fade is complete.
                 */
                fadeLib.fn.prototype._fade = function(mode, opacity, duration, callback) {

                    var interval = 25;
                    var gap = interval / duration;
                    var el = this.el;

                    el.css('opacity', opacity);

                    var func = function() {

                        opacity = opacity + mode * gap;

                        el.css('filter', 'progid:DXImageTransform.Microsoft.Alpha(Opacity=' + opacity * 100 + ')'); // IE8
                        el.css('opacity', opacity);

                        if (opacity <= 0 || opacity >= 1) {
                            $interval.cancel(notifyInterval);

                            if (opacity <= 0) {
                                el.css('display', 'none');
                            }

                            if (callback) {
                                callback();
                            }
                        }
                    };

                    notifyInterval = $interval(func, interval);
                };

                /**
                 * Triggers a fade in, opacity from 0 to 1.
                 *
                 * @param  {Integer}  duration - how long the fade should take to complete, in ms.
                 * @param  {Function} callback - function to invoke once fade has completed.
                 */
                fadeLib.fn.prototype.fadeIn = function(duration, callback) {
                    this.el.css('filter', 'progid:DXImageTransform.Microsoft.Alpha(Opacity=0)');
                    this.el.css('display', 'block');
                    this._fade(1, 0, duration, callback);
                };

                /**
                 * Triggers a fade out, opacity from 1 to 0.
                 *
                 * @param  {Integer}  duration - how long the fade should take to complete, in ms.
                 * @param  {Function} callback - function to invoke once fade has completed.
                 */
                fadeLib.fn.prototype.fadeOut = function(duration, callback) {
                    this._fade(-1, 1, duration, callback);
                };

                /**
                 * Dismisses our notification when called, attached to scope for ngCLick event to trigger.
                 *
                 */
                notifyScope.dismiss = function() {
                    el.el[0].classList.remove(setPosition(userOpts.position));
                    $timeout(function() {
                        notifyReset();
                    }, 400);
                };

                /**
                 * Our template bound to it's own personal scope and receiving our fade protoype functions.
                 *
                 * @type {Object}
                 */
                var el = fadeLib(tpl);

                /**
                 * Our primary object containing all public API methods and allows for all our functionality to be invoked.
                 *
                 * @type {Object}
                 */
                var notifyObject = {

                    /**
                     * Merges our user specified options with our default set of options.
                     *
                     * @param {Object} params - object of user provided options to configure notifications.
                     */
                    config: function(params) {
                        params = params || {};
                        angular.extend(options, params);
                    },

                    /**
                     * Sets, configures and displays each notification.
                     *
                     * @param {String}             message - the message our notification will display to the user.
                     * @param {String|Object|null} userOpt - optional parameter that contains the type or an object of options used to configure this notification.
                     */
                    set: function(message, userOpt) {

                        if (!message) {
                            return;
                        }

                        $interval.cancel(notifyInterval);
                        $timeout.cancel(notifyTimeout);

                        if (typeof userOpt === 'object') {
                            userOpts = {
                                type: userOpt.type || undefined,
                                theme: userOpt.theme || undefined,
                                position: userOpt.position || undefined,
                                duration: userOpt.duration || undefined,
                                sticky: userOpt.sticky || undefined
                            };
                        } else {
                            userOpts.type = userOpt;
                        }

                        var sticky = setSticky(userOpts.sticky);
                        var duration = setDuration(userOpts.duration);
                        var notifyClass = setType(userOpts.type) + ' ' +
                                          setTheme(userOpts.theme) + ' ';

                        notifyClass += setPosition(userOpts.position);
                        notifyClass += sticky ? ' ngn-sticky' : '';
                        // notifyClass += ' is-animated';

                        notifyScope.ngNotify = {
                            notifyClass: notifyClass,
                            notifyMessage: message
                        };

                        // el.fadeIn(200, function() {
                            if (!sticky) {
                                notifyTimeout = $timeout(function() {
                                    notifyScope.dismiss();
                                }, duration);
                            }
                        // });
                    },

                    /**
                     * Allows a developer to manually dismiss a notification that may be
                     * set to sticky, when the message is no longer warranted.
                     */
                    dismiss: function() {
                        notifyScope.dismiss();
                    },

                    // User customizations...

                    /**
                     * Adds a new, user specified theme to our notification system
                     * that they can then use throughout their application.
                     *
                     * @param {String} themeName  - the name for this new theme that will be used when applying it via configuration.
                     * @param {String} themeClass - the class that this theme will use when applying it's styles.
                     */
                    addTheme: function(themeName, themeClass) {
                        if (!themeName || !themeClass) { return; }
                        themes[themeName] = themeClass;
                    },

                    /**
                     * Adds a new, user specified notification type that they
                     * can then use throoughout their application.
                     *
                     * @param {String} typeName  - the name for this new type that will be used when applying it via configuration.
                     * @param {String} typeClass - the class that this type will use when applying it's styles.
                     */
                    addType: function(typeName, typeClass) {
                        if (!typeName || !typeClass) { return; }
                        types[typeName + 'Class'] = typeClass;
                    }

                };

                return notifyObject;
            }
        ];
     });
})();
<|endoftext|>